Do not edit. This page has been migrated. See Converting_Wiki_Documentation_to_Sphinx.

Filemd5 and white or black listing with MD5 hashes

This guide will show you how to set up a white/black MD5 listing using latest Suricata on Ubuntu LTS 12.04 64 bit
and a file containing 87 million MD5s - white list.

In this set up we had/did the following :

1. A Suricata installation with MD5 enabled.
2. We start Suricata with about 4.5K rules and the MD5 white list file containing 87 million MD5 entries.
3. We have a 9.5Gb of traffic.
4. We have the following set up:

    CPU: One Intel(R) Xeon(R) CPU E5-2680 0 @ 2.70GHz (16 cores counting Hyperthreading)
    Memory: 32Gb
    capture NIC: Intel 82599EB 10-Gigabit SFI/SFP+

You need to get the white list file containing MD5s from here -
This is an official database containing SHA-1 and MD5s for files that are " traceable ".
For example after you download and unzip (I used the Combo DVD link) you would get a file like so:


The file contains 87 million entries/lines, each line having
of a traceable file.

You can use the Linux "cut" utility to make this file into only a MD5 file - have only the MD5 check sums (second row) - which is what we need.
Here is what you can do:

Download the ComboDVD -

unzip/tar, then

cat NSRFile.txt |more

would be able to see the beginning of the file and get an idea of what does it contain.(shown above)
NOTE – this is a 10GB file, make sure you have the space!!!
the MD5 column ... should start with "MD5"

sudo cut -d'"' -f4 NSRFile.txt >> MD5.txt

and you have only MD5s ...but still with "MD5" on top

sed -i '1d'  MD5.txt

wait for a while
check the file

wc -l MD5.txt

wait for about 2-3 min

should be about 87Mil something md5s , one per line

You can also import the file into a MySQL database, if you would like:

mysql> create user 'filejson'@'localhost' IDENTIFIED BY 'PASSWORD123';
Query OK, 0 rows affected (0.00 sec)

mysql>create database filejsondb;
mysql> grant all privileges on filejsondb.* to 'filejson'@'localhost' with grant option;
mysql>  flush privileges;
mysql> use filejsondb;

CREATE TABLE MD5(md5_whitelist VARCHAR(32));

The trick here for the import is that the table name and the file name MUST be the same - aka MySQL table "MD5" and the file is called MD5.txt !!!
sudo mysqlimport -u root -p --local filejsondb MD5.txt

Where "filejsondb" is the name of the database.

So , here is how we did it ....

pevman@suricata:~$ ls -lh /etc/suricata/et-config/MD5_NSRFile.txt 
-rw-r--r-- 1 root root 2.7G Aug 29 00:35 /etc/suricata/et-config/MD5_NSRFile.txt

pevman@suricata:~$ wc -l  /etc/suricata/et-config/MD5_NSRFile.txt 
87345542 /etc/suricata/et-config/MD5_NSRFile.txt

pevman@suricata:~$ sudo tcpstat -i eth3
Time:1346241952    n=6664547    avg=898.01    stddev=757.68    bps=9575769952.00
Time:1346241957    n=6670750    avg=897.22    stddev=754.07    bps=9576254160.00
Time:1346241962    n=6626520    avg=903.62    stddev=747.26    bps=9580577822.40
Time:1346241967    n=6685956    avg=895.15    stddev=749.34    bps=9575883715.20
Time:1346241972    n=6712481    avg=891.53    stddev=747.34    bps=9575027134.40
Time:1346241977    n=6696189    avg=893.82    stddev=746.62    bps=9576294273.60
Time:1346241982    n=6681826    avg=895.75    stddev=749.67    bps=9576376033.60

pevman@suricata:~$ suricata --build-info
[2746] 29/8/2012 -- 15:07:25 - (suricata.c:539) <Info> (SCPrintBuildInfo) -- This is Suricata version 1.4dev (rev 75af345)
[2746] 29/8/2012 -- 15:07:25 - (suricata.c:626) <Info> (SCPrintBuildInfo) -- 64-bits, Little-endian architecture
[2746] 29/8/2012 -- 15:07:25 - (suricata.c:628) <Info> (SCPrintBuildInfo) -- GCC version 4.6.3, C version 199901
[2746] 29/8/2012 -- 15:07:25 - (suricata.c:634) <Info> (SCPrintBuildInfo) -- __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1
[2746] 29/8/2012 -- 15:07:25 - (suricata.c:637) <Info> (SCPrintBuildInfo) -- __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2
[2746] 29/8/2012 -- 15:07:25 - (suricata.c:640) <Info> (SCPrintBuildInfo) -- __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
[2746] 29/8/2012 -- 15:07:25 - (suricata.c:643) <Info> (SCPrintBuildInfo) -- __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8
[2746] 29/8/2012 -- 15:07:25 - (suricata.c:646) <Info> (SCPrintBuildInfo) -- __GCC_HAVE_SYNC_COMPARE_AND_SWAP_16
[2746] 29/8/2012 -- 15:07:25 - (suricata.c:650) <Info> (SCPrintBuildInfo) -- compiled with -fstack-protector
[2746] 29/8/2012 -- 15:07:25 - (suricata.c:656) <Info> (SCPrintBuildInfo) -- compiled with _FORTIFY_SOURCE=2

During Suricata start up :

[3071] 29/8/2012 -- 15:23:45 - (detect.c:670) <Info> (SigLoadSignatures) -- Loading rule file: /var/data/peter/md5test.rules
[3071] 29/8/2012 -- 15:23:45 - (detect-filemd5.c:105) <Error> (Md5ReadString) -- [ERRCODE: SC_ERR_INVALID_MD5(214)] - md5 string not 32 bytes
[3071] 29/8/2012 -- 15:24:25 - (detect-filemd5.c:277) <Info> (DetectFileMd5Parse) -- MD5 hash size 1399625840 bytes, negated match
[3071] 29/8/2012 -- 15:24:25 - (detect.c:701) <Info> (SigLoadSignatures) -- 5 rule files processed. 4641 rules succesfully loaded, 0 rules failed

You will get the

[ERRCODE: SC_ERR_INVALID_MD5(214)] - md5 string not 32 bytes

if a line of the file is not containing a proper MD5 hash.

For example above we get the err message (which is more of a warning) because in the file , the first line was containing:

However , nonetheless Suricata will continue loading the rest of the MD5 hashes from the file. REMEMBER - you would need put only the MD5 hashes in the file.

Then we just created the following test rules:

root@suricata:/etc/suricata/peter-yaml# cat /var/data/peter/md5test.rules 
alert http any any -> any any (msg:"FILE MD5 Check PDF against a white list"; filemagic:"pdf"; filemd5:!MD5_NSRFile.txt; sid:9966699; rev:1;)
alert http any any -> any any (msg:"FILE MD5 Check EXE against a white list"; filemagic:"exe"; filemd5:!MD5_NSRFile.txt; sid:9977799; rev:2;)

Make sure the MD5_NSRFile.txt file (containing the MD5 hashes) is in your "rules directory" (where you load the rules from).

Basically the two rules above are telling Suricata to do the following:
1. If you see a PDF document that has a MD5 hash NOT in the MD5_NSRFile.txt - generate an alert
2. If you see an EXE file that has a MD5 hash NOT in the MD5_NSRFile.txt - generate an alert

all that on the fly, while inspecting traffic.

Then all that is left is to start Suricata:

sudo /usr/local/bin/suricata -c /etc/suricata/peter-yaml/suricata-af-packet-mmap.yaml -s /var/data/peter/md5test.rules --af-packet=eth3

and we get the alerts:

08/29/2012-15:38:43.165038  [**] [1:9977799:2] FILE MD5 Check EXE against a white list [**] [Classification: (null)] [Priority: 3] {TCP} y.y.y.y:80 -> x.x.x.x:23836
08/29/2012-15:39:32.551950  [**] [1:9977799:2] FILE MD5 Check EXE against a white list [**] [Classification: (null)] [Priority: 3] {TCP} y.y.y.y:2091 -> x.x.x.x:80

That's it.

You can reverse and use the above rules with a "blacklisting" of MD5 hashes, for example:

alert http any any -> any any (msg:"FILE MD5 Check PDF against a black list"; filemagic:"pdf"; filemd5:BlackMD5s.txt; sid:9966699; rev:1;)

You can also use the filestore keyword to store the file on disk and do further analysis on the particular file - or blend it in with other File-keywords .
Peter Manev