All Projects → vanhauser-thc → afl-dyninst

vanhauser-thc / afl-dyninst

Licence: Apache-2.0 license
American Fuzzy Lop + Dyninst == AFL Fuzzing blackbox binaries

Projects that are alternatives of or similar to afl-dyninst

Aflplusplus
The fuzzer afl++ is afl with community patches, qemu 5.1 upgrade, collision-free coverage, enhanced laf-intel & redqueen, AFLfast++ power schedules, MOpt mutators, unicorn_mode, and a lot more!
Stars: ✭ 2,319 (+3467.69%)
Mutual labels:  instrumentation, fuzzing, afl, afl-fuzz, fuzzer, afl-fuzzer
afl-dynamorio
run AFL with dynamorio
Stars: ✭ 32 (-50.77%)
Mutual labels:  fuzzing, afl, afl-fuzz, fuzzer, afl-fuzzer
afl-pin
run AFL with pintool
Stars: ✭ 64 (-1.54%)
Mutual labels:  fuzzing, afl, afl-fuzz, fuzzer, afl-fuzzer
fuzzuf
Fuzzing Unification Framework
Stars: ✭ 263 (+304.62%)
Mutual labels:  fuzzing, afl, afl-fuzz, fuzzer
e9afl
AFL binary instrumentation
Stars: ✭ 234 (+260%)
Mutual labels:  instrumentation, fuzzing, afl, afl-fuzz
unicorn-fuzzer
expansion of afl-unicorn using c++
Stars: ✭ 25 (-61.54%)
Mutual labels:  fuzzing, fuzzer, afl-fuzzer
Grammar-Mutator
A grammar-based custom mutator for AFL++
Stars: ✭ 133 (+104.62%)
Mutual labels:  fuzzing, afl, afl-fuzz
LibAFL
Advanced Fuzzing Library - Slot your Fuzzer together in Rust! Scales across cores and machines. For Windows, Android, MacOS, Linux, no_std, ...
Stars: ✭ 1,348 (+1973.85%)
Mutual labels:  fuzzing, afl, afl-fuzz
Fuzzing Survey
The Art, Science, and Engineering of Fuzzing: A Survey
Stars: ✭ 116 (+78.46%)
Mutual labels:  fuzzing, fuzzer
Sienna Locomotive
A user-friendly fuzzing and crash triage tool for Windows
Stars: ✭ 130 (+100%)
Mutual labels:  fuzzing, fuzzer
Janus
Janus: a state-of-the-art file system fuzzer on Linux
Stars: ✭ 139 (+113.85%)
Mutual labels:  fuzzing, fuzzer
Clusterfuzz Tools
Bugs are inevitable. Suffering is optional.
Stars: ✭ 111 (+70.77%)
Mutual labels:  fuzzing, fuzzer
Fisy Fuzz
This is the full file system fuzzing framework that I presented at the Hack in the Box 2020 Lockdown Edition conference in April.
Stars: ✭ 110 (+69.23%)
Mutual labels:  fuzzing, fuzzer
Winafl
A fork of AFL for fuzzing Windows binaries
Stars: ✭ 1,826 (+2709.23%)
Mutual labels:  fuzzing, afl
Ansvif
A Not So Very Intelligent Fuzzer: An advanced fuzzing framework designed to find vulnerabilities in C/C++ code.
Stars: ✭ 107 (+64.62%)
Mutual labels:  fuzzing, fuzzer
Pythonfuzz
coverage guided fuzz testing for python
Stars: ✭ 175 (+169.23%)
Mutual labels:  fuzzing, fuzzer
Sharpfuzz
AFL-based fuzz testing for .NET
Stars: ✭ 185 (+184.62%)
Mutual labels:  fuzzing, fuzzer
Crlf Injection Scanner
Command line tool for testing CRLF injection on a list of domains.
Stars: ✭ 91 (+40%)
Mutual labels:  fuzzing, fuzzer
Grammarinator
ANTLR v4 grammar-based test generator
Stars: ✭ 162 (+149.23%)
Mutual labels:  fuzzing, fuzzer
Javafuzz
coverage guided fuzz testing for java
Stars: ✭ 193 (+196.92%)
Mutual labels:  fuzzing, fuzzer

American Fuzzy Lop + Dyninst == AFL Fuzzing blackbox binaries

The tool has two parts. The instrumentation tool and the instrumentation library. Instrumentation library has an initialization callback and basic block callback functions which are designed to emulate what AFL is doing with afl-gcc/afl-g++/afl-as.

Instrumentation tool (afl-dyninst) instruments the supplied binary by inserting callbacks for each basic block and an initialization callback either at _init or at specified entry point.

You can pull a docker image from hub (last push February 2021):

docker pull vanhauser/afl-dyninst

Building / Compiling

docker

simply run

docker build -t afl-dyninst .

which will take ~25 minutes. Afterwards you have a containers with afl-dyninst and afl++:

docker run -ti afl-dyninst

on your own

  1. Clone, compile and install dyninst: https://github.com/dyninst/dyninst

Note that you could also use dyninst 9.3.2, but has less platform support and quite a few bugs. For using dyninst 9.x you have to edit the Makefile Using at least 10.1.0 is highly recommended!

  1. Download and install afl++ from https://github.com/vanhauser-thc/AFLplusplus It's an up to date and enhanced version to the original afl with better performance, new features and bugfixes.

  2. Edit the Makefile and set DYNINST_ROOT and AFL_ROOT to appropriate paths.

  3. make

  4. sudo make install

Building dyninst 10

Building dyninst10 can be a pain. If you are not on debian-testing or kali-rolling, I recommend the following steps:

  1. remove elfutils if installed as a distribution package
  2. install libboost-all-dev for your distribution
  3. execute (depending where your libboost is installed, for me its /usr/lib/x86_64-linux-gnu):
cd /usr/lib/x86_64-linux-gnu && for i in libboost*.so libboost*.a; do
  n=`echo $i|sed 's/\./-mt./'`
  ln -s $i $n 2> /dev/null
done
  1. git clone https://github.com/dyninst/dyninst ; mkdir build ; cd build ; cmake .. ; make ; make install If dyninst complains about any missing packages - install them. Depending on the age of your Linux OS you can try to use packages from your distro, and install from source otherwise.

Commandline options

Usage: afl-dyninst -dfvxD -i binary -o  binary -l library -e address -E address -s number -S funcname -I funcname -m size
   -i: input binary program
   -o: output binary program
   -r: runtime library to instrument (path to, repeat for more than one)
   -e: entry point address to patch (required for stripped binaries)
   -E: exit point - force exit(0) at this address (repeat for more than one)
   -s: number of initial basic blocks to skip in binary
   -m: minimum size of a basic bock to instrument (default: 10)
   -f: try to fix a dyninst bug that leads to crashes (loss of 20%% performance, only required for dyninst9)
   -I: only instrument this function and nothing else (repeat for more than one)
   -S: do not instrument this function (repeat for more than one)
   -D: instrument only a simple fork server and also forced exit functions
   -x: experimental performance mode (~25-50% speed improvement)
   -v: verbose output
   Note: options -l and -d have been deprecated, use -r and -D instead.

Switch -e is used to manualy specify the entry point where initialization callback is to be inserted. For unstipped binaries, afl-dyninst defaults to using _init of the binary as an entry point. In case of stripped binaries this option is required and is best set to the address of main which can easily be determined by disassembling the binary and looking for an argument to __libc_start_main.

Switch -E is used to specify addresses that should force a clean exit when reached. This can speed up the fuzzing tremendously.

Switch -s instructs afl-dyninst to skip the first NUMBER of basic blocks. Currently, it is used to work around a bug in Dyninst but doubles as an optimization option, as skipping the basic blocks of the initialization routines makes things run faster. If the instrumented binary is crashing by itself, try skiping a number of blocks.

Switch -r allows you to specify a path to a library that is loaded via dlopen() at runtime. Instrumented runtime libraries will be written to the same location with a ".ins" suffix as not to overwrite the original ones. Make sure to backup the originals and then rename the instrumented ones to original name.

Switch -m allows you to only instrument basic blocks of a minimum size - the default minimum size is 1

Switch -f fixes a dyninst bug that lead to bugs in the instrumented program: our basic block instrumentation function loaded into the instrumentd binaries uses the edi/rdi. However dyninst does not always saves and restores it when instrumenting that function leading to crashes and changed program behaviour when the register is used for function parameters.

Switch -S allows you to not instrument specific functions. This options is mainly to hunt down bugs in dyninst. Can be specified multiple times.

Switch -I specified to only instrument specific functions. This option is amazing with large and threaded targets. Can be specified multiple times.

Switch -D installs the afl fork server and forced exit functions but no basic block instrumentation. That would serve no purpose - unless there are other tools that need that:

Switch -x enables an experimental performance mode (+25-50% speed). Just try it and if the target crashes too often, instrument again without this. Should not crash though.

Note that the -l option has been deprecated, use -r instead.

Note that the -d option has been deprecated, use -D instead (or ignore the -o output file).

Example of instrumenting a target binary

Dyninst requires DYNINSTAPI_RT_LIB environment variable to point to the location of libdyninstAPI_RT.so.

$ export DYNINSTAPI_RT_LIB=/usr/local/lib/libdyninstAPI_RT.so
$ ./afl-dyninst -i ./unrar -o ./rar_ins -e 0x4034c0 -x
Skipping library: libAflDyninst.so
Instrumenting module: DEFAULT_MODULE
Inserting init callback.
Saving the instrumented binary to ./unrar_ins...
All done! Happy fuzzing!

Here we are instrumenting the rar binary with entrypoint at 0x4034c0 (manually found address of main), skipping the first 10 basic blocks and outputing to unrar_ins

You can also use the afl-dyninst.sh helper script which sets the required environment variables for you:

$ ./afl-dyninst.sh -i ./unrar -o ./rar_ins -e 0x4034c0 -x

Running AFL on the instrumented binary

NOTE: The instrumentation library "libDyninst.so" must be available in the current working directory or LD_LIBRARY_PATH as that is where the instrumented binary will be looking for it.

Since AFL checks if the binary has been instrumented by afl-gcc, the AFL_SKIP_BIN_CHECK environment variable needs to be set. No modifications to AFL itself is needed.

$ export AFL_SKIP_BIN_CHECK=1

Then, AFL can be run as usual:

$ afl-fuzz -i testcases/archives/common/gzip/ -o test_gzip -- ./gzip_ins -d -c 

You can also use the afl-fuzz-dyninst.sh helper script which sets the required environment variables for you.

$ afl-fuzz-dyninst.sh -i testcases/archives/common/gzip/ -o test_gzip -- ./gzip_ins -d -c 

Problems

After instrumenting the target binary always check if it works. Dyninst is making big changes to the code, and hence more often than not things are not working anymore.

Problem 1: The binary does not work (crashes or hangs)

Solution: increase the -m parameter. -m 8 is the minimum recommended, on some targets -m 16 is required etc. You can also try to remove the -x performance enhancer

Problem 2: Basically every fuzzing test case is reported as crash although it does not when running it from the command line

Solution: This happens if the target is using throw/catch, and dyninst's modification result in that the caught exception is not resetted and hence abort() is triggered. No solution to this issue is known yet. Binary editing the target binary to perform _exit(0) would help though.

More problems? Create an issue at https://github.com/vanhauser-thc/afl-dyninst

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].