improve readme

This commit is contained in:
van Hauser 2020-08-11 22:58:57 +02:00
parent 052d74b16c
commit ee548df05f

View File

@ -64,21 +64,20 @@
Among others, the following features and patches have been integrated: 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 * 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 * Persistent mode, deferred forkserver and in-memory fuzzing for qemu_mode
* Unicorn mode which allows fuzzing of binaries from completely different platforms (integration provided by domenukk) * 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) * 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 * 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) * 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) * 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) * 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) * InsTrim, a CFG llvm_mode instrumentation implementation: [https://github.com/csienslab/instrim](https://github.com/csienslab/instrim)
* C. Holler's afl-fuzz Python mutator module: [https://github.com/choller/afl](https://github.com/choller/afl) * C. Holler's afl-fuzz Python mutator module: [https://github.com/choller/afl](https://github.com/choller/afl)
* Custom mutator by a library (instead of Python) by kyakdan * 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) * LAF-Intel/CompCov support for llvm_mode, qemu_mode and unicorn_mode (with enhanced capabilities)
* Radamsa and hongfuzz mutators (as custom mutators). * Radamsa and hongfuzz mutators (as custom mutators).
* QBDI mode to fuzz android native libraries via Quarkslab's [QBDI](https://github.com/QBDI/QBDI) framework * QBDI mode to fuzz android native libraries via Quarkslab's [QBDI](https://github.com/QBDI/QBDI) framework
* Frida and ptrace mode to fuzz binary-only libraries, etc.
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 out there :-) So all in all this is the best-of afl that is out there :-)
@ -273,15 +272,17 @@ afl-clang-lto:
To use this set the following environment variable before compiling the To use this set the following environment variable before compiling the
target: `export AFL_LLVM_LAF_ALL=1` target: `export AFL_LLVM_LAF_ALL=1`
You can read more about this in [llvm/README.laf-intel.md](llvm/README.laf-intel.md) You can read more about this in [llvm/README.laf-intel.md](llvm/README.laf-intel.md)
* A different technique (and usually a bit better than laf-intel) is to * A different technique (and usually a better than laf-intel) is to
instrument the target so that any compare values in the target are sent 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 afl++ which then tries to put these values into the fuzzing data at different
locations. This technique is very fast and good - if the target does not locations. This technique is very fast and good - if the target does not
transform input data before comparison. Therefore this technique is called transform input data before comparison. Therefore this technique is called
`input to state` or `redqueen`. `input to state` or `redqueen`.
If you want to use this technique, then you have to compile the target If you want to use this technique, then you have to compile the target
twice, once specifically with/for this mode, and pass this binary to afl-fuzz twice, once specifically with/for this mode, and pass this binary to afl-fuzz
via the `-c` parameter. via the `-c` parameter.
Not that you can compile also just a cmplog binary and use that for both
however there will a performance penality.
You can read more about this in [llvm_mode/README.cmplog.md](llvm_mode/README.cmplog.md) 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 If you use afl-clang-fast, afl-clang-lto or afl-gcc-fast you have the option to
@ -309,12 +310,15 @@ time less effective. See:
* [llvm_mode/README.ctx.md](llvm_mode/README.ctx.md) * [llvm_mode/README.ctx.md](llvm_mode/README.ctx.md)
* [llvm_mode/README.ngram.md](llvm_mode/README.ngram.md) * [llvm_mode/README.ngram.md](llvm_mode/README.ngram.md)
* [llvm_mode/README.instrim.md](llvm_mode/README.instrim.md) * [llvm_mode/README.instrim.md](llvm_mode/README.instrim.md)
afl++ employs never zero counting in its bitmap. You can read more about this
here:
* [llvm_mode/README.neverzero.md](llvm_mode/README.neverzero.md) * [llvm_mode/README.neverzero.md](llvm_mode/README.neverzero.md)
#### c) Modify the target #### c) Modify the target
If the target has features that makes fuzzing more difficult, e.g. If the target has features that makes fuzzing more difficult, e.g.
checksums, HMAC etc. then modify the source code so that this is checksums, HMAC, etc. then modify the source code so that this is
removed. removed.
This can even be done for productional source code be eliminating This can even be done for productional source code be eliminating
these checks within this specific defines: these checks within this specific defines:
@ -389,6 +393,7 @@ As you fuzz the target with mutated input, having as diverse inputs for the
target as possible improves the efficiency a lot. target as possible improves the efficiency a lot.
#### a) Collect inputs #### a) Collect inputs
Try to gather valid inputs for the target from wherever you can. E.g. if it is Try to gather valid inputs for the target from wherever you can. E.g. if it is
the PNG picture format try to find as many png files as possible, e.g. from 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 reported bugs, test suites, random downloads from the internet, unit test
@ -437,23 +442,24 @@ to be used in fuzzing! :-)
### 3. Fuzzing the target ### 3. Fuzzing the target
In this final step we fuzz 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 There are not that many important options to run the target - unless you want
use many CPU cores/threads for the fuzzing, which will make the fuzzing much to use many CPU cores/threads for the fuzzing, which will make the fuzzing much
more useful. more useful.
If you just use one CPU for fuzzing, then you are fuzzing just for fun and not If you just use one CPU for fuzzing, then you are fuzzing just for fun and not
seriously :-) seriously :-)
Pro tip: load the [afl++ snapshot module](https://github.com/AFLplusplus/AFL-Snapshot-LKM) Pro tip: load the [afl++ snapshot module](https://github.com/AFLplusplus/AFL-Snapshot-LKM)
before the start of afl-fuzz as this improves performance by a x2 speed increase! before the start of afl-fuzz as this improves performance by a x2 speed increase
(less if you use a persistent mode harness)!
#### a) Running afl-fuzz #### a) Running afl-fuzz
Before to do even a test run of afl-fuzz execute `sudo afl-system-config` (on 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 reconfigures the the host if you execute afl-fuzz in a docker container). This reconfigures the
system for optimal speed - which afl-fuzz checks and bails otherwise. system for optimal speed - which afl-fuzz checks and bails otherwise.
Set `export AFL_SKIP_CPUFREQ=1` for afl-fuzz to skip this check if you cannot run Set `export AFL_SKIP_CPUFREQ=1` for afl-fuzz to skip this check if you cannot
afl-system-config with root privileges on the host for whatever reason. 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` 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 option. Otherwise create a new directory and create a file with any content
@ -475,7 +481,7 @@ of memory. By default this is 50MB for a process. If this is too little for
the target (which you can usually see by afl-fuzz bailing with the message the target (which you can usually see by afl-fuzz bailing with the message
that it could not connect to the forkserver), then you can increase this that it could not connect to the forkserver), then you can increase this
with the `-m` option, the value is in MB. To disable any memory limits with the `-m` option, the value is in MB. To disable any memory limits
(beware!) set `-m 0` - which is usually required for ASAN compiled targets. (beware!) set `-m none` - which is usually required for ASAN compiled targets.
Adding a dictionary is helpful. See the [dictionaries/](dictionaries/) if Adding a dictionary is helpful. See the [dictionaries/](dictionaries/) if
something is already included for your data format, and tell afl-fuzz to load something is already included for your data format, and tell afl-fuzz to load
@ -536,7 +542,7 @@ Examples are:
A long list can be found at [https://github.com/Microsvuln/Awesome-AFL](https://github.com/Microsvuln/Awesome-AFL) 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. However you can also sync afl++ with honggfuzz, libfuzzer with -entropic, etc.
Just show the main fuzzer (-M) with the `-F` option where the queue Just show the main fuzzer (-M) with the `-F` option where the queue
directory of a different fuzzer is, e.g. `-F /src/target/honggfuzz`. directory of a different fuzzer is, e.g. `-F /src/target/honggfuzz`.
@ -554,7 +560,14 @@ To have only the summary use the `-s` switch e.g.: `afl-whatsup -s output/`
#### d) Checking the coverage of the fuzzing #### d) Checking the coverage of the fuzzing
The `paths found` value is a bad indicator how good the coverage is. 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 -
A better indicator - if you use default llvm instrumentation with at least
version 9 - to use `afl-showmap` on the target with all inputs of the
queue/ directory one after another and collecting the found edge IDs (`-o N.out`),
removing the counters of the edge IDs, making them unique - and there you have
the total number of found instrumented edges.
It is even better to check out the exact lines of code that have been reached -
and which have not been found so far. and which have not been found so far.
An "easy" helper script for this is [https://github.com/vanhauser-thc/afl-cov](https://github.com/vanhauser-thc/afl-cov), An "easy" helper script for this is [https://github.com/vanhauser-thc/afl-cov](https://github.com/vanhauser-thc/afl-cov),
@ -575,6 +588,10 @@ then you can expect that your fuzzing won't be fruitful anymore.
However often this just means that you should switch out secondaries for However often this just means that you should switch out secondaries for
others, e.g. custom mutator modules, sync to very different fuzzers, etc. others, e.g. custom mutator modules, sync to very different fuzzers, etc.
Keep the queue/ directory (for future fuzzings of the same or similar targets)
and use them to seed other good fuzzers like libfuzzer with the -entropic
switch or honggfuzz.
#### f) Improve the speed! #### f) Improve the speed!
* Use [persistent mode](llvm_mode/README.persistent_mode.md) (x2-x20 speed increase) * Use [persistent mode](llvm_mode/README.persistent_mode.md) (x2-x20 speed increase)