Skip to content

Commit

Permalink
moar file handling exceptions, fix of a bug in ip rules generation
Browse files Browse the repository at this point in the history
  • Loading branch information
rmarsollier committed Jan 31, 2017
1 parent 128d340 commit 6ab9770
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 59 deletions.
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,17 @@ The input file must be a csv file containing the following information, 3 rows :
- first row : Threat name
- second row : IOC
- third row : link to a reference
## Exmaple

## Example
```
LimunosityLink;030092056f0368639145711a615d3b7f.co.cc;https://conix.fr
```

# Example
```
$ cat blacklist.txt
LimunosityLink;030092056f0368639145711a615d3b7f.co.cc;https://conix.fr
LimunosityLink;70.30.5.3;https://conix.fr
LuminosityLink;030092056f0368639145711a615d3b7f.co.cc;https://conix.fr
LuminosityLink;70.30.5.3;https://conix.fr
$
$
$  python bl2ru2.py blacklist.txt -o cert-conix.rules -e CERT-Conix
Expand All @@ -47,17 +48,16 @@ $  python bl2ru2.py blacklist.txt -o cert-conix.rules -e CERT-Conix
$
$
$  cat cert-conix.rules
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 )
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;)
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;)
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 )
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;)
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;)
```

# TODO
- add -s --sid option to let user specify the starting sid
- add rule for md5
- manage uri like example.com/stuff_here
- make the prints to stdout conditionnals to args.output
- add exception PermissionError if .sid and output file can't be written
- add baserule for domain in ssl cert (if possible)
- add rules examples along the baserules
- smb/netbios etc ?
120 changes: 68 additions & 52 deletions bl2ru2.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,6 @@
import argparse
import re

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

# To add a rule class while keeping the code clean, add the baserule here
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;)'
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;)'
Expand All @@ -40,60 +30,54 @@ def main(args):
global ORG
ORG = args.emitter

#############################
# Latest SID
print("[+] Getting SID")
try:
with open(".sid_log_file", "r") as f_sid_log_file:
line = f_sid_log_file.readline()
sid = int(line)
except FileNotFoundError:
sid = 5100000
print("[-] .sid_log_file not found, starting SID from %s"%str(sid))
sid = get_sid()

#############################
# Generating rules
print("[+] Generating rules")
with open(args.file, "r") as f_input:
rules = []
for line in f_input:
line = line.strip()
(name, ioc, url) = split_line(line)
sid += 1
if ioc.startswith("/"):
# URL it is
rules.append(gen_url_rule(name, ioc, url, sid))
elif re.match(r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}", ioc):
# IP it is
#rules.append(gen_ip_rule_udp(name, ioc, url, sid))
#sid += 1
#rules.append(gen_ip_rule_tcp(name, ioc, url, sid))
#sid += 1
rules.append(gen_ip_rule(name, ioc, url, sid))
else:
# Well, by lack of other option, let's say it is a domain name
rules.append(gen_dns_rule(name, ioc, url, sid))
try:
with open(args.file, "r") as f_input:
rules = []
for line in f_input:
line = line.strip()
(name, ioc, url) = split_line(line)
sid += 1
rules.append(gen_url_rule(name, ioc, url, sid))
if ioc.startswith("/"):
# URL it is
rules.append(gen_url_rule(name, ioc, url, sid))
elif re.match(r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}", ioc):
# IP it is
#rules.append(gen_ip_rule_udp(name, ioc, url, sid))
#sid += 1
#rules.append(gen_ip_rule_tcp(name, ioc, url, sid))
#sid += 1
rules.append(gen_ip_rule(name, ioc, url, sid))
else:
# Well, by lack of other option, let's say it is a domain name
rules.append(gen_dns_rule(name, ioc, url, sid))
sid += 1
rules.append(gen_url_rule(name, ioc, url, sid))
except PermissionError as err:
print(err)
print("[+] Aborting!")
quit(0)

#############################
# Writing rules to file
# Writing rules to file or stdout
if args.output:
print("[+] Writing Rule file")
with open(args.output, "a") as f_out:
for rule in rules:
f_out.write("%s \n"%(rule))
try:
with open(args.output, "a") as f_out:
for rule in rules:
f_out.write("%s \n"%(rule))
except PermissionError:
print("[+] Can't write rule file, permission denied")
print("[+] Rules not saved, be carefull")
else:
for rule in rules:
print("%s"%rule)

#############################
# Logging max sid
print("[+] Writing Last SID")
with open(".sid_log_file", "w") as f_sid:
f_sid.write("%d"%(sid))

return True
save_sid(sid)

def gen_dns_rule(name, domain, ref, sid):
'''
Expand Down Expand Up @@ -141,10 +125,42 @@ def gen_ip_rule_tcp(name, ip_addr, ref, sid):
def gen_ip_rule(name, ip_addr, ref, sid):
'''
Generate suricata rule for an IP
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;)'
'''
rule = (IP_BASERULE%(ORG, ip_addr, name, ip_addr, ref, sid))
rule = (IP_BASERULE%(ip_addr, ORG, name, ip_addr, ref, sid))
return rule

def get_sid():
'''
get sid to use for this run
'''
print("[+] Getting SID")
try:
with open(".sid_log_file", "r") as f_sid_log_file:
line = f_sid_log_file.readline()
return int(line)
except FileNotFoundError:
print("[-] .sid_log_file not found, starting SID from 5100000")
return 5100000
except PermissionError as err:
print(err)
print("[+] Aborting!")
quit(0)

def save_sid(sid):
'''
save sid to use for next run
'''
print("[+] Writing Last SID")
try:
with open(".sid_log_file", "w") as f_sid:
f_sid.write("%d"%(sid))
except PermissionError as err:
print(err)
print("[+] sid not saved, be carefull")
return False
return True

def split_line(line):
'''
Cut the line to extract the different fields
Expand Down

0 comments on commit 6ab9770

Please sign in to comment.