Skip to content

Commit 6ab9770

Browse files
committed
moar file handling exceptions, fix of a bug in ip rules generation
1 parent 128d340 commit 6ab9770

File tree

2 files changed

+75
-59
lines changed

2 files changed

+75
-59
lines changed

README.md

+7-7
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,17 @@ The input file must be a csv file containing the following information, 3 rows :
2727
- first row : Threat name
2828
- second row : IOC
2929
- third row : link to a reference
30-
## Exmaple
30+
31+
## Example
3132
```
3233
LimunosityLink;030092056f0368639145711a615d3b7f.co.cc;https://conix.fr
3334
```
3435

3536
# Example
3637
```
3738
$ cat blacklist.txt
38-
LimunosityLink;030092056f0368639145711a615d3b7f.co.cc;https://conix.fr
39-
LimunosityLink;70.30.5.3;https://conix.fr
39+
LuminosityLink;030092056f0368639145711a615d3b7f.co.cc;https://conix.fr
40+
LuminosityLink;70.30.5.3;https://conix.fr
4041
$
4142
$
4243
$  python bl2ru2.py blacklist.txt -o cert-conix.rules -e CERT-Conix
@@ -47,17 +48,16 @@ $  python bl2ru2.py blacklist.txt -o cert-conix.rules -e CERT-Conix
4748
$
4849
$
4950
$  cat cert-conix.rules
50-
alert udp $HOME_NET any -> any 53 (msg:CERT-Conix - LimunosityLink - DNS request for 030092056f0368639145711a615d3b7f.co.cc"; content:"|01 00 00 01 00 00 00 00 00 00|"; depth:20; offset: 2; content:"|20|030092056f0368639145711a615d3b7f|02|co|02|cc"; fast_pattern:only; nocase; classtype:trojan-activity; reference:url,https://conix.fr; sid: 5100004; rev:1 )
51-
alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS (msg:"CERT-Conix - LimunosityLink - Related URL (030092056f0368639145711a615d3b7f.co.cc)"; content:"030092056f0368639145711a615d3b7f.co.cc"; http_uri; classtype:trojan-activity; reference:url,https://conix.fr; sid:5100005;rev:1;)
52-
alert ip $HOME_NET any -> CERT-Conix any (msg:"70.30.5.3 - LimunosityLink - IP traffic to 70.30.5.3"; classtype:trojan-activity; reference:url,https://conix.fr; sid:5100006; rev:1;)
51+
alert udp $HOME_NET any -> any 53 (msg:CERT-Conix - LuminosityLink - DNS request for 030092056f0368639145711a615d3b7f.co.cc"; content:"|01 00 00 01 00 00 00 00 00 00|"; depth:20; offset: 2; content:"|20|030092056f0368639145711a615d3b7f|02|co|02|cc"; fast_pattern:only; nocase; classtype:trojan-activity; reference:url,https://conix.fr; sid: 5100004; rev:1 )
52+
alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS (msg:"CERT-Conix - LuminosityLink - Related URL (030092056f0368639145711a615d3b7f.co.cc)"; content:"030092056f0368639145711a615d3b7f.co.cc"; http_uri; classtype:trojan-activity; reference:url,https://conix.fr; sid:5100005;rev:1;)
53+
alert ip $HOME_NET any -> 70.30.5.3 any (msg:"CERT-Conix - LuminosityLink - IP traffic to 70.30.5.3"; classtype:trojan-activity; reference:url,https://conix.fr; sid:5100006; rev:1;)
5354
```
5455

5556
# TODO
5657
- add -s --sid option to let user specify the starting sid
5758
- add rule for md5
5859
- manage uri like example.com/stuff_here
5960
- make the prints to stdout conditionnals to args.output
60-
- add exception PermissionError if .sid and output file can't be written
6161
- add baserule for domain in ssl cert (if possible)
6262
- add rules examples along the baserules
6363
- smb/netbios etc ?

bl2ru2.py

+68-52
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,6 @@
1919
import argparse
2020
import re
2121

22-
#TODO:
23-
# - add -s --sid option to let user specify the starting sid
24-
# - add rule for md5
25-
# - manage uri like example.com/stuff_here
26-
# - make the prints to tsdout conditionnals to args.output
27-
# - add exception PermissionError if .sid and output file can't be written
28-
# - add baserule for domain in ssl cert (if possible)
29-
# - add rules examples along the baserules
30-
# - smb/netbios etc ?
31-
3222
# To add a rule class while keeping the code clean, add the baserule here
3323
IP_UDP_BASERULE = 'alert udp $HOME_NET any -> %s any (msg:"%s - %s - UDP traffic to %s"; classtype:trojan-activity; reference:url,%s; sid:%d; rev:1;)'
3424
IP_TCP_BASERULE = 'alert tcp $HOME_NET any -> %s any (msg:"%s - %s - TCP traffic to %s"; classtype:trojan-activity; reference:url,%s; sid:%d; rev:1;)'
@@ -40,60 +30,54 @@ def main(args):
4030
global ORG
4131
ORG = args.emitter
4232

43-
#############################
44-
# Latest SID
45-
print("[+] Getting SID")
46-
try:
47-
with open(".sid_log_file", "r") as f_sid_log_file:
48-
line = f_sid_log_file.readline()
49-
sid = int(line)
50-
except FileNotFoundError:
51-
sid = 5100000
52-
print("[-] .sid_log_file not found, starting SID from %s"%str(sid))
33+
sid = get_sid()
5334

5435
#############################
5536
# Generating rules
5637
print("[+] Generating rules")
57-
with open(args.file, "r") as f_input:
58-
rules = []
59-
for line in f_input:
60-
line = line.strip()
61-
(name, ioc, url) = split_line(line)
62-
sid += 1
63-
if ioc.startswith("/"):
64-
# URL it is
65-
rules.append(gen_url_rule(name, ioc, url, sid))
66-
elif re.match(r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}", ioc):
67-
# IP it is
68-
#rules.append(gen_ip_rule_udp(name, ioc, url, sid))
69-
#sid += 1
70-
#rules.append(gen_ip_rule_tcp(name, ioc, url, sid))
71-
#sid += 1
72-
rules.append(gen_ip_rule(name, ioc, url, sid))
73-
else:
74-
# Well, by lack of other option, let's say it is a domain name
75-
rules.append(gen_dns_rule(name, ioc, url, sid))
38+
try:
39+
with open(args.file, "r") as f_input:
40+
rules = []
41+
for line in f_input:
42+
line = line.strip()
43+
(name, ioc, url) = split_line(line)
7644
sid += 1
77-
rules.append(gen_url_rule(name, ioc, url, sid))
45+
if ioc.startswith("/"):
46+
# URL it is
47+
rules.append(gen_url_rule(name, ioc, url, sid))
48+
elif re.match(r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}", ioc):
49+
# IP it is
50+
#rules.append(gen_ip_rule_udp(name, ioc, url, sid))
51+
#sid += 1
52+
#rules.append(gen_ip_rule_tcp(name, ioc, url, sid))
53+
#sid += 1
54+
rules.append(gen_ip_rule(name, ioc, url, sid))
55+
else:
56+
# Well, by lack of other option, let's say it is a domain name
57+
rules.append(gen_dns_rule(name, ioc, url, sid))
58+
sid += 1
59+
rules.append(gen_url_rule(name, ioc, url, sid))
60+
except PermissionError as err:
61+
print(err)
62+
print("[+] Aborting!")
63+
quit(0)
7864

7965
#############################
80-
# Writing rules to file
66+
# Writing rules to file or stdout
8167
if args.output:
8268
print("[+] Writing Rule file")
83-
with open(args.output, "a") as f_out:
84-
for rule in rules:
85-
f_out.write("%s \n"%(rule))
69+
try:
70+
with open(args.output, "a") as f_out:
71+
for rule in rules:
72+
f_out.write("%s \n"%(rule))
73+
except PermissionError:
74+
print("[+] Can't write rule file, permission denied")
75+
print("[+] Rules not saved, be carefull")
8676
else:
8777
for rule in rules:
8878
print("%s"%rule)
8979

90-
#############################
91-
# Logging max sid
92-
print("[+] Writing Last SID")
93-
with open(".sid_log_file", "w") as f_sid:
94-
f_sid.write("%d"%(sid))
95-
96-
return True
80+
save_sid(sid)
9781

9882
def gen_dns_rule(name, domain, ref, sid):
9983
'''
@@ -141,10 +125,42 @@ def gen_ip_rule_tcp(name, ip_addr, ref, sid):
141125
def gen_ip_rule(name, ip_addr, ref, sid):
142126
'''
143127
Generate suricata rule for an IP
128+
IP_BASERULE = 'alert ip $HOME_NET any -> %s any (msg:"%s - %s - IP traffic to %s"; classtype:trojan-activity; reference:url,%s; sid:%d; rev:1;)'
144129
'''
145-
rule = (IP_BASERULE%(ORG, ip_addr, name, ip_addr, ref, sid))
130+
rule = (IP_BASERULE%(ip_addr, ORG, name, ip_addr, ref, sid))
146131
return rule
147132

133+
def get_sid():
134+
'''
135+
get sid to use for this run
136+
'''
137+
print("[+] Getting SID")
138+
try:
139+
with open(".sid_log_file", "r") as f_sid_log_file:
140+
line = f_sid_log_file.readline()
141+
return int(line)
142+
except FileNotFoundError:
143+
print("[-] .sid_log_file not found, starting SID from 5100000")
144+
return 5100000
145+
except PermissionError as err:
146+
print(err)
147+
print("[+] Aborting!")
148+
quit(0)
149+
150+
def save_sid(sid):
151+
'''
152+
save sid to use for next run
153+
'''
154+
print("[+] Writing Last SID")
155+
try:
156+
with open(".sid_log_file", "w") as f_sid:
157+
f_sid.write("%d"%(sid))
158+
except PermissionError as err:
159+
print(err)
160+
print("[+] sid not saved, be carefull")
161+
return False
162+
return True
163+
148164
def split_line(line):
149165
'''
150166
Cut the line to extract the different fields

0 commit comments

Comments
 (0)