diff options
Diffstat (limited to 'README.md')
-rw-r--r-- | README.md | 595 |
1 files changed, 498 insertions, 97 deletions
diff --git a/README.md b/README.md index 9c802285..97fa99b7 100644 --- a/README.md +++ b/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"> @@ -8,61 +8,36 @@ 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) 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), - it is unlikely to receive any notable enhancements: [https://twitter.com/Dor3s/status/1154737061787660288](https://twitter.com/Dor3s/status/1154737061787660288) - -## The enhancements compared to the original stock afl - - Many improvements were made over the official afl release - which did not - get any feature improvements since November 2017. - - Among other changes afl++ has a more performant llvm_mode, supports - 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: - - * AFLfast's power schedules by Marcel Böhme: [https://github.com/mboehme/aflfast](https://github.com/mboehme/aflfast) - - * The new excellent MOpt mutator: [https://github.com/puppet-meteor/MOpt-AFL](https://github.com/puppet-meteor/MOpt-AFL) - - * InsTrim, a very 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) + * 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>. - * 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 + Originally developed by Michal "lcamtuf" Zalewski. - * Radamsa mutator (as a custom mutator). + afl++ is a superiour fork to Google's afl - more speed, more and better + mutations, more and better instrumentation, custom module support, etc. - * QBDI mode to fuzz android native libraries via QBDI framework +## Contents - * 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) + 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) - * LLVM mode Ngram coverage by Adrian Herrera [https://github.com/adrianherrera/afl-ngram-pass](https://github.com/adrianherrera/afl-ngram-pass) +## Important features of afl++ - A more thorough list is available in the [PATCHES](docs/PATCHES.md) file. + 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 + Android support and much, much, much more. | Feature/Instrumentation | afl-gcc | llvm_mode | gcc_plugin | qemu_mode | unicorn_mode | | ----------------------- |:-------:|:---------:|:----------:|:----------------:|:------------:| @@ -75,6 +50,7 @@ | InsTrim | | x | | | | | Ngram prev_loc coverage | | x(6) | | | | | Context coverage | | x | | | | + | Auto dictionary | | x(7) | | | | | Snapshot LKM support | | x | | (x)(5) | | neverZero: @@ -85,11 +61,45 @@ (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 (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 :-) @@ -115,7 +125,7 @@ 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/)! :-) @@ -140,7 +150,7 @@ hence afl-clang-lto is available!) or just pull directly from the docker hub: docker pull 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. 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 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! 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 +## 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 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 superior to blind fuzzing or coverage-only tools. - ## Instrumenting programs for use with AFL 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) 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 The power schedules were copied from Marcel Böhme's AFLfast implementation and |