Friday, April 9, 2010

Help Us Make Our Meerkat Fuzzier!

If you checkout the latest version of the suricata from it's git repo, now included is a new qa/ directory. In this directory there now lives a perl script I created called wirefuzz.pl that is a suricata specific re-implementation of the wireshark fuzzing technique described here. The script can also be used as a shortcut to running the engine through valgrind tools etc.

In it's simplest "set it and forget it form" you can leave it running and it will loop through the pcaps provided continuing to mutate them with whatever error ratio you provide, i.e. if you pass -e=0.02 there is a 2% chance that each byte will be modified in one of four different ways. It will continue to loop until a invalid exit value is detected, at which point it will try to find the a core dump, parse it and save the output to a file for further inspection.

We have found this technique to be a very effective way of discovering bugs. We have multiple instances of this script running 24/7 using an extensive collection of pcaps as ammunition. With that said we will never be able to account for the "uniqueness" that exists in real-world environments both large and small.

if you want to help the project please don't hesitate to checkout the latest version of the repo and point the fuzzer at perhaps your rotating packet capture, or a sample of your network traffic.

If you have any questions please don't hesitate to ask on the oisf-users mailing list, which you can subscribe to here, or you can leave a comment and I will try to respond. Ladies and gentlemen start your fuzzers!

To check the latest development version of suricata:

git clone git://phalanx.openinfosecfoundation.org/oisf.git

The script relies on a couple of perl modules Capture::Tiny and Devel::GDB. Here are a couple of tips on getting them installed:


Ubuntu 9.10
sudo apt-get install libdevel-gdb-perl libcapture-tiny-perl

RedHatES/CentOS 5
yum -y install cpanspec perl-Module-Build
cpanspec --packager OISF -v -s --follow Capture::Tiny
cpanspec --packager OISF -v -s --follow Devel::GDB
rpmbuild --rebuild *.src.rpm
rpm -ivh /usr/src/redhat/RPMS/noarch/perl-Devel-GDB*.rpm
rpm -ivh /usr/src/redhat/RPMS/noarch/perl-Capture-Tiny*.rpm

Fedora Core 12
yum -y install perl-Capture-Tiny perl-Devel-GDB

Other debain based versions, try the Ubunutu instructions if this doesn't work try the following.
sudo apt-get install dh-make-perl
mkdir fuzzmodules && cd fuzzmodules
dh-make-perl --cpan Devel-GDB --build
dh-make-perl --cpan Capture-Tiny --build
sudo dpkg -i *.deb

Output from wirefuzz.pl -h:

-h or help <(this output)>
-r=<(filemask for pcaps to read)>
-n=<(optional) number of iterations or if not specified will run until error>
-s=<(optional) path to ids rules file will be passed as -s to suricata>
-e=<(optional) editcap error ratio to introduce if not specified will not fuzz. Valid range for this is 0.00 - 1.0>
-p=<(path to the suricata bin)>
-l=<(optional) log dir for output if not specified will use current directory.>
-v=<(optional) (memcheck|drd|helgrind|callgrind) will run the command through one of the specified valgrind tools.>
-y <(shuffle the array, this is useful if running multiple instances of this script.)>

Example usage:
First thing to do is download and build suricata from git with -O0 so vars don't get optimized out. See the example below:
git clone git://phalanx.openinfosecfoundation.org/oisf.git suricatafuzz1 && cd suricatafuzz1 && ./autogen.sh && CFLAGS="-g -O0" ./configure && make

Second thing to do is to edit suricata.yaml to fit your environment.

Third go ahead and run the script.

In the example below the script will loop forever until an error is encountered will behave in the following way.
1.-r Process all pcaps in subdirectories of /home/somepath/pcaps/
2.-s Tell suricata to use the rules file /home/somepath/current-all.rules
3.-y Shuffle the array of pcaps this is useful if running multiple instances of this script.
4.-c Tell suricata to use the suricata.yaml in the current dir.
6.-e Tell editcap to introduce a 2% error ratio, i.e. there is a 2% chance that a byte will be fuzzed see http://wiki.wireshark.org/FuzzTesting for more info.
7.-p Use src/suricata as our suricata bin file. The script will determin if the argument passed is a bin file or a txt wrapper and will adjust accordingly.

/usr/bin/wirefuzz.pl -r=/home/somepath/pcaps/*/* -s=/home/somepath/current-all.rules -y -c=suricata.yaml -e=0.02 -p src/suricata

If an error is encountered a file named ERR.txt will be created in the log dir (current dir in this example) that will contain output from stderr,stdout, and gdb.

Take a look at the opts make it work for you environtment and from the OISF QA team thanks for helping us make our meerkat fuzzier! ;-)

2 comments:

Tedi Heriyanto said...

Will,

Shouldn't the compiler option is "-g -O0" ?

Will Metcalf said...

Tedi, You are correct. This is correct in the script I just messed up pasting it somehow. Thanks for the tip!

Regards,

Will