mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-14 11:08:06 +00:00
update readme, renice -20
This commit is contained in:
@ -96,7 +96,7 @@ ifneq "$(shell uname -m)" "x86_64"
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
CFLAGS ?= -O3 -funroll-loops $(CFLAGS_OPT)
|
CFLAGS ?= -O3 -funroll-loops $(CFLAGS_OPT)
|
||||||
override CFLAGS += -Wall -g -Wno-pointer-sign -Wmissing-declarations\
|
override CFLAGS += -Wall -g -Wno-pointer-sign -Wmissing-declarations -Wno-unused-result \
|
||||||
-I include/ -DAFL_PATH=\"$(HELPER_PATH)\" \
|
-I include/ -DAFL_PATH=\"$(HELPER_PATH)\" \
|
||||||
-DBIN_PATH=\"$(BIN_PATH)\" -DDOC_PATH=\"$(DOC_PATH)\"
|
-DBIN_PATH=\"$(BIN_PATH)\" -DDOC_PATH=\"$(DOC_PATH)\"
|
||||||
|
|
||||||
|
595
README.md
595
README.md
@ -1,4 +1,4 @@
|
|||||||
# american fuzzy lop plus plus (afl++)
|
# American Fuzzy Lop plus plus (afl++)
|
||||||
|
|
||||||
<img align="right" src="https://raw.githubusercontent.com/andreafioraldi/AFLplusplus-website/master/static/logo_256x256.png" alt="AFL++ Logo">
|
<img align="right" src="https://raw.githubusercontent.com/andreafioraldi/AFLplusplus-website/master/static/logo_256x256.png" alt="AFL++ Logo">
|
||||||
|
|
||||||
@ -8,61 +8,36 @@
|
|||||||
|
|
||||||
Github Version: 2.66d
|
Github Version: 2.66d
|
||||||
|
|
||||||
includes all necessary/interesting changes from Google's afl 2.56b
|
|
||||||
|
|
||||||
Originally developed by Michal "lcamtuf" Zalewski.
|
|
||||||
|
|
||||||
Repository: [https://github.com/AFLplusplus/AFLplusplus](https://github.com/AFLplusplus/AFLplusplus)
|
Repository: [https://github.com/AFLplusplus/AFLplusplus](https://github.com/AFLplusplus/AFLplusplus)
|
||||||
|
|
||||||
afl++ is maintained by:
|
afl++ is maintained by:
|
||||||
* Marc "van Hauser" Heuse <mh@mh-sec.de>,
|
|
||||||
* Heiko "hexcoder-" Eißfeldt <heiko.eissfeldt@hexco.de>,
|
|
||||||
* Andrea Fioraldi <andreafioraldi@gmail.com> and
|
|
||||||
* Dominik Maier <mail@dmnk.co>.
|
|
||||||
|
|
||||||
Note that although afl now has a Google afl repository [https://github.com/Google/afl](https://github.com/Google/afl),
|
* Marc "van Hauser" Heuse <mh@mh-sec.de>,
|
||||||
it is unlikely to receive any notable enhancements: [https://twitter.com/Dor3s/status/1154737061787660288](https://twitter.com/Dor3s/status/1154737061787660288)
|
* Heiko "hexcoder-" Eißfeldt <heiko.eissfeldt@hexco.de>,
|
||||||
|
* Andrea Fioraldi <andreafioraldi@gmail.com> and
|
||||||
|
* Dominik Maier <mail@dmnk.co>.
|
||||||
|
|
||||||
## The enhancements compared to the original stock afl
|
Originally developed by Michal "lcamtuf" Zalewski.
|
||||||
|
|
||||||
Many improvements were made over the official afl release - which did not
|
afl++ is a superiour fork to Google's afl - more speed, more and better
|
||||||
get any feature improvements since November 2017.
|
mutations, more and better instrumentation, custom module support, etc.
|
||||||
|
|
||||||
Among other changes afl++ has a more performant llvm_mode, supports
|
## Contents
|
||||||
llvm up to version 12, QEMU 3.1, more speed and crashfixes for QEMU,
|
|
||||||
better *BSD and Android support and much, much more.
|
|
||||||
|
|
||||||
Additionally the following features and patches have been integrated:
|
1. [Features](#important-features-of-afl)
|
||||||
|
2. [How to compile and install afl++](#building-and-installing-afl)
|
||||||
|
3. [How to fuzz a target](#how-to-fuzz-with-afl)
|
||||||
|
4. [Fuzzing binary-only targets](#fuzzing-binary-only-targets)
|
||||||
|
5. [Good examples and writeups of afl++ usages](#good-examples-and-writeups)
|
||||||
|
6. [Branches](#branches)
|
||||||
|
7. [Want to help?](#help-wanted)
|
||||||
|
8. [Detailed help and description of afl++](#challenges-of-guided-fuzzing)
|
||||||
|
|
||||||
* AFLfast's power schedules by Marcel Böhme: [https://github.com/mboehme/aflfast](https://github.com/mboehme/aflfast)
|
## Important features of afl++
|
||||||
|
|
||||||
* The new excellent MOpt mutator: [https://github.com/puppet-meteor/MOpt-AFL](https://github.com/puppet-meteor/MOpt-AFL)
|
afl++ supports llvm up to version 12, very fast binary fuzzing with QEMU 3.1
|
||||||
|
with laf-intel and redqueen, unicorn mode, gcc plugin, full *BSD, Solaris and
|
||||||
* InsTrim, a very effective CFG llvm_mode instrumentation implementation for large targets: [https://github.com/csienslab/instrim](https://github.com/csienslab/instrim)
|
Android support and much, much, much more.
|
||||||
|
|
||||||
* C. Holler's afl-fuzz Python mutator module and llvm_mode instrument file support: [https://github.com/choller/afl](https://github.com/choller/afl)
|
|
||||||
|
|
||||||
* Custom mutator by a library (instead of Python) by kyakdan
|
|
||||||
|
|
||||||
* Unicorn mode which allows fuzzing of binaries from completely different platforms (integration provided by domenukk)
|
|
||||||
|
|
||||||
* LAF-Intel or CompCov support for llvm_mode, qemu_mode and unicorn_mode
|
|
||||||
|
|
||||||
* NeverZero patch for afl-gcc, llvm_mode, qemu_mode and unicorn_mode which prevents a wrapping map value to zero, increases coverage
|
|
||||||
|
|
||||||
* Persistent mode and deferred forkserver for qemu_mode
|
|
||||||
|
|
||||||
* Win32 PE binary-only fuzzing with QEMU and Wine
|
|
||||||
|
|
||||||
* Radamsa mutator (as a custom mutator).
|
|
||||||
|
|
||||||
* QBDI mode to fuzz android native libraries via QBDI framework
|
|
||||||
|
|
||||||
* The new CmpLog instrumentation for LLVM and QEMU inspired by [Redqueen](https://www.syssec.ruhr-uni-bochum.de/media/emma/veroeffentlichungen/2018/12/17/NDSS19-Redqueen.pdf)
|
|
||||||
|
|
||||||
* LLVM mode Ngram coverage by Adrian Herrera [https://github.com/adrianherrera/afl-ngram-pass](https://github.com/adrianherrera/afl-ngram-pass)
|
|
||||||
|
|
||||||
A more thorough list is available in the [PATCHES](docs/PATCHES.md) file.
|
|
||||||
|
|
||||||
| Feature/Instrumentation | afl-gcc | llvm_mode | gcc_plugin | qemu_mode | unicorn_mode |
|
| Feature/Instrumentation | afl-gcc | llvm_mode | gcc_plugin | qemu_mode | unicorn_mode |
|
||||||
| ----------------------- |:-------:|:---------:|:----------:|:----------------:|:------------:|
|
| ----------------------- |:-------:|:---------:|:----------:|:----------------:|:------------:|
|
||||||
@ -75,6 +50,7 @@
|
|||||||
| InsTrim | | x | | | |
|
| InsTrim | | x | | | |
|
||||||
| Ngram prev_loc coverage | | x(6) | | | |
|
| Ngram prev_loc coverage | | x(6) | | | |
|
||||||
| Context coverage | | x | | | |
|
| Context coverage | | x | | | |
|
||||||
|
| Auto dictionary | | x(7) | | | |
|
||||||
| Snapshot LKM support | | x | | (x)(5) | |
|
| Snapshot LKM support | | x | | (x)(5) | |
|
||||||
|
|
||||||
neverZero:
|
neverZero:
|
||||||
@ -85,11 +61,45 @@
|
|||||||
|
|
||||||
(3) partially via AFL_CODE_START/AFL_CODE_END
|
(3) partially via AFL_CODE_START/AFL_CODE_END
|
||||||
|
|
||||||
(4) Only for LLVM >= 11 and not all targets compile
|
(4) with pcguard mode and LTO mode for LLVM >= 11
|
||||||
|
|
||||||
(5) upcoming, development in the branch
|
(5) upcoming, development in the branch
|
||||||
|
|
||||||
(6) not compatible with LTO instrumentation and needs at least LLVM >= 4.1
|
(6) not compatible with LTO instrumentation and needs at least LLVM >= 4.1
|
||||||
|
|
||||||
|
(7) only in LTO mode with LLVM >= 11
|
||||||
|
|
||||||
|
Among others, the following features and patches have been integrated:
|
||||||
|
|
||||||
|
* NeverZero patch for afl-gcc, llvm_mode, qemu_mode and unicorn_mode which prevents a wrapping map value to zero, increases coverage
|
||||||
|
|
||||||
|
* Persistent mode and deferred forkserver for qemu_mode
|
||||||
|
|
||||||
|
* Unicorn mode which allows fuzzing of binaries from completely different platforms (integration provided by domenukk)
|
||||||
|
|
||||||
|
* The new CmpLog instrumentation for LLVM and QEMU inspired by [Redqueen](https://www.syssec.ruhr-uni-bochum.de/media/emma/veroeffentlichungen/2018/12/17/NDSS19-Redqueen.pdf)
|
||||||
|
|
||||||
|
* Win32 PE binary-only fuzzing with QEMU and Wine
|
||||||
|
|
||||||
|
* AFLfast's power schedules by Marcel Böhme: [https://github.com/mboehme/aflfast](https://github.com/mboehme/aflfast)
|
||||||
|
|
||||||
|
* The MOpt mutator: [https://github.com/puppet-meteor/MOpt-AFL](https://github.com/puppet-meteor/MOpt-AFL)
|
||||||
|
|
||||||
|
* LLVM mode Ngram coverage by Adrian Herrera [https://github.com/adrianherrera/afl-ngram-pass](https://github.com/adrianherrera/afl-ngram-pass)
|
||||||
|
|
||||||
|
* InsTrim, an effective CFG llvm_mode instrumentation implementation for large targets: [https://github.com/csienslab/instrim](https://github.com/csienslab/instrim)
|
||||||
|
|
||||||
|
* C. Holler's afl-fuzz Python mutator module and llvm_mode instrument file support: [https://github.com/choller/afl](https://github.com/choller/afl)
|
||||||
|
|
||||||
|
* Custom mutator by a library (instead of Python) by kyakdan
|
||||||
|
|
||||||
|
* LAF-Intel/CompCov support for llvm_mode, qemu_mode and unicorn_mode (with enhanced capabilities)
|
||||||
|
|
||||||
|
* Radamsa and hongfuzz mutators (as custom mutators).
|
||||||
|
|
||||||
|
* QBDI mode to fuzz android native libraries via QBDI framework
|
||||||
|
|
||||||
|
A more thorough list is available in the [PATCHES](docs/PATCHES.md) file.
|
||||||
|
|
||||||
So all in all this is the best-of afl that is currently out there :-)
|
So all in all this is the best-of afl that is currently out there :-)
|
||||||
|
|
||||||
@ -115,7 +125,7 @@
|
|||||||
|
|
||||||
For releases, please see the [Releases](https://github.com/AFLplusplus/AFLplusplus/releases) tab.
|
For releases, please see the [Releases](https://github.com/AFLplusplus/AFLplusplus/releases) tab.
|
||||||
|
|
||||||
## Google Summer of Code 2020 (and any other students and enthusiast developers)
|
## Help wanted
|
||||||
|
|
||||||
We are happy to be part of [Google Summer of Code 2020](https://summerofcode.withgoogle.com/organizations/5100744400699392/)! :-)
|
We are happy to be part of [Google Summer of Code 2020](https://summerofcode.withgoogle.com/organizations/5100744400699392/)! :-)
|
||||||
|
|
||||||
@ -140,7 +150,7 @@ hence afl-clang-lto is available!) or just pull directly from the docker hub:
|
|||||||
docker pull aflplusplus/aflplusplus
|
docker pull aflplusplus/aflplusplus
|
||||||
docker run -ti -v /location/of/your/target:/src aflplusplus/aflplusplus
|
docker run -ti -v /location/of/your/target:/src aflplusplus/aflplusplus
|
||||||
```
|
```
|
||||||
This container is automatically generated when a push to master happens.
|
This image is automatically generated when a push to master happens.
|
||||||
You will find your target source code in /src in the container.
|
You will find your target source code in /src in the container.
|
||||||
|
|
||||||
If you want to build afl++ yourself you have many options.
|
If you want to build afl++ yourself you have many options.
|
||||||
@ -151,7 +161,7 @@ sudo apt install build-essential libtool-bin python3-dev automake flex bison lib
|
|||||||
make distrib
|
make distrib
|
||||||
sudo make install
|
sudo make install
|
||||||
```
|
```
|
||||||
It is recommended to install the newest available gcc and clang and llvm-dev
|
It is recommended to install the newest available gcc, clang and llvm-dev
|
||||||
possible in your distribution!
|
possible in your distribution!
|
||||||
|
|
||||||
Note that "make distrib" also builds llvm_mode, qemu_mode, unicorn_mode and
|
Note that "make distrib" also builds llvm_mode, qemu_mode, unicorn_mode and
|
||||||
@ -197,6 +207,444 @@ These build options exist:
|
|||||||
|
|
||||||
e.g.: make ASAN_BUILD=1
|
e.g.: make ASAN_BUILD=1
|
||||||
|
|
||||||
|
## Good examples and writeups
|
||||||
|
|
||||||
|
Here are some good writeups to show how to effectively use AFL++:
|
||||||
|
|
||||||
|
* [https://aflplus.plus/docs/tutorials/libxml2_tutorial/](https://aflplus.plus/docs/tutorials/libxml2_tutorial/)
|
||||||
|
* [https://bananamafia.dev/post/gb-fuzz/](https://bananamafia.dev/post/gb-fuzz/)
|
||||||
|
* [https://securitylab.github.com/research/fuzzing-challenges-solutions-1](https://securitylab.github.com/research/fuzzing-challenges-solutions-1)
|
||||||
|
* [https://securitylab.github.com/research/fuzzing-sockets-FTP](https://securitylab.github.com/research/fuzzing-sockets-FTP)
|
||||||
|
|
||||||
|
If you are interested in fuzzing structured data (where you define what the
|
||||||
|
structure is), these links have you covered:
|
||||||
|
* Superion for afl++: [https://github.com/adrian-rt/superion-mutator](https://github.com/adrian-rt/superion-mutator)
|
||||||
|
* libprotobuf raw: [https://github.com/bruce30262/libprotobuf-mutator_fuzzing_learning/tree/master/4_libprotobuf_aflpp_custom_mutator](https://github.com/bruce30262/libprotobuf-mutator_fuzzing_learning/tree/master/4_libprotobuf_aflpp_custom_mutator)
|
||||||
|
* libprotobuf for old afl++ API: [https://github.com/thebabush/afl-libprotobuf-mutator](https://github.com/thebabush/afl-libprotobuf-mutator)
|
||||||
|
|
||||||
|
If you find other good ones, please send them to us :-)
|
||||||
|
|
||||||
|
## How to fuzz with afl++
|
||||||
|
|
||||||
|
The following describes how to fuzz with a target if source code is available.
|
||||||
|
If you have a binary-only target please skip to [#Instrumenting binary-only apps](#Instrumenting binary-only apps)
|
||||||
|
|
||||||
|
Fuzzing source code is a two step process.
|
||||||
|
|
||||||
|
1. compile the target with a special compiler that prepares the target to be
|
||||||
|
fuzzed efficiently. This step is called "instrumenting a target".
|
||||||
|
2. Prepare the fuzzing by selecting and optimizing the input corpus for the
|
||||||
|
target.
|
||||||
|
3. perform the fuzzing of the target by randomly mutating input and assessing
|
||||||
|
if a generated input was processed in a new path in the target binary
|
||||||
|
|
||||||
|
### 1. Instrumenting that target
|
||||||
|
|
||||||
|
#### a) Selecting the best afl++ compiler for instrumenting the target
|
||||||
|
|
||||||
|
afl++ comes with different compilers and instrumentation options.
|
||||||
|
The following evaluation flow will help you to select the best possible.
|
||||||
|
|
||||||
|
It is highly recommended to have the newest llvm version possible installed,
|
||||||
|
anything below 9 is not recommended.
|
||||||
|
|
||||||
|
```
|
||||||
|
+--------------------------------+
|
||||||
|
| clang/clang++ 11+ is available | --> use afl-clang-lto and afl-clang-lto++
|
||||||
|
+--------------------------------+ see [llvm/README.lto.md](llvm/README.lto.md)
|
||||||
|
|
|
||||||
|
| if not, or if the target fails with with afl-clang-lto/++
|
||||||
|
|
|
||||||
|
v
|
||||||
|
+---------------------------------+
|
||||||
|
| clang/clang++ 3.3+ is available | --> use afl-clang-fast and afl-clang-fast++
|
||||||
|
+---------------------------------+ see [llvm/README.md](llvm/README.md)
|
||||||
|
|
|
||||||
|
| if not, or if the target fails with afl-clang-fast/++
|
||||||
|
|
|
||||||
|
v
|
||||||
|
+--------------------------------+
|
||||||
|
| if you want to instrument only | -> use afl-gcc-fast and afl-gcc-fast++
|
||||||
|
| parts of the target | see [gcc_plugin/README.md](gcc_plugin/README.md) and
|
||||||
|
+--------------------------------+ [gcc_plugin/README.instrument_file.md](gcc_plugin/README.instrument_file.md)
|
||||||
|
|
|
||||||
|
| if not, or if you do not have a gcc with plugin support
|
||||||
|
|
|
||||||
|
v
|
||||||
|
use afl-gcc and afl-g++
|
||||||
|
```
|
||||||
|
|
||||||
|
#### b) Selecting instrumentation options
|
||||||
|
|
||||||
|
The following options are available when you instrument with afl-clang-fast or
|
||||||
|
afl-clang-lto:
|
||||||
|
|
||||||
|
* Splitting integer, string, float and switch compares so afl++ can easier
|
||||||
|
solve these. This is an important option if you do not have a very good
|
||||||
|
good and large input corpus. This technique is called laf-intel or COMPCOV.
|
||||||
|
To use this set the following environment variable before compiling the
|
||||||
|
target: `export AFL_LLVM_LAF_ALL=1`
|
||||||
|
You can read more about this in [llvm/README.laf-intel.md](llvm/README.laf-intel.md)
|
||||||
|
* A different technique is to instrument the target so that any compare values
|
||||||
|
in the target are sent to afl++ which then tries to put this value into the
|
||||||
|
fuzzing data at different locations. This technique is very fast and good -
|
||||||
|
if the target does not transform input data before comparison. Therefore
|
||||||
|
technique is called `input to state` or `redqueen`.
|
||||||
|
If you want to use this technique, then you have to compile the target
|
||||||
|
twice, once specifically with/for this mode.
|
||||||
|
You can read more about this in [llvm_mode/README.cmplog.md](llvm_mode/README.cmplog.md)
|
||||||
|
|
||||||
|
If you use afl-clang-fast, afl-clang-lto or afl-gcc-fast you have the option to
|
||||||
|
selectivly only instrument parts of the target that you are interested in:
|
||||||
|
|
||||||
|
* To instrument only those parts of the target that you are interested in
|
||||||
|
create a file with all the filenames of the source code that should be
|
||||||
|
instrumented.
|
||||||
|
For afl-clang-lto and afl-gcc-fast - or afl-clang-fast if either the clang
|
||||||
|
version is < 7 or the CLASSIC instrumentation is used - just put one
|
||||||
|
filename per line, no directory information necessary, and set
|
||||||
|
`export AFL_LLVM_INSTRUMENT_FILE=yourfile.txt`
|
||||||
|
see [llvm_mode/README.instrument_file.md](llvm_mode/README.instrument_file.md)
|
||||||
|
For afl-clang-fast > 6.0 or if PCGUARD instrumentation is used then use the
|
||||||
|
llvm sancov allow-list feature: [http://clang.llvm.org/docs/SanitizerCoverage.html](http://clang.llvm.org/docs/SanitizerCoverage.html)
|
||||||
|
|
||||||
|
There are many more options and modes available however these are most of the
|
||||||
|
time less effective. See:
|
||||||
|
* [llvm_mode/README.ctx.md](llvm_mode/README.ctx.md)
|
||||||
|
* [llvm_mode/README.ngram.md](llvm_mode/README.ngram.md)
|
||||||
|
* [llvm_mode/README.instrim.md](llvm_mode/README.instrim.md)
|
||||||
|
* [llvm_mode/README.neverzero.md](llvm_mode/README.neverzero.md)
|
||||||
|
|
||||||
|
#### c) Modify the target
|
||||||
|
|
||||||
|
If the target has features that makes fuzzing more difficult, e.g.
|
||||||
|
checksums, HMAC etc. then modify the source code so that this is
|
||||||
|
removed.
|
||||||
|
This can even be done for productional source code be eliminating
|
||||||
|
these checks within this specific defines:
|
||||||
|
|
||||||
|
```
|
||||||
|
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
||||||
|
// say that the checksum or HMAC was fine - or whatever is required
|
||||||
|
// to eliminate the need for the fuzzer to guess the right checksum
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
```
|
||||||
|
|
||||||
|
#### d) Instrument the target
|
||||||
|
|
||||||
|
In this step the target source code is compiled so that it can be fuzzed.
|
||||||
|
|
||||||
|
Basically you have to tell the target build system that the selected afl++
|
||||||
|
compiler is used. Also - if possible - you should always configure the
|
||||||
|
build system that the target is compiled statically and not dynamically.
|
||||||
|
How to do this is described below.
|
||||||
|
|
||||||
|
Then build the target. (Usually with `make`)
|
||||||
|
|
||||||
|
##### configure
|
||||||
|
|
||||||
|
For `configure` build systems this is usually done by:
|
||||||
|
`CC=afl-clang-fast CXX=afl-clang-fast++ ./configure --disable-shared`
|
||||||
|
|
||||||
|
Note that if you using the (better) afl-clang-lto compiler you also have to
|
||||||
|
AR to llvm-ar[-VERSION] and RANLIB to llvm-ranlib[-VERSION] - as it is
|
||||||
|
described in [llvm/README.lto.md](llvm/README.lto.md)
|
||||||
|
|
||||||
|
##### cmake
|
||||||
|
|
||||||
|
For `configure` build systems this is usually done by:
|
||||||
|
`mkdir build; cd build; CC=afl-clang-fast CXX=afl-clang-fast++ cmake ..`
|
||||||
|
|
||||||
|
Note that if you using the (better) afl-clang-lto compiler you also have to
|
||||||
|
AR to llvm-ar[-VERSION] and RANLIB to llvm-ranlib[-VERSION] - as it is
|
||||||
|
described in [llvm/README.lto.md](llvm/README.lto.md)
|
||||||
|
|
||||||
|
##### other build systems or if configure/cmake didn't work
|
||||||
|
|
||||||
|
Sometimes cmake and configure do not pick up the afl compiler, or the ranlib/ar
|
||||||
|
that is needed - because this was just not foreseen by the developer of the
|
||||||
|
target. Or they have non-standard options. Figure out if there is a
|
||||||
|
non-standard way to set this, otherwise set the build normally and edit the
|
||||||
|
generated build environment afterwards by hand to point to the right compiler
|
||||||
|
(and/or ranlib and ar).
|
||||||
|
|
||||||
|
#### d) Better instrumentation
|
||||||
|
|
||||||
|
If you just fuzz a target program as-is you are wasting a great opportunity for
|
||||||
|
much more fuzzing speed.
|
||||||
|
|
||||||
|
This requires the usage of afl-clang-lto or afl-clang-fast
|
||||||
|
|
||||||
|
This is the so-called `persistent mode`, which is much, much faster but
|
||||||
|
requires that you code a source file that is specifically calling the target
|
||||||
|
functions that you want to fuzz, plus a few specific afl++ functions around
|
||||||
|
it. See [llvm_mode/README.persistent_mode.md](llvm_mode/README.persistent_mode.md) for details.
|
||||||
|
|
||||||
|
Basically if you do not fuzz a target in persistent mode then you are just
|
||||||
|
doing it for a hobby and not professionally :-)
|
||||||
|
|
||||||
|
### 2. Preparing the fuzzing
|
||||||
|
|
||||||
|
As you fuzz the target with mutated input, having as diverse inputs for the
|
||||||
|
target as possible improves the efficiency a lot.
|
||||||
|
|
||||||
|
#### a) Collect inputs
|
||||||
|
Try to gather valid inputs for the target from wherever you can. E.g. if it
|
||||||
|
the PNG picture format try to find as many png files as possible, e.g. from
|
||||||
|
reported bugs, test suites, random downloads from the internet, unit test
|
||||||
|
case data - from all kind of PNG software.
|
||||||
|
|
||||||
|
If the input is not known files, you can also modify a target program to write
|
||||||
|
away normal data it receives and processes to a file and use these.
|
||||||
|
|
||||||
|
#### b) Making the input corpus unique
|
||||||
|
|
||||||
|
Use the afl++ tool `afl-cmin` to remove inputs from the corpus that do not
|
||||||
|
use a different paths in the target.
|
||||||
|
Put all files from step a) into one directory, e.g. INPUTS.
|
||||||
|
|
||||||
|
Put all the files from step a)
|
||||||
|
|
||||||
|
If the target program is to be called by fuzzing as `bin/target -d INPUTFILE`
|
||||||
|
the run afl-cmin like this:
|
||||||
|
`afl-cmin -i INPUTS -o INPUTS_UNIQUE -- bin/target -d @@`
|
||||||
|
Note that the INPUTFILE that the target program would read has to be set as `@@`.
|
||||||
|
|
||||||
|
If the target reads from stdin instead, just omit the `@@` as this is the
|
||||||
|
default.
|
||||||
|
|
||||||
|
#### b) Minimizing all corpus files
|
||||||
|
|
||||||
|
The shorter the input files are so that they still traverse the same path
|
||||||
|
within the target, the better the fuzzing will be. This is done with `afl-tmin`
|
||||||
|
however it is a long processes as this has to be done for every file:
|
||||||
|
|
||||||
|
```
|
||||||
|
mkdir input
|
||||||
|
cd INPUTS_UNIQUE
|
||||||
|
for i in *; do
|
||||||
|
afl-tmin -i "$i" -o "../input/$i" -- bin/target -d @@
|
||||||
|
done
|
||||||
|
```
|
||||||
|
|
||||||
|
This can also be parallelized, e.g. with `parallel`
|
||||||
|
|
||||||
|
#### c) done!
|
||||||
|
|
||||||
|
The INPUTS_UNIQUE/ directory from step a) - or even better if you minimized the
|
||||||
|
corpus in step b) then the files in input/ is then the input corpus directory
|
||||||
|
to be used in fuzzing! :-)
|
||||||
|
|
||||||
|
### Fuzzing the target
|
||||||
|
|
||||||
|
In this final step we fuzz the target.
|
||||||
|
There are not that many useful options to run the target - unless you want to
|
||||||
|
use many CPU cores for the fuzzing, which will make the fuzzing much more useful.
|
||||||
|
|
||||||
|
If you just use one CPU for fuzzing, then you are fuzzing just for fun and not
|
||||||
|
seriously :-)
|
||||||
|
|
||||||
|
#### a) running afl-fuzz
|
||||||
|
|
||||||
|
Before to do even a test run of afl-fuzz execute `sudo afl-system-config` (on
|
||||||
|
the host if you execute afl-fuzz in a docker container). This reconfigured the
|
||||||
|
system for optimal speed - which afl-fuzz checks and bails otherwise.
|
||||||
|
Set `export AFL_SKIP_CPUFREQ=1` for afl-fuzz to skip this if you cannot run
|
||||||
|
afl-system-config with root privileges on the host for whatever reason.
|
||||||
|
|
||||||
|
If you have an input corpus from step 2 then specify this directory with the `-i`
|
||||||
|
option. Otherwise create a new directory and create a file with any content
|
||||||
|
in there.
|
||||||
|
|
||||||
|
If you do not want anything special, the defaults are already the usual best,
|
||||||
|
hence all you need (from the example in 2a):
|
||||||
|
`afl-fuzz -i input -o output -- bin/target -d @@`
|
||||||
|
Note that the directory specified with -o will be created if it does not exist.
|
||||||
|
|
||||||
|
If you need to stop and re-start the fuzzing, use the same command line option
|
||||||
|
and switch the input directory with a dash (`-`):
|
||||||
|
`afl-fuzz -i - -o output -- bin/target -d @@`
|
||||||
|
|
||||||
|
Adding a dictionary helpful. See the [dictionaries/](dictionaries/) if
|
||||||
|
something is already included for your data format, and tell afl-fuzz to load
|
||||||
|
that dictionary by adding `-x dicationaries/FORMAT.dict`. With afl-clang-lto
|
||||||
|
you have an autodictionary generation for which you need to do nothing except
|
||||||
|
to use afl-clang-lto as the compiler. You also have the option to generate
|
||||||
|
a dictionary yourself, see [libtokencap/README.md](libtokencap/README.md)
|
||||||
|
|
||||||
|
afl-fuzz never stops fuzzing. To terminate afl++ simply press Control-C.
|
||||||
|
|
||||||
|
When you start afl-fuzz you will see a user interface that shows what the status
|
||||||
|
is:
|
||||||
|

|
||||||
|
All the entries are explained in [docs/status_screen.md](docs/status_screen.md)
|
||||||
|
|
||||||
|
#### b) Using multiple cores
|
||||||
|
|
||||||
|
If you want to seriously fuzz then use as many cores as possible to fuzz your
|
||||||
|
target.
|
||||||
|
|
||||||
|
On the same machine - due to the nature how afl++ works - there is a maximum
|
||||||
|
number of CPU cores that are useful, more and the overall performance degrades
|
||||||
|
instead. This value depends on the target and the limit is between 24 and 64
|
||||||
|
cores per machine.
|
||||||
|
|
||||||
|
There should be one main fuzzer (`-M main` option) and as many secondary
|
||||||
|
fuzzers (eg `-S variant1`) as you cores that you use.
|
||||||
|
Every -M/-S entry needs a unique name (that can be whatever), however the same
|
||||||
|
-o output directory location has to be used for all.
|
||||||
|
|
||||||
|
For every secondary there should be a variation, e.g.:
|
||||||
|
* one should fuzz the target that was compiled differently: with sanitizers
|
||||||
|
activated (`export AFL_USE_ASAN=1 ; export AFL_USE_UBSAN=1 ;
|
||||||
|
export AFL_USE_CFISAN=1 ; `
|
||||||
|
* one should fuzz the target with CMPLOG/redqueen (see above)
|
||||||
|
* At 1-2 should fuzz a target compiled with laf-intel/COMPCOV (see above).
|
||||||
|
|
||||||
|
All other secondaries should be:
|
||||||
|
* 1/2 with MOpt option enabled: `-L 0`
|
||||||
|
* run with a different power schedule, available are:
|
||||||
|
`explore (default), fast, coe, lin, quad, exploit, mmopt, rare, seek`
|
||||||
|
which you can set with e.g. `-p seek`
|
||||||
|
|
||||||
|
You can also use different fuzzers.
|
||||||
|
If you are afl-spinoffs or afl conforming, then just use the same -o directory
|
||||||
|
and give it a unique `-S` name.
|
||||||
|
Examples are e.g.:
|
||||||
|
* [Angora](https://github.com/AngoraFuzzer/Angora)
|
||||||
|
* [Untracer](https://github.com/FoRTE-Research/UnTracer-AFL)
|
||||||
|
* [AFLsmart](https://github.com/aflsmart/aflsmart)
|
||||||
|
* [FairFuzz](https://github.com/carolemieux/afl-rb)
|
||||||
|
* [Neuzz](https://github.com/Dongdongshe/neuzz)
|
||||||
|
A long list can be found at [https://github.com/Microsvuln/Awesome-AFL](https://github.com/Microsvuln/Awesome-AFL)
|
||||||
|
|
||||||
|
However you can also sync afl++ with honggfuzz, libfuzzer, entropic, etc.
|
||||||
|
Just show the main fuzzer (-M) with the `-F` option where the queue
|
||||||
|
directory of these other fuzzers are, e.g. `-F /src/target/honggfuzz`
|
||||||
|
|
||||||
|
#### c) The status of the fuzz campaign
|
||||||
|
|
||||||
|
afl++ comes with the `afl-whatsup` script to show the status of fuzzing
|
||||||
|
campaign.
|
||||||
|
|
||||||
|
Just supply the directory that afl-fuzz is given with the -o option and
|
||||||
|
you will see a detailed status of every fuzzer in that campaign plus
|
||||||
|
a summary.
|
||||||
|
|
||||||
|
To have only the summary use the `-s` switch e.g.: `afl-whatsup -s output/`
|
||||||
|
|
||||||
|
#### d) Checking the coverage of the fuzzing
|
||||||
|
|
||||||
|
The `paths found` value is a bad indicator how good the coverage is.
|
||||||
|
It is better to check out the exact lines of code that have been reached -
|
||||||
|
and which have not been found so far.
|
||||||
|
|
||||||
|
An "easy" helper script for this is [afl-cov](https://github.com/vanhauser-thc/afl-cov),
|
||||||
|
just follow the README of that seperate project.
|
||||||
|
|
||||||
|
If you see that an important area or a feature has not been covered so far then
|
||||||
|
try to find an input that is able to reach that and start a new secondary in
|
||||||
|
that fuzzing campaign with that seed as input, let it run for a few minutes,
|
||||||
|
then terminate it. The main node will pick it up and make it available to the
|
||||||
|
other secondary nodes over time. Set `export AFL_NO_AFFINITY=1` if you have no
|
||||||
|
free core.
|
||||||
|
|
||||||
|
#### e) How long to fuzz a target?
|
||||||
|
|
||||||
|
This is a difficult question.
|
||||||
|
Basically if no new path is found for a long time (e.g. for a day or a week)
|
||||||
|
then you can expect that your fuzzing won't be fruitful anymore.
|
||||||
|
However often this just means that you should switch out secondaries for
|
||||||
|
others, e.g. custom mutator modules, sync to very different fuzzers, etc.
|
||||||
|
|
||||||
|
### The End
|
||||||
|
|
||||||
|
This is basically all you need to know to professionally run fuzzing campaigns.
|
||||||
|
If you want to know more, the rest of this README and the tons of texts in
|
||||||
|
[docs/](docs/) will have you covered.
|
||||||
|
|
||||||
|
Note that there are also a lot of tools out there that help fuzzing with afl++
|
||||||
|
(some might be deprecated or unsupported):
|
||||||
|
|
||||||
|
Minimization of test cases:
|
||||||
|
* [afl-pytmin](https://github.com/ilsani/afl-pytmin) - a wrapper for afl-tmin that tries to speed up the process of the minimization of test case by using many CPU cores.
|
||||||
|
* [afl-ddmin-mod](https://github.com/MarkusTeufelberger/afl-ddmin-mod) - a variation of afl-tmin based on the ddmin algorithm.
|
||||||
|
* [halfempty](https://github.com/googleprojectzero/halfempty) - is a fast utility for minimizing test cases by Tavis Ormandy based on parallelization.
|
||||||
|
|
||||||
|
Distributed execution:
|
||||||
|
* [disfuzz-afl](https://github.com/MartijnB/disfuzz-afl) - distributed fuzzing for AFL.
|
||||||
|
* [AFLDFF](https://github.com/quantumvm/AFLDFF) - AFL distributed fuzzing framework.
|
||||||
|
* [afl-launch](https://github.com/bnagy/afl-launch) - a tool for the execution of many AFL instances.
|
||||||
|
* [afl-mothership](https://github.com/afl-mothership/afl-mothership) - management and execution of many synchronized AFL fuzzers on AWS cloud.
|
||||||
|
* [afl-in-the-cloud](https://github.com/abhisek/afl-in-the-cloud) - another script for running AFL in AWS.
|
||||||
|
|
||||||
|
Deployment, management, monitoring, reporting
|
||||||
|
* [afl-other-arch](https://github.com/shellphish/afl-other-arch) - is a set of patches and scripts for easily adding support for various non-x86 architectures for AFL.
|
||||||
|
* [afl-trivia](https://github.com/bnagy/afl-trivia) - a few small scripts to simplify the management of AFL.
|
||||||
|
* [afl-monitor](https://github.com/reflare/afl-monitor) - a script for monitoring AFL.
|
||||||
|
* [afl-manager](https://github.com/zx1340/afl-manager) - a web server on Python for managing multi-afl.
|
||||||
|
* [afl-remote](https://github.com/block8437/afl-remote) - a web server for the remote management of AFL instances.
|
||||||
|
|
||||||
|
Crash processing
|
||||||
|
* [afl-utils](https://gitlab.com/rc0r/afl-utils) - a set of utilities for automatic processing/analysis of crashes and reducing the number of test cases.
|
||||||
|
* [afl-crash-analyzer](https://github.com/floyd-fuh/afl-crash-analyzer) - another crash analyzer for AFL.
|
||||||
|
* [fuzzer-utils](https://github.com/ThePatrickStar/fuzzer-utils) - a set of scripts for the analysis of results.
|
||||||
|
* [atriage](https://github.com/Ayrx/atriage) - a simple triage tool.
|
||||||
|
* [afl-kit](https://github.com/kcwu/afl-kit) - afl-cmin on Python.
|
||||||
|
* [AFLize](https://github.com/d33tah/aflize) - a tool that automatically generates builds of debian packages suitable for AFL.
|
||||||
|
* [afl-fid](https://github.com/FoRTE-Research/afl-fid) - a set of tools for working with input data.
|
||||||
|
|
||||||
|
## Fuzzing binary-only targets
|
||||||
|
|
||||||
|
When source code is *NOT* available, afl++ offers various support for fast,
|
||||||
|
on-the-fly instrumentation of black-box binaries.
|
||||||
|
|
||||||
|
### QEMU
|
||||||
|
|
||||||
|
For linux programs and it's libraries this is accomplished with a version of
|
||||||
|
QEMU running in the lesser-known "user space emulation" mode.
|
||||||
|
QEMU is a project separate from AFL, but you can conveniently build the
|
||||||
|
feature by doing:
|
||||||
|
```shell
|
||||||
|
cd qemu_mode
|
||||||
|
./build_qemu_support.sh
|
||||||
|
```
|
||||||
|
For additional instructions and caveats, see [qemu_mode/README.md](qemu_mode/README.md).
|
||||||
|
If possible you should use the persistent mode, see [qemu_mode/README.persistent.md](qemu_mode/README.persistent.md).
|
||||||
|
The mode is approximately 2-5x slower than compile-time instrumentation, and is
|
||||||
|
less conducive to parallelization.
|
||||||
|
|
||||||
|
If [afl-dyninst](https://github.com/vanhauser-thc/afl-dyninst) works for
|
||||||
|
your binary, then you can use afl-fuzz normally and it will have twice
|
||||||
|
the speed compared to qemu_mode (but slower than persistent mode).
|
||||||
|
|
||||||
|
### Unicorn
|
||||||
|
|
||||||
|
For non-Linux binaries you can use afl++'s unicorn mode which can emulate
|
||||||
|
anything you want - for the price of speed and the user writing scripts.
|
||||||
|
See [unicorn_mode](unicorn_mode/README.md).
|
||||||
|
|
||||||
|
It can be easily build by:
|
||||||
|
```shell
|
||||||
|
cd unicorn_mode
|
||||||
|
./build_unicorn_support.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
### Shared libraries
|
||||||
|
|
||||||
|
If the goal is to fuzz a dynamic library then there are two options available.
|
||||||
|
For both you need to write a small hardness that loads and calls the library.
|
||||||
|
Faster is the frida solution: [examples/afl_frida/README.md](examples/afl_frida/README.md)
|
||||||
|
|
||||||
|
Another, less precise and slower option is using ptrace with debugger interrupt
|
||||||
|
instrumentation: [examples/afl_untracer/README.md](examples/afl_untracer/README.md)
|
||||||
|
|
||||||
|
### More
|
||||||
|
|
||||||
|
A more comprehensive description of these and other options can be found in
|
||||||
|
[docs/binaryonly_fuzzing.md](docs/binaryonly_fuzzing.md)
|
||||||
|
|
||||||
## Challenges of guided fuzzing
|
## Challenges of guided fuzzing
|
||||||
|
|
||||||
Fuzzing is one of the most powerful and proven strategies for identifying
|
Fuzzing is one of the most powerful and proven strategies for identifying
|
||||||
@ -262,7 +710,6 @@ closed-source tools.
|
|||||||
The fuzzer is thoroughly tested to deliver out-of-the-box performance far
|
The fuzzer is thoroughly tested to deliver out-of-the-box performance far
|
||||||
superior to blind fuzzing or coverage-only tools.
|
superior to blind fuzzing or coverage-only tools.
|
||||||
|
|
||||||
|
|
||||||
## Instrumenting programs for use with AFL
|
## Instrumenting programs for use with AFL
|
||||||
|
|
||||||
PLEASE NOTE: llvm_mode compilation with afl-clang-fast/afl-clang-fast++
|
PLEASE NOTE: llvm_mode compilation with afl-clang-fast/afl-clang-fast++
|
||||||
@ -318,52 +765,6 @@ simple memory bugs. Libdislocator, a helper library included with AFL (see
|
|||||||
PS. ASAN users are advised to review [docs/notes_for_asan.md](docs/notes_for_asan.md)
|
PS. ASAN users are advised to review [docs/notes_for_asan.md](docs/notes_for_asan.md)
|
||||||
file for important caveats.
|
file for important caveats.
|
||||||
|
|
||||||
|
|
||||||
## Instrumenting binary-only apps
|
|
||||||
|
|
||||||
When source code is *NOT* available, the fuzzer offers experimental support for
|
|
||||||
fast, on-the-fly instrumentation of black-box binaries. This is accomplished
|
|
||||||
with a version of QEMU running in the lesser-known "user space emulation" mode.
|
|
||||||
|
|
||||||
QEMU is a project separate from AFL, but you can conveniently build the
|
|
||||||
feature by doing:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
cd qemu_mode
|
|
||||||
./build_qemu_support.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
For additional instructions and caveats, see [qemu_mode/README.md](qemu_mode/README.md).
|
|
||||||
|
|
||||||
If possible you should use the persistent mode, see [qemu_mode/README.persistent.md](qemu_mode/README.persistent.md).
|
|
||||||
|
|
||||||
The mode is approximately 2-5x slower than compile-time instrumentation, is
|
|
||||||
less conducive to parallelization, and may have some other quirks.
|
|
||||||
|
|
||||||
If [afl-dyninst](https://github.com/vanhauser-thc/afl-dyninst) works for
|
|
||||||
your binary, then you can use afl-fuzz normally and it will have twice
|
|
||||||
the speed compared to qemu_mode.
|
|
||||||
|
|
||||||
A more comprehensive description of these and other options can be found in
|
|
||||||
[docs/binaryonly_fuzzing.md](docs/binaryonly_fuzzing.md)
|
|
||||||
|
|
||||||
## Good examples and writeups
|
|
||||||
|
|
||||||
Here are some good writeups to show how to effectively use AFL++:
|
|
||||||
|
|
||||||
* [https://aflplus.plus/docs/tutorials/libxml2_tutorial/](https://aflplus.plus/docs/tutorials/libxml2_tutorial/)
|
|
||||||
* [https://bananamafia.dev/post/gb-fuzz/](https://bananamafia.dev/post/gb-fuzz/)
|
|
||||||
* [https://securitylab.github.com/research/fuzzing-challenges-solutions-1](https://securitylab.github.com/research/fuzzing-challenges-solutions-1)
|
|
||||||
* [https://securitylab.github.com/research/fuzzing-sockets-FTP](https://securitylab.github.com/research/fuzzing-sockets-FTP)
|
|
||||||
|
|
||||||
If you are interested in fuzzing structured data (where you define what the
|
|
||||||
structure is), these links have you covered:
|
|
||||||
* Superion for afl++: [https://github.com/adrian-rt/superion-mutator](https://github.com/adrian-rt/superion-mutator)
|
|
||||||
* libprotobuf raw: [https://github.com/bruce30262/libprotobuf-mutator_fuzzing_learning/tree/master/4_libprotobuf_aflpp_custom_mutator](https://github.com/bruce30262/libprotobuf-mutator_fuzzing_learning/tree/master/4_libprotobuf_aflpp_custom_mutator)
|
|
||||||
* libprotobuf for old afl++ API: [https://github.com/thebabush/afl-libprotobuf-mutator](https://github.com/thebabush/afl-libprotobuf-mutator)
|
|
||||||
|
|
||||||
If you find other good ones, please send them to us :-)
|
|
||||||
|
|
||||||
## Power schedules
|
## Power schedules
|
||||||
|
|
||||||
The power schedules were copied from Marcel Böhme's AFLfast implementation and
|
The power schedules were copied from Marcel Böhme's AFLfast implementation and
|
||||||
|
1065
README_new.md
1065
README_new.md
File diff suppressed because it is too large
Load Diff
BIN
docs/screenshot.png
Normal file
BIN
docs/screenshot.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 114 KiB |
@ -1234,6 +1234,7 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
(void)nice(-20);
|
||||||
// real start time, we reset, so this works correctly with -V
|
// real start time, we reset, so this works correctly with -V
|
||||||
afl->start_time = get_cur_time();
|
afl->start_time = get_cur_time();
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user