/dns2snort

AYY LMAO

Primary LanguagePython

dns2snort.py
-by da_667
-with code contributions from @botnet_hunter and @3XPlo1T2

Purpose: Given a file containing a list of fully qualified DNS domains, generate snort rules for those domains. Incredibly useful if you are sitting on top of a pile of IOCs, but want an efficiently lazy way to generate snort sigs for them.
Requires: argparse, textwrap, python 2.7
Tested on: OSX, Ubuntu, Debian

Options (INFILE, OUTFILE, and SID arguments are all required!):
-i : input file. Point the script to the file that contains the list of domains (one domain per line)
-o : output file: File to output your new snort rules
-s : SID. This is integer value that must be between 1000000 and 2000000 (one million and two million)
-w : Remove the 'www' subdomain from domains that have it.
-h : prints out the most badass help message you've ever seen.

Example input:

.pw
evilcorp.co
www.evil.com
seemstoteslegit.notreally.tk
stupidlylongsubdomain.lol.wutski.biz

..becomes:

alert udp $HOME_NET any -> $EXTERNAL_NET 53 (msg:"BLACKLIST DNS domain .pw"; flow:to_server; byte_test:1,!&,0xF8,2; content:"|02|pw|00|"; fast_pattern:only; metadata:service dns;  sid:1000000; rev:1;)
alert udp $HOME_NET any -> $EXTERNAL_NET 53 (msg:"BLACKLIST DNS domain evilcorp.co"; flow:to_server; byte_test:1,!&,0xF8,2; content:"|08|evilcorp|02|co|00|"; fast_pattern:only; metadata:service dns;  sid:1000001; rev:1;)
alert udp $HOME_NET any -> $EXTERNAL_NET 53 (msg:"BLACKLIST DNS domain www.evil.com"; flow:to_server; byte_test:1,!&,0xF8,2; content:"|03|www|04|evil|03|com|00|"; fast_pattern:only; metadata:service dns;  sid:1000002; rev:1;)
alert udp $HOME_NET any -> $EXTERNAL_NET 53 (msg:"BLACKLIST DNS domain seemstoteslegit.notreally.tk"; flow:to_server; byte_test:1,!&,0xF8,2; content:"|0F|seemstoteslegit|09|notreally|02|tk|00|"; fast_pattern:only; metadata:service dns;  sid:1000003; rev:1;)
alert udp $HOME_NET any -> $EXTERNAL_NET 53 (msg:"BLACKLIST DNS known malware domain stupidlylongsubdomain.lol.wutski.biz"; flow:to_server; byte_test:1,!&,0xF8,2; content:"|15|stupidlylongsubdomain|03|lol|06|wutski|03|biz|00|"; fast_pattern:only; metadata:service dns;  sid:1000004; rev:1;)

These are all properly formatted snort rules ready to be pushed to a sensor.

Notes:
- Please note that none of these sample domains are malicious. They are samples for testing only.
- The domain list input file should not have ANY trailing spaces on any of the individual user-agent lines. Additionally, there should be ZERO blank lines in the domain list file that will be used to generate the snort rules.
- If you think this is a concern, the Mandiant APT1 report has over 2000 domains as IOCs associated with the campaign. dns2snort only encountered two FQDNs with 5+ subdomains; dns2snort successfully created rules for every other domain in the list of IOCs. Maybe you can look over my code and implement a way to support FQDNs of varying length? I'm not good enough at python to do this currently without a huge CF of if/then statements. Help is welcome.