diff options
-rw-r--r-- | Makefile | 20 | ||||
-rw-r--r-- | README.md | 4 | ||||
-rw-r--r-- | docs/ChangeLog | 38 | ||||
-rw-r--r--[l---------] | docs/README.md | 683 | ||||
-rw-r--r--[l---------] | docs/README.radamsa.md | 10 | ||||
-rw-r--r-- | docs/env_variables.md | 4 | ||||
-rw-r--r-- | docs/life_pro_tips.txt | 4 | ||||
-rw-r--r-- | docs/notes_for_asan.md | 4 | ||||
-rw-r--r-- | docs/parallel_fuzzing.md | 2 | ||||
-rw-r--r-- | examples/README.md | 2 | ||||
-rw-r--r-- | gcc_plugin/README.md | 2 | ||||
-rw-r--r-- | llvm_mode/README.md | 2 | ||||
-rw-r--r-- | qemu_mode/README.md | 2 | ||||
-rw-r--r-- | src/afl-as.c | 2 | ||||
-rwxr-xr-x | test/test.sh | 4 |
15 files changed, 736 insertions, 47 deletions
diff --git a/Makefile b/Makefile index dd6c19aa..aae2a9c9 100644 --- a/Makefile +++ b/Makefile @@ -277,8 +277,8 @@ code-format: ./.custom-format.py -i gcc_plugin/*.c #./.custom-format.py -i gcc_plugin/*.h ./.custom-format.py -i gcc_plugin/*.cc - ./.custom-format.py -i experimental/*/*.c - ./.custom-format.py -i experimental/*/*.h + ./.custom-format.py -i examples/*/*.c + ./.custom-format.py -i examples/*/*.h ./.custom-format.py -i qemu_mode/patches/*.h ./.custom-format.py -i qemu_mode/libcompcov/*.c ./.custom-format.py -i qemu_mode/libcompcov/*.cc @@ -323,8 +323,8 @@ clean: -$(MAKE) -C gcc_plugin clean $(MAKE) -C libdislocator clean $(MAKE) -C libtokencap clean - $(MAKE) -C experimental/socket_fuzzing clean - $(MAKE) -C experimental/argv_fuzzing clean + $(MAKE) -C examples/socket_fuzzing clean + $(MAKE) -C examples/argv_fuzzing clean $(MAKE) -C qemu_mode/unsigaction clean $(MAKE) -C qemu_mode/libcompcov clean $(MAKE) -C src/third_party/libradamsa/ clean @@ -335,16 +335,16 @@ distrib: all radamsa -$(MAKE) -C gcc_plugin $(MAKE) -C libdislocator $(MAKE) -C libtokencap - $(MAKE) -C experimental/socket_fuzzing - $(MAKE) -C experimental/argv_fuzzing + $(MAKE) -C examples/socket_fuzzing + $(MAKE) -C examples/argv_fuzzing cd qemu_mode && sh ./build_qemu_support.sh cd unicorn_mode && sh ./build_unicorn_support.sh binary-only: all radamsa $(MAKE) -C libdislocator $(MAKE) -C libtokencap - $(MAKE) -C experimental/socket_fuzzing - $(MAKE) -C experimental/argv_fuzzing + $(MAKE) -C examples/socket_fuzzing + $(MAKE) -C examples/argv_fuzzing cd qemu_mode && sh ./build_qemu_support.sh cd unicorn_mode && sh ./build_unicorn_support.sh @@ -395,8 +395,8 @@ endif if [ -f libcompcov.so ]; then set -e; install -m 755 libcompcov.so $${DESTDIR}$(HELPER_PATH); fi if [ -f libradamsa.so ]; then set -e; install -m 755 libradamsa.so $${DESTDIR}$(HELPER_PATH); fi if [ -f afl-fuzz-document ]; then set -e; install -m 755 afl-fuzz-document $${DESTDIR}$(BIN_PATH); fi - $(MAKE) -C experimental/socket_fuzzing install - $(MAKE) -C experimental/argv_fuzzing install + $(MAKE) -C examples/socket_fuzzing install + $(MAKE) -C examples/argv_fuzzing install set -e; ln -sf afl-gcc $${DESTDIR}$(BIN_PATH)/afl-g++ set -e; if [ -f afl-clang-fast ] ; then ln -sf afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang ; ln -sf afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang++ ; else ln -sf afl-gcc $${DESTDIR}$(BIN_PATH)/afl-clang ; ln -sf afl-gcc $${DESTDIR}$(BIN_PATH)/afl-clang++; fi diff --git a/README.md b/README.md index 00ae599c..e926c956 100644 --- a/README.md +++ b/README.md @@ -593,9 +593,9 @@ Here are some of the most important caveats for AFL: wholly wrap the actual data format to be tested. To work around this, you can comment out the relevant checks (see - experimental/libpng_no_checksum/ for inspiration); if this is not possible, + examples/libpng_no_checksum/ for inspiration); if this is not possible, you can also write a postprocessor, as explained in - experimental/post_library/ (with AFL_POST_LIBRARY) + examples/post_library/ (with AFL_POST_LIBRARY) - There are some unfortunate trade-offs with ASAN and 64-bit binaries. This isn't due to any specific fault of afl-fuzz; see [docs/notes_for_asan.md](docs/notes_for_asan.md) diff --git a/docs/ChangeLog b/docs/ChangeLog index a559f6f2..b047b95f 100644 --- a/docs/ChangeLog +++ b/docs/ChangeLog @@ -43,9 +43,9 @@ Version ++2.60c (release): - fixed a critical bug in afl-tmin that was introduced during ++2.53d - added test cases for afl-cmin and afl-tmin to test/test.sh - - added ./experimental/argv_fuzzing ld_preload library by Kjell Braden + - added ./examples/argv_fuzzing ld_preload library by Kjell Braden - added preeny's desock_dup ld_preload library as - ./experimental/socket_fuzzing for network fuzzing + ./examples/socket_fuzzing for network fuzzing - added AFL_AS_FORCE_INSTRUMENT environment variable for afl-as - this is for the retrorewrite project - we now set QEMU_SET_ENV from AFL_PRELOAD when qemu_mode is used @@ -512,7 +512,7 @@ Version 2.27b: - Moved libdislocator to its own dir, added README. - - The demo in experimental/instrumented_cmp is no more. + - The demo in examples/instrumented_cmp is no more. -------------- Version 2.26b: @@ -666,7 +666,7 @@ Version 2.11b: - Made an improvement to afl-gotcpu when -Z not used. - - Fixed a typo in post_library_png.so.c in experimental/. Spotted by Kostya + - Fixed a typo in post_library_png.so.c in examples/. Spotted by Kostya Serebryany. -------------- @@ -1066,7 +1066,7 @@ Version 1.75b: Version 1.74b: -------------- - - Added an example argv[] fuzzing wrapper in experimental/argv_fuzzing. + - Added an example argv[] fuzzing wrapper in examples/argv_fuzzing. Reworked the bash example to be faster, too. - Clarified llvm_mode prerequisites for FreeBSD. @@ -1231,12 +1231,12 @@ Version 1.61b: Version 1.60b: -------------- - - Allowed experimental/llvm_instrumentation/ to graduate to llvm_mode/. + - Allowed examples/llvm_instrumentation/ to graduate to llvm_mode/. - - Removed experimental/arm_support/, since it's completely broken and likely + - Removed examples/arm_support/, since it's completely broken and likely unnecessary with LLVM support in place. - - Added ASAN cgroups script to experimental/asan_cgroups/, updated existing + - Added ASAN cgroups script to examples/asan_cgroups/, updated existing docs. Courtesy Sam Hakim and David A. Wheeler. - Refactored afl-tmin to reduce the number of execs in common use cases. @@ -1256,7 +1256,7 @@ Version 1.59b: -------------- - Imported Laszlo Szekeres' experimental LLVM instrumentation into - experimental/llvm_instrumentation. I'll work on including it in the + examples/llvm_instrumentation. I'll work on including it in the "mainstream" version soon. - Fixed another typo, thanks to Jakub Wilk. @@ -1305,7 +1305,7 @@ Version 1.54b: - Added another postprocessor example for PNG. - - Made a cosmetic fix to realloc() handling in experimental/post_library/, + - Made a cosmetic fix to realloc() handling in examples/post_library/, suggested by Jakub Wilk. - Improved -ldl handling. Suggested by Jakub Wilk. @@ -1323,7 +1323,7 @@ Version 1.52b: - Added support for file format postprocessors. Requested by Ben Nagy. This feature is intentionally buried, since it's fairly easy to misuse and - useful only in some scenarios. See experimental/post_library/. + useful only in some scenarios. See examples/post_library/. -------------- Version 1.51b: @@ -1958,7 +1958,7 @@ Version 0.98b: - Fixed another cosmetic snafu with stage exec counts for -x. - Switched afl-plot to /bin/sh, since it seems bashism-free. Also tried - to remove any obvious bashisms from other experimental/ scripts, + to remove any obvious bashisms from other examples/ scripts, most notably including minimize_corpus.sh and triage_crashes.sh. Requested by Jonathan Gray. @@ -2126,7 +2126,7 @@ Version 0.84b: Version 0.83b: -------------- - - Added experimental/clang_asm_normalize/ and related notes in + - Added examples/clang_asm_normalize/ and related notes in env_variables.txt and afl-as.c. Thanks to Ryan Govostes for the idea. - Added advice on hardware utilization in README. @@ -2350,7 +2350,7 @@ Version 0.62b: - Made minor improvements to the allocator, as suggested by Tobias Ospelt. - - Added example instrumented memcmp() in experimental/instrumented_cmp. + - Added example instrumented memcmp() in examples/instrumented_cmp. - Added a speculative fix for MacOS X (clang detection, again). @@ -2475,7 +2475,7 @@ Version 0.53b: Version 0.52b: -------------- - - Added a quick summary of the contents in experimental/. + - Added a quick summary of the contents in examples/. - Made a fix to the process of writing fuzzer_stats. @@ -2637,7 +2637,7 @@ Version 0.43b: - Added status_screen.txt. - - Added experimental/canvas_harness. + - Added examples/canvas_harness. - Made a minor change to the Makefile GCC check. Suggested by Hanno Boeck. @@ -2648,7 +2648,7 @@ Version 0.42b: - Fixed a bug with red zone handling for 64-bit (oops!). Problem reported by Felix Groebert. - - Implemented horribly experimental ARM support in experimental/arm_support. + - Implemented horribly experimental ARM support in examples/arm_support. - Made several improvements to error messages. @@ -2687,7 +2687,7 @@ Version 0.40b: - Added support for parallelized fuzzing. Inspired by earlier patch from Sebastian Roschke. - - Added an example in experimental/distributed_fuzzing/. + - Added an example in examples/distributed_fuzzing/. -------------- Version 0.39b: @@ -2837,7 +2837,7 @@ Version 0.26b: - Added a built-in effort minimizer to get rid of potentially redundant inputs, - - Provided a testcase count minimization script in experimental/, + - Provided a testcase count minimization script in examples/, - Made miscellaneous improvements to directory and file handling. diff --git a/docs/README.md b/docs/README.md index 32d46ee8..e926c956 120000..100644 --- a/docs/README.md +++ b/docs/README.md @@ -1 +1,682 @@ -../README.md \ No newline at end of file +# american fuzzy lop plus plus (afl++) + +  + + Release Version: 2.60c + + Github Version: 2.60d + + includes all necessary/interesting changes from Google's afl 2.56b + + + Originally developed by Michal "lcamtuf" Zalewski. + + Repository: [https://github.com/vanhauser-thc/AFLplusplus](https://github.com/vanhauser-thc/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 noteable 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 11, 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 whitelist 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 (enable with `-R` to add or `-RR` to run it exclusivly). + + * qbdi_mode: fuzz android native libraries via QBDI framework + + + A more thorough list is available in the PATCHES file. + + | Feature/Instrumentation | afl-gcc | llvm_mode | gcc_plugin | qemu_mode | unicorn_mode | + | ----------------------- |:-------:|:---------:|:----------:|:---------:|:------------:| + | laf-intel / CompCov | | x | | x86/arm | x86/arm | + | NeverZero | x | x(1) | (2) | x | x | + | Persistent mode | | x | x | x86 | x | + | Whitelist | | x | x | | | + | InsTrim | | x | | | | + + neverZero: + + (1) only in LLVM >= 9.0 due to a bug in llvm in previous versions + + (2) gcc creates non-performant code, hence it is disabled in gcc_plugin + + So all in all this is the best-of afl that is currently out there :-) + + For new versions and additional information, check out: + [https://github.com/vanhauser-thc/AFLplusplus](https://github.com/vanhauser-thc/AFLplusplus) + + To compare notes with other users or get notified about major new features, + send a mail to <afl-users+subscribe@googlegroups.com>. + + See [docs/QuickStartGuide.md](docs/QuickStartGuide.md) if you don't have time to + read this file. + + +## 0) Building and installing afl++ + +afl++ has many build options. +The easiest is to build and install everything: + +```shell +$ make distrib +$ sudo make install +``` + +Note that "make distrib" also builds llvm_mode, qemu_mode, unicorn_mode and +more. If you just want plain afl then do "make all", however compiling and +using at least llvm_mode is highly recommended for much better results - +hence in this case + +```shell +$ make source-only +``` +is what you should choose. + +These build options exist: + +* all: just the main afl++ binaries +* binary-only: everything for binary-only fuzzing: qemu_mode, unicorn_mode, libdislocator, libtokencap, radamsa +* source-only: everything for source code fuzzing: llvm_mode, libdislocator, libtokencap, radamsa +* distrib: everything (for both binary-only and source code fuzzing) +* install: installs everything you have compiled with the build options above +* clean: cleans everything. for qemu_mode and unicorn_mode it means it deletes all downloads as well +* code-format: format the code, do this before you commit and send a PR please! +* tests: runs test cases to ensure that all features are still working as they should +* help: shows these build options + +[Unless you are on Mac OS X](https://developer.apple.com/library/archive/qa/qa1118/_index.html) you can also build statically linked versions of the +afl++ binaries by passing the STATIC=1 argument to make: + +```shell +$ make all STATIC=1 +``` + +Note that afl++ is faster and better the newer the compilers used are. +Hence gcc-9 and especially llvm-9 should be the compilers of choice. +If your distribution does not have them, you can use the Dockerfile: + +```shell +$ docker build -t aflplusplus +``` + + +## 1) Challenges of guided fuzzing + +Fuzzing is one of the most powerful and proven strategies for identifying +security issues in real-world software; it is responsible for the vast +majority of remote code execution and privilege escalation bugs found to date +in security-critical software. + +Unfortunately, fuzzing is also relatively shallow; blind, random mutations +make it very unlikely to reach certain code paths in the tested code, leaving +some vulnerabilities firmly outside the reach of this technique. + +There have been numerous attempts to solve this problem. One of the early +approaches - pioneered by Tavis Ormandy - is corpus distillation. The method +relies on coverage signals to select a subset of interesting seeds from a +massive, high-quality corpus of candidate files, and then fuzz them by +traditional means. The approach works exceptionally well, but requires such +a corpus to be readily available. In addition, block coverage measurements +provide only a very simplistic understanding of program state, and are less +useful for guiding the fuzzing effort in the long haul. + +Other, more sophisticated research has focused on techniques such as program +flow analysis ("concolic execution"), symbolic execution, or static analysis. +All these methods are extremely promising in experimental settings, but tend +to suffer from reliability and performance problems in practical uses - and +currently do not offer a viable alternative to "dumb" fuzzing techniques. + + +## 2) The afl-fuzz approach + +American Fuzzy Lop is a brute-force fuzzer coupled with an exceedingly simple +but rock-solid instrumentation-guided genetic algorithm. It uses a modified +form of edge coverage to effortlessly pick up subtle, local-scale changes to +program control flow. + +Simplifying a bit, the overall algorithm can be summed up as: + + 1) Load user-supplied initial test cases into the queue, + + 2) Take next input file from the queue, + + 3) Attempt to trim the test case to the smallest size that doesn't alter + the measured behavior of the program, + + 4) Repeatedly mutate the file using a balanced and well-researched variety + of traditional fuzzing strategies, + + 5) If any of the generated mutations resulted in a new state transition + recorded by the instrumentation, add mutated output as a new entry in the + queue. + + 6) Go to 2. + +The discovered test cases are also periodically culled to eliminate ones that +have been obsoleted by newer, higher-coverage finds; and undergo several other +instrumentation-driven effort minimization steps. + +As a side result of the fuzzing process, the tool creates a small, +self-contained corpus of interesting test cases. These are extremely useful +for seeding other, labor- or resource-intensive testing regimes - for example, +for stress-testing browsers, office applications, graphics suites, or +closed-source tools. + +The fuzzer is thoroughly tested to deliver out-of-the-box performance far +superior to blind fuzzing or coverage-only tools. + + +## 3) Instrumenting programs for use with AFL + +PLEASE NOTE: llvm_mode compilation with afl-clang-fast/afl-clang-fast++ +instead of afl-gcc/afl-g++ is much faster and has a few cool features. +See llvm_mode/ - however few code does not compile with llvm. +We support llvm versions 3.8.0 to 11. + +When source code is available, instrumentation can be injected by a companion +tool that works as a drop-in replacement for gcc or clang in any standard build +process for third-party code. + +The instrumentation has a fairly modest performance impact; in conjunction with +other optimizations implemented by afl-fuzz, most programs can be fuzzed as fast +or even faster than possible with traditional tools. + +The correct way to recompile the target program may vary depending on the +specifics of the build process, but a nearly-universal approach would be: + +```shell +$ CC=/path/to/afl/afl-gcc ./configure +$ make clean all +``` + +For C++ programs, you'd would also want to set `CXX=/path/to/afl/afl-g++`. + +The clang wrappers (afl-clang and afl-clang++) can be used in the same way; +clang users may also opt to leverage a higher-performance instrumentation mode, +as described in [llvm_mode/README.md](llvm_mode/README.md). +Clang/LLVM has a much better performance and works with LLVM version 3.8.0 to 11. + +Using the LAF Intel performance enhancements are also recommended, see +[llvm_mode/README.laf-intel.md](llvm_mode/README.laf-intel.md) + +Using partial instrumentation is also recommended, see +[llvm_mode/README.whitelist.md](llvm_mode/README.whitelist.md) + +When testing libraries, you need to find or write a simple program that reads +data from stdin or from a file and passes it to the tested library. In such a +case, it is essential to link this executable against a static version of the +instrumented library, or to make sure that the correct .so file is loaded at +runtime (usually by setting `LD_LIBRARY_PATH`). The simplest option is a static +build, usually possible via: + +```shell +$ CC=/path/to/afl/afl-gcc ./configure --disable-shared +``` + +Setting `AFL_HARDEN=1` when calling 'make' will cause the CC wrapper to +automatically enable code hardening options that make it easier to detect +simple memory bugs. Libdislocator, a helper library included with AFL (see +[libdislocator/README.md](libdislocator/README.md)) can help uncover heap corruption issues, too. + +PS. ASAN users are advised to review [docs/notes_for_asan.md](docs/notes_for_asan.md) +file for important caveats. + + +## 4) 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). + +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) + + +## 5) Power schedules + +The power schedules were copied from Marcel Böhme's excellent AFLfast +implementation and expand on the ability to discover new paths and +therefore may increase the code coverage. + +The available schedules are: + + - explore (default) + - fast + - coe + - quad + - lin + - exploit + +In parallel mode (-M/-S, several instances with shared queue), we suggest to +run the master using the exploit schedule (-p exploit) and the slaves with a +combination of cut-off-exponential (-p coe), exponential (-p fast; default), +and explore (-p explore) schedules. + +In single mode, using -p fast is usually more beneficial than the default +explore mode. +(We don't want to change the default behaviour of afl, so "fast" has not been +made the default mode). + +More details can be found in the paper published at the 23rd ACM Conference on +Computer and Communications Security [CCS'16](https://www.sigsac.org/ccs/CCS2016/accepted-papers/) +## 6) Choosing initial test cases + +To operate correctly, the fuzzer requires one or more starting file that +contains a good example of the input data normally expected by the targeted +application. There are two basic rules: + + - Keep the files small. Under 1 kB is ideal, although not strictly necessary. + For a discussion of why size matters, see [perf_tips.txt](docs/perf_tips.txt). + + - Use multiple test cases only if they are functionally different from + each other. There is no point in using fifty different vacation photos + to fuzz an image library. + +You can find many good examples of starting files in the testcases/ subdirectory +that comes with this tool. + +PS. If a large corpus of data is available for screening, you may want to use +the afl-cmin utility to identify a subset of functionally distinct files that +exercise different code paths in the target binary. + + +## 7) Fuzzing binaries + +The fuzzing process itself is carried out by the afl-fuzz utility. This program +requires a read-only directory with initial test cases, a separate place to +store its findings, plus a path to the binary to test. + +For target binaries that accept input directly from stdin, the usual syntax is: + +```shell +$ ./afl-fuzz -i testcase_dir -o findings_dir /path/to/program [...params...] +``` + +For programs that take input from a file, use '@@' to mark the location in +the target's command line where the input file name should be placed. The +fuzzer will substitute this for you: + +```shell +$ ./afl-fuzz -i testcase_dir -o findings_dir /path/to/program @@ +``` + +You can also use the -f option to have the mutated data written to a specific +file. This is useful if the program expects a particular file extension or so. + +Non-instrumented binaries can be fuzzed in the QEMU mode (add -Q in the command +line) or in a traditional, blind-fuzzer mode (specify -n). + +You can use -t and -m to override the default timeout and memory limit for the +executed process; rare examples of targets that may need these settings touched +include compilers and video decoders. + +Tips for optimizing fuzzing performance are discussed in [perf_tips.txt](docs/perf_tips.txt). + +Note that afl-fuzz starts by performing an array of deterministic fuzzing +steps, which can take several days, but tend to produce neat test cases. If you +want quick & dirty results right away - akin to zzuf and other traditional +fuzzers - add the -d option to the command line. + + +## 8) Interpreting output + +See the [docs/status_screen.txt](docs/status_screen.txt) file for information on +how to interpret the displayed stats and monitor the health of the process. Be +sure to consult this file especially if any UI elements are highlighted in red. + +The fuzzing process will continue until you press Ctrl-C. At minimum, you want +to allow the fuzzer to complete one queue cycle, which may take anywhere from a +couple of hours to a week or so. + +There are three subdirectories created within the output directory and updated +in real time: + + - queue/ - test cases for every distinctive execution path, plus all the + starting files given by the user. This is the synthesized corpus + mentioned in section 2. + + Before using this corpus for any other purposes, you can shrink + it to a smaller size using the afl-cmin tool. The tool will find + a smaller subset of files offering equivalent edge coverage. + + - crashes/ - unique test cases that cause the tested program to receive a + fatal signal (e.g., SIGSEGV, SIGILL, SIGABRT). The entries are + grouped by the received signal. + + - hangs/ - unique test cases that cause the tested program to time out. The + default time limit before something is classified as a hang is + the larger of 1 second and the value of the -t parameter. + The value can be fine-tuned by setting AFL_HANG_TMOUT, but this + is rarely necessary. + +Crashes and hangs are considered "unique" if the associated execution paths +involve any state transitions not seen in previously-recorded faults. If a +single bug can be reached in multiple ways, there will be some count inflation +early in the process, but this should quickly taper off. + +The file names for crashes and hangs are correlated with parent, non-faulting +queue entries. This should help with debugging. + +When you can't reproduce a crash found by afl-fuzz, the most likely cause is +that you are not setting the same memory limit as used by the tool. Try: + +```shell +$ LIMIT_MB=50 +$ ( ulimit -Sv $[LIMIT_MB << 10]; /path/to/tested_binary ... ) +``` + +Change LIMIT_MB to match the -m parameter passed to afl-fuzz. On OpenBSD, +also change -Sv to -Sd. + +Any existing output directory can be also used to resume aborted jobs; try: + +```shell +$ ./afl-fuzz -i- -o existing_output_dir [...etc...] +``` + +If you have gnuplot installed, you can also generate some pretty graphs for any +active fuzzing task using afl-plot. For an example of how this looks like, +see [http://lcamtuf.coredump.cx/afl/plot/](http://lcamtuf.coredump.cx/afl/plot/). + + +## 9) Parallelized fuzzing + +Every instance of afl-fuzz takes up roughly one core. This means that on +multi-core systems, parallelization is necessary to fully utilize the hardware. +For tips on how to fuzz a common target on multiple cores or multiple networked +machines, please refer to [docs/parallel_fuzzing.md](docs/parallel_fuzzing.md). + +The parallel fuzzing mode also offers a simple way for interfacing AFL to other +fuzzers, to symbolic or concolic execution engines, and so forth; again, see the +last section of [docs/parallel_fuzzing.md](docs/parallel_fuzzing.md) for tips. + + +## 10) Fuzzer dictionaries + +By default, afl-fuzz mutation engine is optimized for compact data formats - +say, images, multimedia, compressed data, regular expression syntax, or shell +scripts. It is somewhat less suited for languages with particularly verbose and +redundant verbiage - notably including HTML, SQL, or JavaScript. + +To avoid the hassle of building syntax-aware tools, afl-fuzz provides a way to +seed the fuzzing process with an optional dictionary of language keywords, +magic headers, or other special tokens associated with the targeted data type +-- and use that to reconstruct the underlying grammar on the go: + + [http://lcamtuf.blogspot.com/2015/01/afl-fuzz-making-up-grammar-with.html](http://lcamtuf.blogspot.com/2015/01/afl-fuzz-making-up-grammar-with.html) + +To use this feature, you first need to create a dictionary in one of the two +formats discussed in [dictionaries/README.md](dictionaries/README.md); +and then point the fuzzer to it via the -x option in the command line. + +(Several common dictionaries are already provided in that subdirectory, too.) + +There is no way to provide more structured descriptions of the underlying +syntax, but the fuzzer will likely figure out some of this based on the +instrumentation feedback alone. This actually works in practice, say: + + [http://lcamtuf.blogspot.com/2015/04/finding-bugs-in-sqlite-easy-way.html](http://lcamtuf.blogspot.com/2015/04/finding-bugs-in-sqlite-easy-way.html) + +PS. Even when no explicit dictionary is given, afl-fuzz will try to extract +existing syntax tokens in the input corpus by watching the instrumentation +very closely during deterministic byte flips. This works for some types of +parsers and grammars, but isn't nearly as good as the -x mode. + +If a dictionary is really hard to come by, another option is to let AFL run +for a while, and then use the token capture library that comes as a companion +utility with AFL. For that, see [libtokencap/README.md](libtokencap/README.tokencap.md). + + +## 11) Crash triage + +The coverage-based grouping of crashes usually produces a small data set that +can be quickly triaged manually or with a very simple GDB or Valgrind script. +Every crash is also traceable to its parent non-crashing test case in the +queue, making it easier to diagnose faults. + +Having said that, it's important to acknowledge that some fuzzing crashes can be +difficult to quickly evaluate for exploitability without a lot of debugging and +code analysis work. To assist with this task, afl-fuzz supports a very unique +"crash exploration" mode enabled with the -C flag. + +In this mode, the fuzzer takes one or more crashing test cases as the input, +and uses its feedback-driven fuzzing strategies to very quickly enumerate all +code paths that can be reached in the program while keeping it in the +crashing state. + +Mutations that do not result in a crash are rejected; so are any changes that +do not affect the execution path. + +The output is a small corpus of files that can be very rapidly examined to see +what degree of control the attacker has over the faulting address, or whether +it is possible to get past an initial out-of-bounds read - and see what lies +beneath. + +Oh, one more thing: for test case minimization, give afl-tmin a try. The tool +can be operated in a very simple way: + +```shell +$ ./afl-tmin -i test_case -o minimized_result -- /path/to/program [...] +``` + +The tool works with crashing and non-crashing test cases alike. In the crash +mode, it will happily accept instrumented and non-instrumented binaries. In the +non-crashing mode, the minimizer relies on standard AFL instrumentation to make +the file simpler without altering the execution path. + +The minimizer accepts the -m, -t, -f and @@ syntax in a manner compatible with +afl-fuzz. + +Another recent addition to AFL is the afl-analyze tool. It takes an input +file, attempts to sequentially flip bytes, and observes the behavior of the +tested program. It then color-codes the input based on which sections appear to +be critical, and which are not; while not bulletproof, it can often offer quick +insights into complex file formats. More info about its operation can be found +near the end of [docs/technical_details.txt](docs/technical_details.txt). + + +## 12) Going beyond crashes + +Fuzzing is a wonderful and underutilized technique for discovering non-crashing +design and implementation errors, too. Quite a few interesting bugs have been +found by modifying the target programs to call abort() when, say: + + - Two bignum libraries produce different outputs when given the same + fuzzer-generated input, + + - An image library produces different outputs when asked to decode the same + input image several times in a row, + + - A serialization / deserialization library fails to produce stable outputs + when iteratively serializing and deserializing fuzzer-supplied data, + + - A compression library produces an output inconsistent with the input file + when asked to compress and then decompress a particular blob. + +Implementing these or similar sanity checks usually takes very little time; +if you are the maintainer of a particular package, you can make this code +conditional with `#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION` (a flag also +shared with libfuzzer) or `#ifdef __AFL_COMPILER` (this one is just for AFL). + + +## 13) Common-sense risks + +Please keep in mind that, similarly to many other computationally-intensive +tasks, fuzzing may put strain on your hardware and on the OS. In particular: + + - Your CPU will run hot and will need adequate cooling. In most cases, if + cooling is insufficient or stops working properly, CPU speeds will be + automatically throttled. That said, especially when fuzzing on less + suitable hardware (laptops, smartphones, etc), it's not entirely impossible + for something to blow up. + + - Targeted programs may end up erratically grabbing gigabytes of memory or + filling up disk space with junk files. AFL tries to enforce basic memory + limits, but can't prevent each and every possible mishap. The bottom line + is that you shouldn't be fuzzing on systems where the prospect of data loss + is not an acceptable risk. + + - Fuzzing involves billions of reads and writes to the filesystem. On modern + systems, this will be usually heavily cached, resulting in fairly modest + "physical" I/O - but there are many factors that may alter this equation. + It is your responsibility to monitor for potential trouble; with very heavy + I/O, the lifespan of many HDDs and SSDs may be reduced. + + A good way to monitor disk I/O on Linux is the 'iostat' command: + +```shell + $ iostat -d 3 -x -k [...optional disk ID...] +``` + + +## 14) Known limitations & areas for improvement + +Here are some of the most important caveats for AFL: + + - AFL detects faults by checking for the first spawned process dying due to + a signal (SIGSEGV, SIGABRT, etc). Programs that install custom handlers for + these signals may need to have the relevant code commented out. In the same + vein, faults in child processed spawned by the fuzzed target may evade + detection unless you manually add some code to catch that. + + - As with any other brute-force tool, the fuzzer offers limited coverage if + encryption, checksums, cryptographic signatures, or compression are used to + wholly wrap the actual data format to be tested. + + To work around this, you can comment out the relevant checks (see + examples/libpng_no_checksum/ for inspiration); if this is not possible, + you can also write a postprocessor, as explained in + examples/post_library/ (with AFL_POST_LIBRARY) + + - There are some unfortunate trade-offs with ASAN and 64-bit binaries. This + isn't due to any specific fault of afl-fuzz; see [docs/notes_for_asan.md](docs/notes_for_asan.md) + for tips. + + - There is no direct support for fuzzing network services, background + daemons, or interactive apps that require UI interaction to work. You may + need to make simple code changes to make them behave in a more traditional + way. Preeny may offer a relatively simple option, too - see: + [https://github.com/zardus/preeny](https://github.com/zardus/preeny) + + Some useful tips for modifying network-based services can be also found at: + [https://www.fastly.com/blog/how-to-fuzz-server-american-fuzzy-lop](https://www.fastly.com/blog/how-to-fuzz-server-american-fuzzy-lop) + + - AFL doesn't output human-readable coverage data. If you want to monitor + coverage, use afl-cov from Michael Rash: [https://github.com/mrash/afl-cov](https://github.com/mrash/afl-cov) + + - Occasionally, sentient machines rise against their creators. If this + happens to you, please consult [http://lcamtuf.coredump.cx/prep/](http://lcamtuf.coredump.cx/prep/). + +Beyond this, see INSTALL for platform-specific tips. + + +## 15) Special thanks + +Many of the improvements to the original afl and afl++ wouldn't be possible +without feedback, bug reports, or patches from: + +``` + Jann Horn Hanno Boeck + Felix Groebert Jakub Wilk + Richard W. M. Jones Alexander Cherepanov + Tom Ritter Hovik Manucharyan + Sebastian Roschke Eberhard Mattes + Padraig Brady Ben Laurie + @dronesec Luca Barbato + Tobias Ospelt Thomas Jarosch + Martin Carpenter Mudge Zatko + Joe Zbiciak Ryan Govostes + Michael Rash William Robinet + Jonathan Gray Filipe Cabecinhas + Nico Weber Jodie Cunningham + Andrew Griffiths Parker Thompson + Jonathan Neuschaefer Tyler Nighswander + Ben Nagy Samir Aguiar + Aidan Thornton Aleksandar Nikolich + Sam Hakim Laszlo Szekeres + David A. Wheeler Turo Lamminen + Andreas Stieger Richard Godbee + Louis Dassy teor2345 + Alex Moneger Dmitry Vyukov + Keegan McAllister Kostya Serebryany + Richo Healey Martijn Bogaard + rc0r Jonathan Foote + Christian Holler Dominique Pelle + Jacek Wielemborek Leo Barnes + Jeremy Barnes Jeff Trull + Guillaume Endignoux ilovezfs + Daniel Godas-Lopez Franjo Ivancic + Austin Seipp Daniel Komaromy + Daniel Binderman Jonathan Metzman + Vegard Nossum Jan Kneschke + Kurt Roeckx Marcel Boehme + Van-Thuan Pham Abhik Roychoudhury + Joshua J. Drake Toby Hutton + Rene Freingruber Sergey Davidoff + Sami Liedes Craig Young + Andrzej Jackowski Daniel Hodson + Nathan Voss Dominik Maier + Andrea Biondo Vincent Le Garrec + Khaled Yakdan Kuang-che Wu +``` + +Thank you! + + +## 16) Contact + +Questions? Concerns? Bug reports? The contributors can be reached via +[https://github.com/vanhauser-thc/AFLplusplus](https://github.com/vanhauser-thc/AFLplusplus) + +There is also a mailing list for the afl project; to join, send a mail to +<afl-users+subscribe@googlegroups.com>. Or, if you prefer to browse +archives first, try: [https://groups.google.com/group/afl-users](https://groups.google.com/group/afl-users) diff --git a/docs/README.radamsa.md b/docs/README.radamsa.md index b4823063..b01a4c83 120000..100644 --- a/docs/README.radamsa.md +++ b/docs/README.radamsa.md @@ -1 +1,9 @@ -../src/third_party/libradamsa/README.md \ No newline at end of file +# libradamsa + +Pretranslated radamsa library. This code belongs to the radamsa author. + +> Original repository: https://gitlab.com/akihe/radamsa + +> Source commit: 7b2cc2d0 + +> The code here is adapted for AFL++ with minor changes respect the original version diff --git a/docs/env_variables.md b/docs/env_variables.md index d38a4bc3..677a7b5f 100644 --- a/docs/env_variables.md +++ b/docs/env_variables.md @@ -34,7 +34,7 @@ tools make fairly broad use of environmental variables: in your $PATH. - AFL_PATH can be used to point afl-gcc to an alternate location of afl-as. - One possible use of this is experimental/clang_asm_normalize/, which lets + One possible use of this is examples/clang_asm_normalize/, which lets you instrument hand-written assembly when compiling clang code by plugging a normalizer into the chain. (There is no equivalent feature for GCC.) @@ -215,7 +215,7 @@ checks or alter some of the more exotic semantics of the tool: Beyond counter aesthetics, not much else should change. - Setting AFL_POST_LIBRARY allows you to configure a postprocessor for - mutated files - say, to fix up checksums. See experimental/post_library/ + mutated files - say, to fix up checksums. See examples/post_library/ for more. - Setting AFL_CUSTOM_MUTATOR_LIBRARY to a shared library with diff --git a/docs/life_pro_tips.txt b/docs/life_pro_tips.txt index 27c70592..03407e4a 100644 --- a/docs/life_pro_tips.txt +++ b/docs/life_pro_tips.txt @@ -113,12 +113,12 @@ Be sure to check out docs/sister_projects.txt before writing your own. % Need to fuzz the command-line arguments of a particular program? -You can find a simple solution in experimental/argv_fuzzing. +You can find a simple solution in examples/argv_fuzzing. % Attacking a format that uses checksums? Remove the checksum-checking code or -use a postprocessor! See experimental/post_library/ for more. +use a postprocessor! See examples/post_library/ for more. % diff --git a/docs/notes_for_asan.md b/docs/notes_for_asan.md index c05d0771..c10a9726 100644 --- a/docs/notes_for_asan.md +++ b/docs/notes_for_asan.md @@ -20,7 +20,7 @@ Because of this, fuzzing with ASAN is recommended only in four scenarios: - Precisely gauge memory needs using http://jwilk.net/software/recidivm . - Limit the memory available to process using cgroups on Linux (see - experimental/asan_cgroups). + examples/asan_cgroups). To compile with ASAN, set AFL_USE_ASAN=1 before calling 'make clean all'. The afl-gcc / afl-clang wrappers will pick that up and add the appropriate flags. @@ -70,7 +70,7 @@ There are also cgroups, but they are Linux-specific, not universally available even on Linux systems, and they require root permissions to set up; I'm a bit hesitant to make afl-fuzz require root permissions just for that. That said, if you are on Linux and want to use cgroups, check out the contributed script -that ships in experimental/asan_cgroups/. +that ships in examples/asan_cgroups/. In settings where cgroups aren't available, we have no nice, portable way to avoid counting the ASAN allocation toward the limit. On 32-bit systems, or for diff --git a/docs/parallel_fuzzing.md b/docs/parallel_fuzzing.md index 51fa3986..e6780125 100644 --- a/docs/parallel_fuzzing.md +++ b/docs/parallel_fuzzing.md @@ -126,7 +126,7 @@ write a simple script that performs two actions: done ``` -There is an example of such a script in experimental/distributed_fuzzing/; +There is an example of such a script in examples/distributed_fuzzing/; you can also find a more featured, experimental tool developed by Martijn Bogaard at: diff --git a/examples/README.md b/examples/README.md index 512b03f7..37fae1a0 100644 --- a/examples/README.md +++ b/examples/README.md @@ -38,7 +38,7 @@ Here's a quick overview of the stuff you can find in this directory: - socket_fuzzing - a LD_PRELOAD library 'redirects' a socket to stdin for fuzzing access with afl++ -Note that the minimize_corpus.sh tool has graduated from the experimental/ +Note that the minimize_corpus.sh tool has graduated from the examples/ directory and is now available as ../afl-cmin. The LLVM mode has likewise graduated to ../llvm_mode/*. diff --git a/gcc_plugin/README.md b/gcc_plugin/README.md index 8b944f1a..20ae5c6f 100644 --- a/gcc_plugin/README.md +++ b/gcc_plugin/README.md @@ -141,7 +141,7 @@ The numerical value specified within the loop controls the maximum number of iterations before AFL will restart the process from scratch. This minimizes the impact of memory leaks and similar glitches; 1000 is a good starting point. -A more detailed template is shown in ../experimental/persistent_demo/. +A more detailed template is shown in ../examples/persistent_demo/. Similarly to the previous mode, the feature works only with afl-gcc-fast or afl-clang-fast; #ifdef guards can be used to suppress it when using other compilers. diff --git a/llvm_mode/README.md b/llvm_mode/README.md index 8af763c5..806f0269 100644 --- a/llvm_mode/README.md +++ b/llvm_mode/README.md @@ -189,7 +189,7 @@ the impact of memory leaks and similar glitches; 1000 is a good starting point, and going much higher increases the likelihood of hiccups without giving you any real performance benefits. -A more detailed template is shown in ../experimental/persistent_demo/. +A more detailed template is shown in ../examples/persistent_demo/. Similarly to the previous mode, the feature works only with afl-clang-fast; #ifdef guards can be used to suppress it when using other compilers. diff --git a/qemu_mode/README.md b/qemu_mode/README.md index 60d6c060..ccfd50e3 100644 --- a/qemu_mode/README.md +++ b/qemu_mode/README.md @@ -164,7 +164,7 @@ match. ## 9) Gotchas, feedback, bugs If you need to fix up checksums or do other cleanup on mutated test cases, see -experimental/post_library/ for a viable solution. +examples/post_library/ for a viable solution. Do not mix QEMU mode with ASAN, MSAN, or the likes; QEMU doesn't appreciate the "shadow VM" trick employed by the sanitizers and will probably just diff --git a/src/afl-as.c b/src/afl-as.c index 8d689385..5fa83569 100644 --- a/src/afl-as.c +++ b/src/afl-as.c @@ -27,7 +27,7 @@ utility has right now is to be able to skip them gracefully and allow the compilation process to continue. - That said, see experimental/clang_asm_normalize/ for a solution that may + That said, see examples/clang_asm_normalize/ for a solution that may allow clang users to make things work even with hand-crafted assembly. Just note that there is no equivalent for GCC. diff --git a/test/test.sh b/test/test.sh index 20e02a83..79cba57a 100755 --- a/test/test.sh +++ b/test/test.sh @@ -318,7 +318,7 @@ test -e ../afl-clang-fast -a -e ../split-switches-pass.so && { CODE=1 } rm -f test-compcov test.out whitelist.txt - ../afl-clang-fast -o test-persistent ../experimental/persistent_demo/persistent_demo.c > /dev/null 2>&1 + ../afl-clang-fast -o test-persistent ../examples/persistent_demo/persistent_demo.c > /dev/null 2>&1 test -e test-persistent && { echo foo | ../afl-showmap -o /dev/null -q -r ./test-persistent && { $ECHO "$GREEN[+] llvm_mode persistent mode feature works correctly" @@ -427,7 +427,7 @@ test -e ../afl-gcc-fast -a -e ../afl-gcc-rt.o && { CODE=1 } rm -f test-compcov test.out whitelist.txt - ../afl-gcc-fast -o test-persistent ../experimental/persistent_demo/persistent_demo.c > /dev/null 2>&1 + ../afl-gcc-fast -o test-persistent ../examples/persistent_demo/persistent_demo.c > /dev/null 2>&1 test -e test-persistent && { echo foo | ../afl-showmap -o /dev/null -q -r ./test-persistent && { $ECHO "$GREEN[+] gcc_plugin persistent mode feature works correctly" |