advanced
Using libFuzzer, AFL, and honggfuzz OSS fuzzers with Mayhem¶
In this lesson, we'll walk through how to use the three most popular open-source software fuzzing frameworks with Mayhem: libFuzzer, AFL, and honggfuzz.
Estimated Time: 15 minutes
By the end of this lesson, you will be able to:
- Define the AFL, libFuzzer, and honggfuzz fuzzing frameworks.
- Configure the
Mayhemfile
to use each respective fuzzing framework for thetestme
target. - Perform Mayhem runs on the
testme
target using each fuzzing framework.
Run through the lesson:
See prerequisites before beginning.
-
Package the libFuzzer-instrumented
testme
binary using themayhem package
command:mayhem package ./testme -o /tmp/libfuzzer-pkg
-
Execute a Mayhem run on the libFuzzer-instrumented
testme
binary using themayhem run
command with the following Mayhemfile:1 2 3 4 5 6 7 8 9
project: libfuzzer target: testme duration: 90 advanced_triage: false cmds: - cmd: /root/tutorial/oss-fuzzers/libfuzzer/testme libfuzzer: true sanitizer: true
-
Package the afl-instrumented
testme
binary using themayhem package
command:mayhem package ./testme -o /tmp/afl-pkg
-
Execute a Mayhem run on the afl-instrumented
testme
binary using themayhem run
command with the following Mayhemfile:1 2 3 4 5 6 7 8
project: afl target: testme duration: 90 advanced_triage: false cmds: - cmd: /root/tutorial/oss-fuzzers/afl/testme @@ afl: true
-
Package the honggfuzz-instrumented
testme
binary (compiled withhfuzz-clang
) using themayhem package
command:mayhem package ./testme -o /tmp/hfuzz-libfuzzer-pkg
-
Execute a Mayhem run on the honggfuzz-instrumented
testme
binary (compiled withhfuzz-clang
) using themayhem run
command with the following Mayhemfile:1 2 3 4 5 6 7 8 9
project: honggfuzz-libfuzzer target: testme duration: 90 advanced_triage: false cmds: - cmd: /root/tutorial/oss-fuzzers/honggfuzz-libfuzzer/testme honggfuzz: true sanitizer: true
-
Package the honggfuzz-instrumented
testme
binary (compiled withhfuzz-gcc
) using themayhem package
command:mayhem package ./testme -o /tmp/honggfuzz-pkg
-
Execute a Mayhem run on the honggfuzz-instrumented
testme
binary (compiled withhfuzz-gcc
) using themayhem run
command with the following Mayhemfile:1 2 3 4 5 6 7 8
project: honggfuzz target: testme duration: 90 advanced_triage: false cmds: - cmd: /root/tutorial/oss-fuzzers/honggfuzz/testme honggfuzz: true
You will need the following:
- The Mayhem CLI installed and authenticated with the Mayhem server.
-
Access to the tutorial examples by running the pre-built Docker image.
docker pull forallsecure/tutorial:2.10 docker run -ti --privileged --rm forallsecure/tutorial:2.10
Fuzzing with LibFuzzer¶
LibFuzzer is an in-process fuzzer produced by the LLVM project. An in-process fuzzer doesn't use fork() to re-execute the program on each invocation, but instead repeatedly calls a target function with new inputs within the same in-memory process.
To build and run this example, change directory (cd
) to oss-fuzzers/libfuzzer
. We use a new version of testme.c
, which is shown below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
|
The changes are:
-
Line 17: the previous
testme.c
used theabort()
function to create an improper input validation defect. We've replaced theabort()
function with an invalid memory access. -
Line 22-26: LibFuzzer requires you write a test driver. We cover test drivers in more detail later. For now, the important part is that LibFuzzer requires you specify the function to test, and passes two arguments:
Data
andSize
. The two arguments are filled in by the fuzzer.
To use LibFuzzer with Mayhem, you need to specify libfuzzer: true
for the command (cmd
) to execute. In addition, you need to specify that the target is built with a sanitizer with sanitizer: true
.
Note
You use sanitizer: true
for any sanitizer (UndefinedBehaviorSanitizer, AddressSanitizer, MemorySanitizer, etc.).
Here is a complete Mayhemfile
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
To run Mayhem, execute the following commands:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
Go to the Mayhem UI, and you should see Mayhem fuzzing the target!
Fuzzing with AFL¶
AFL is a well-known process-based fuzzer. To use AFL, you need to recompile your application with the AFL toolchain. The toolchain inlines AFL instrumentation into the executable, which is used to guide the fuzzer.
To build and run this example, change directory (cd
) to oss-fuzzers/afl
. In that directory, you will find:
testme.c
, which is the same vulnerable application from previous lessons.-
Makefile
, which is a UNIX Makefile to build the target with AFL instrumentation. We use theafl-gcc
command, which usesgcc
as in our previous examples. To build the target runmake clean && make
-
The
Mayhemfile
, as shown below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
|
Note that we've added afl: true
to the Mayhemfile
. This tells Mayhem that the target is compiled with AFL.
To run Mayhem, execute the following commands:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
Go to the Mayhem UI, and you should see Mayhem fuzzing the target!
Fuzzing with honggfuzz¶
Honggfuzz is a security oriented, feedback-driven, evolutionary, easy-to-use fuzzer with several analysis options. Honggfuzz provides compiler wrappers for clang and GCC such as hfuzz-clang
and hfuzz-gcc
, respectively, which allow for compiling in different forms of compile time coverage instrumentation.
Users can use either the hfuzz-clang
or hfuzz-gcc
compiler wrappers interchangeably.
Info
Honggfuzz has several modes; however, we'll show you how to use LLVMFuzzerTestOneInput
or HF_ITER
style test drivers to compile honggfuzz persistent mode binaries for this lesson. See honggfuzz's persistent mode for more information.
Honggfuzz with hfuzz-clang
(Recommended)¶
Mayhem supports fuzzing honggfuzz persistent mode binaries compiled using hfuzz-clang
. Here we'll show how to compile using libFuzzer-style test drivers (e.g. LLVMFuzzerTestOneInput
).
To build and run this example, change directory (cd
) to oss-fuzzers/honggfuzz-libfuzzer
. You will find:
testme.c
, which is the same vulnerable application from the libFuzzer example above.Makefile
, which is a UNIX Makefile to build the target. TheMakefile
useshfuzz-clang
.- The
Mayhemfile
, as shown below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
|
Note
You will need to specify honggfuzz: true
and sanitizer: true
. The honggfuzz: true
instructs Mayhem to use the honggfuzz fuzzer, while sanitizer: true
tells Mayhem that the binary is compiled with a sanitizer.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
Go to the Mayhem UI, and you should see Mayhem fuzzing the target!
Warning
If you do not have the sanitizer: true
with an sanitizer target Mayhem will not correctly report found bugs.
Honggfuzz with hfuzz-gcc
¶
Mayhem also supports fuzzing honggfuzz persistent mode binaries compiled using hfuzz-gcc
. Here we'll show how to compile binaries using HF_ITER
style test drivers.
Info
Mayhem can also run non-persistent mode binaries compiled with Honggfuzz instrumentation. However, non-persistent mode binaries will be treated the same as non-instrumented binaries and is not recommended.
Let's view a basic example! Change directory (cd
) to oss-fuzzers/honggfuzz
. Here you will find the following:
testme.c
, which is a modified version of thetestme
application from previous lessons.Makefile
, which is a UNIX Makefile to build the target. TheMakefile
useshfuzz-gcc
. This adds special honggfuzz instrumentation.Mayhemfile
, which is the configuration file for the Mayhem run.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
|
Notice that the modified testme.c
uses the HF_ITER
function, indicating that this is a persistent mode binary.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
As a result the @@
should be removed from the cmd
parameter for the persistent mode testme
binary.
To run Mayhem, execute the following commands:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
Go to the Mayhem UI, and you should see Mayhem fuzzing the target!
✏️ Summary and Recap¶
In this lesson, you learned how to fuzz targets with the AFL, libFuzzer, and honggfuzz fuzzing frameworks.
I learned how to...
1. Define the AFL, libFuzzer, and honggfuzz fuzzing frameworks.
- AFL is a well-known process-based fuzzer. To use AFL, you need to recompile your application with the AFL toolchain. The toolchain inlines AFL instrumentation into the executable, which is used to guide the fuzzer.
- LibFuzzer is an in-process fuzzer produced by the LLVM project. An in-process fuzzer doesn't use fork() to re-execute the program on each invocation, but instead repeatedly calls a target function with new inputs within the same in-memory process.
- Honggfuzz is a security oriented, feedback-driven, evolutionary, easy-to-use fuzzer with interesting analysis options. Honggfuzz has the ability to compile in different types of instrumentation, including it's own with
hfuzz-gcc
and libFuzzer.
2. Configure the Mayhemfile to use each respective fuzzing framework for the testme target.
-
AFL Mayhemfile:
1 2 3 4 5 6 7
project: afl target: testme duration: 90 advanced_triage: false cmds: - cmd: /root/tutorial/oss-fuzzers/afl/testme @@ afl: true
-
LibFuzzer Mayhemfile:
1 2 3 4 5 6 7 8 9
project: libfuzzer target: testme duration: 90 advanced_triage: false cmds: - cmd: /root/tutorial/oss-fuzzers/libfuzzer/testme libfuzzer: true # this is a libfuzzer target sanitizer: true # A sanitizer was used (the average case)
-
Honggfuzz Mayhemfile:
1 2 3 4 5 6 7 8 9
project: honggfuzz-libfuzzer target: testme duration: 90 advanced_triage: false cmds: - cmd: /root/tutorial/oss-fuzzers/honggfuzz-libfuzzer/testme honggfuzz: true sanitizer: true
3. Perform Mayhem runs on the testme target using each fuzzing framework.
- Execute the
mayhem run
command for each of the AFL, libFuzzer, and honggfuzz targets.