AFL Fuzz Testing

This guide uses Ubuntu, but should largely apply to other distro's.

Getting & compiling AFL

apt-get install llvm clang
tar xzvf afl-latest.tgz
cd afl-2.10b
cd llvm_mode
cd ..
sudo make install

In /usr/local/bin/ you should now have afl-clang-fast.

Compiling Suricata

export ac_cv_func_realloc_0_nonnull=yes
export ac_cv_func_malloc_0_nonnull=yes
CC=/usr/local/bin/afl-clang-fast CFLAGS="-fsanitize=address -fno-omit-frame-pointer" ./configure --enable-afl --disable-shared

Now the ./src/suricata binary can be used. Test it by issuing './src/suricata --build-info'

Getting input data

AFL is surprisingly good at generating input to Suricata. So simply doing:

mkdir input
echo "1" > input/sample.txt

will already yield good results.

However, depending on the interface to Suricata that is used, it may be useful to add some real inputs (one per file).

Running AFL

When running for example the DNS entrypoint:

mkdir dns-output
/usr/local/bin/afl-fuzz -t 1000 -m none -i input/ -o dns-output/ -- src/suricata --afl-dns=@@

There is a lot more to AFL, but this should be enough to get started. has lots of documentation.

Suricata options for AFL

These options are available for direct access to Suricata internals:

app layer

The -request variant only sends the data AFL generates to the request parsers. The plain variant alternates data between request and response parsers every 64 bytes.


packet decoders