-
Notifications
You must be signed in to change notification settings - Fork 4
HowTo
There are lots of ways to fuzz test; this document just describes how I do it. m^2 has written a good guide for how to fuzz compression codecs. It's a bit more detailed than this, and he does things a little different.
You'll need a C and/or C++ compiler (depending on the library); GCC or clang will do. You may also need to install an additional package for the AddressSanitizer shared library. Packages vary by distribution, but on Fedora:
dnf install gcc g++ american-fuzzy-lop libasan
If the implementation uses autotools or CMake, you can generally just use environment variables and/or configure script flags to get the necessary configuration. If the implementation uses Makefiles, though, you'll generally need to modify them.
- Set the C compiler to afl-gcc, and the C++ compiler to afl-g++
- Add
-fsanitize=address
to the C/C++ compiler flags - When compiling, make sure the
AFL_HARDEN
environment variable is set to 1 (e.g.,AFL_HARDEN=1 make
CompFuzz comes with a few (not nearly enough, help wanted) small files suitable for seeding the fuzzer. I typically compress each file at every level a compressor offers. For example, if a compressor (called "foo") supports levels 1-9, something like this:
mkdir testcases
for i in path/to/compfuzz/input/*; do
for level in 1 2 3 4 5 6 7 8 9; do
foo --level $level -o testcases/"$i".$level.foo -i "$i"
done
done
Next, you'll want to remove test cases which don't add anything. We'll get in to details about what the AFL arguments need to look like soon, but the basic idea is
mkdir minimized
afl-cmin -i testcases -o minimized -- …
That may or may not prune some files out of the dataset (which will speed up the fuzzer).
[Mostly TODO]
The basic idea is
afl-fuzz -i minimized -o results -- foo --decompress -i /dev/stdin -o /dev/null
If you're using AddressSanitizer you'll probably get an error message, though. See notes_for_asan.txt (it's probably installed at /usr/share/doc/american-fuzzy-lop/notes_for_asan.txt) for more information. To get around the issue, AFL includes a script:
sudo /usr/share/doc/american-fuzzy-lop/experimental/asan_cgroups/limit_memory.sh \
-u $USER afl-fuzz -i minimized -o results -m none foo --decompress -i /dev/stdin -o /dev/null
Fuzzing is slow. AFL includes support for running multiple fuzzers in parallel. I usually fire up screen, and in the first window I put the master:
sudo /usr/share/doc/american-fuzzy-lop/experimental/asan_cgroups/limit_memory.sh \
-u $USER afl-fuzz -i minimized -o results -m none -M fuzzer0 foo --decompress -i /dev/stdin -o /dev/null
Then, for additional cores I launch slaves with:
sudo /usr/share/doc/american-fuzzy-lop/experimental/asan_cgroups/limit_memory.sh \
-u $USER afl-fuzz -i minimized -o results -m none -S fuzzer1 foo --decompress -i /dev/stdin -o /dev/null
(Increment fuzzer1 for each slave).
Finally, you can create an additional window to keep track of everything with something like
while true; do
clear;
afl-whatsup results;
sleep 5;
done