diff options
Diffstat (limited to 'docs/FAQ.md')
-rw-r--r-- | docs/FAQ.md | 422 |
1 files changed, 182 insertions, 240 deletions
diff --git a/docs/FAQ.md b/docs/FAQ.md index 0e816062..7869ee61 100644 --- a/docs/FAQ.md +++ b/docs/FAQ.md @@ -1,243 +1,185 @@ -# Frequently asked questions about AFL++ - -## Contents - - * [What is the difference between AFL and AFL++?](#what-is-the-difference-between-afl-and-afl) - * [I got a weird compile error from clang](#i-got-a-weird-compile-error-from-clang) - * [How to improve the fuzzing speed?](#how-to-improve-the-fuzzing-speed) - * [How do I fuzz a network service?](#how-do-i-fuzz-a-network-service) - * [How do I fuzz a GUI program?](#how-do-i-fuzz-a-gui-program) - * [What is an edge?](#what-is-an-edge) - * [Why is my stability below 100%?](#why-is-my-stability-below-100) - * [How can I improve the stability value?](#how-can-i-improve-the-stability-value) +# Frequently asked questions (FAQ) If you find an interesting or important question missing, submit it via -[https://github.com/AFLplusplus/AFLplusplus/issues](https://github.com/AFLplusplus/AFLplusplus/issues) - -## What is the difference between AFL and AFL++? - -American Fuzzy Lop (AFL) was developed by Michał "lcamtuf" Zalewski starting in -2013/2014, and when he left Google end of 2017 he stopped developing it. - -At the end of 2019 the Google fuzzing team took over maintenance of AFL, however -it is only accepting PRs from the community and is not developing enhancements -anymore. - -In the second quarter of 2019, 1 1/2 year later when no further development of -AFL had happened and it became clear there would none be coming, AFL++ -was born, where initially community patches were collected and applied -for bug fixes and enhancements. Then from various AFL spin-offs - mostly academic -research - features were integrated. This already resulted in a much advanced -AFL. - -Until the end of 2019 the AFL++ team had grown to four active developers which -then implemented their own research and features, making it now by far the most -flexible and feature rich guided fuzzer available as open source. -And in independent fuzzing benchmarks it is one of the best fuzzers available, -e.g. [Fuzzbench Report](https://www.fuzzbench.com/reports/2020-08-03/index.html) - -## I got a weird compile error from clang - -If you see this kind of error when trying to instrument a target with afl-cc/ -afl-clang-fast/afl-clang-lto: -``` -/prg/tmp/llvm-project/build/bin/clang-13: symbol lookup error: /usr/local/bin/../lib/afl//cmplog-instructions-pass.so: undefined symbol: _ZNK4llvm8TypeSizecvmEv -clang-13: error: unable to execute command: No such file or directory -clang-13: error: clang frontend command failed due to signal (use -v to see invocation) -clang version 13.0.0 (https://github.com/llvm/llvm-project 1d7cf550721c51030144f3cd295c5789d51c4aad) -Target: x86_64-unknown-linux-gnu -Thread model: posix -InstalledDir: /prg/tmp/llvm-project/build/bin -clang-13: note: diagnostic msg: -******************** -``` -Then this means that your OS updated the clang installation from an upgrade -package and because of that the AFL++ llvm plugins do not match anymore. - -Solution: `git pull ; make clean install` of AFL++ - -## How to improve the fuzzing speed? - - 1. Use [llvm_mode](../instrumentation/README.llvm.md): afl-clang-lto (llvm >= 11) or afl-clang-fast (llvm >= 9 recommended) - 2. Use [persistent mode](../instrumentation/README.persistent_mode.md) (x2-x20 speed increase) - 3. Use the [AFL++ snapshot module](https://github.com/AFLplusplus/AFL-Snapshot-LKM) (x2 speed increase) - 4. If you do not use shmem persistent mode, use `AFL_TMPDIR` to put the input file directory on a tempfs location, see [docs/env_variables.md](docs/env_variables.md) - 5. Improve Linux kernel performance: modify `/etc/default/grub`, set `GRUB_CMDLINE_LINUX_DEFAULT="ibpb=off ibrs=off kpti=off l1tf=off mds=off mitigations=off no_stf_barrier noibpb noibrs nopcid nopti nospec_store_bypass_disable nospectre_v1 nospectre_v2 pcid=off pti=off spec_store_bypass_disable=off spectre_v2=off stf_barrier=off"`; then `update-grub` and `reboot` (warning: makes the system less secure) - 6. Running on an `ext2` filesystem with `noatime` mount option will be a bit faster than on any other journaling filesystem - 7. Use your cores! [README.md:3.b) Using multiple cores/threads](../README.md#b-using-multiple-coresthreads) - -## How do I fuzz a network service? - -The short answer is - you cannot, at least not "out of the box". - -Using a network channel is inadequate for several reasons: -- it has a slow-down of x10-20 on the fuzzing speed -- it does not scale to fuzzing multiple instances easily, -- instead of one initial data packet often a back-and-forth interplay of packets is needed for stateful protocols (which is totally unsupported by most coverage aware fuzzers). - -The established method to fuzz network services is to modify the source code -to read from a file or stdin (fd 0) (or even faster via shared memory, combine -this with persistent mode [instrumentation/README.persistent_mode.md](../instrumentation/README.persistent_mode.md) -and you have a performance gain of x10 instead of a performance loss of over -x10 - that is a x100 difference!). - -If modifying the source is not an option (e.g. because you only have a binary -and perform binary fuzzing) you can also use a shared library with AFL_PRELOAD -to emulate the network. This is also much faster than the real network would be. -See [utils/socket_fuzzing/](../utils/socket_fuzzing/). - -There is an outdated AFL++ branch that implements networking if you are -desperate though: [https://github.com/AFLplusplus/AFLplusplus/tree/networking](https://github.com/AFLplusplus/AFLplusplus/tree/networking) - -however a better option is AFLnet ([https://github.com/aflnet/aflnet](https://github.com/aflnet/aflnet)) -which allows you to define network state with different type of data packets. - -## How do I fuzz a GUI program? - -If the GUI program can read the fuzz data from a file (via the command line, -a fixed location or via an environment variable) without needing any user -interaction then it would be suitable for fuzzing. - -Otherwise it is not possible without modifying the source code - which is a -very good idea anyway as the GUI functionality is a huge CPU/time overhead -for the fuzzing. - -So create a new `main()` that just reads the test case and calls the -functionality for processing the input that the GUI program is using. - -## What is an "edge"? - -A program contains `functions`, `functions` contain the compiled machine code. -The compiled machine code in a `function` can be in a single or many `basic blocks`. -A `basic block` is the largest possible number of subsequent machine code -instructions that has exactly one entrypoint (which can be be entered by multiple other basic blocks) -and runs linearly without branching or jumping to other addresses (except at the end). -``` -function() { - A: - some - code - B: - if (x) goto C; else goto D; - C: - some code - goto E - D: - some code - goto B - E: - return -} -``` -Every code block between two jump locations is a `basic block`. - -An `edge` is then the unique relationship between two directly connected `basic blocks` (from the -code example above): -``` - Block A - | +[https://github.com/AFLplusplus/AFLplusplus/discussions](https://github.com/AFLplusplus/AFLplusplus/discussions). + +## General + +<details> + <summary id="what-is-the-difference-between-afl-and-aflplusplus">What is the difference between AFL and AFL++?</summary><p> + + AFL++ is a superior fork to Google's AFL - more speed, more and better + mutations, more and better instrumentation, custom module support, etc. + + American Fuzzy Lop (AFL) was developed by Michał "lcamtuf" Zalewski starting + in 2013/2014, and when he left Google end of 2017 he stopped developing it. + + At the end of 2019, the Google fuzzing team took over maintenance of AFL, + however, it is only accepting PRs from the community and is not developing + enhancements anymore. + + In the second quarter of 2019, 1 1/2 years later, when no further development + of AFL had happened and it became clear there would none be coming, AFL++ was + born, where initially community patches were collected and applied for bug + fixes and enhancements. Then from various AFL spin-offs - mostly academic + research - features were integrated. This already resulted in a much advanced + AFL. + + Until the end of 2019, the AFL++ team had grown to four active developers + which then implemented their own research and features, making it now by far + the most flexible and feature rich guided fuzzer available as open source. And + in independent fuzzing benchmarks it is one of the best fuzzers available, + e.g., [Fuzzbench + Report](https://www.fuzzbench.com/reports/2020-08-03/index.html). +</p></details> + +<details> + <summary id="where-can-i-find-tutorials">Where can I find tutorials?</summary><p> + + We compiled a list of tutorials and exercises, see + [tutorials.md](tutorials.md). +</p></details> + +<details> + <summary id="what-is-an-edge">What is an "edge"?</summary><p> + + A program contains `functions`, `functions` contain the compiled machine code. + The compiled machine code in a `function` can be in a single or many `basic + blocks`. A `basic block` is the largest possible number of subsequent machine + code instructions that has exactly one entry point (which can be be entered by + multiple other basic blocks) and runs linearly without branching or jumping to + other addresses (except at the end). + + ``` + function() { + A: + some + code + B: + if (x) goto C; else goto D; + C: + some code + goto E + D: + some code + goto B + E: + return + } + ``` + + Every code block between two jump locations is a `basic block`. + + An `edge` is then the unique relationship between two directly connected + `basic blocks` (from the code example above): + + ``` + Block A + | + v + Block B <------+ + / \ | + v v | + Block C Block D --+ + \ v - Block B <------+ - / \ | - v v | - Block C Block D --+ - \ - v - Block E -``` -Every line between two blocks is an `edge`. -Note that a few basic block loop to itself, this too would be an edge. - -## Why is my stability below 100%? - -Stability is measured by how many percent of the edges in the target are -"stable". Sending the same input again and again should take the exact same -path through the target every time. If that is the case, the stability is 100%. - -If however randomness happens, e.g. a thread reading other external data, -reaction to timing, etc. then in some of the re-executions with the same data -the edge coverage result will be different accross runs. -Those edges that change are then flagged "unstable". - -The more "unstable" edges, the more difficult for AFL++ to identify valid new -paths. - -A value above 90% is usually fine and a value above 80% is also still ok, and -even a value above 20% can still result in successful finds of bugs. -However, it is recommended that for values below 90% or 80% you should take -countermeasures to improve stability. - -## How can I improve the stability value? - -For fuzzing a 100% stable target that covers all edges is the best case. -A 90% stable target that covers all edges is however better than a 100% stable -target that ignores 10% of the edges. - -With instability you basically have a partial coverage loss on an edge, with -ignored functions you have a full loss on that edges. - -There are functions that are unstable, but also provide value to coverage, eg -init functions that use fuzz data as input for example. -If however a function that has nothing to do with the input data is the -source of instability, e.g. checking jitter, or is a hash map function etc. -then it should not be instrumented. - -To be able to exclude these functions (based on AFL++'s measured stability) -the following process will allow to identify functions with variable edges. - -Four steps are required to do this and it also requires quite some knowledge -of coding and/or disassembly and is effectively possible only with -afl-clang-fast PCGUARD and afl-clang-lto LTO instrumentation. - - 1. First step: Instrument to be able to find the responsible function(s). - - a) For LTO instrumented binaries this can be documented during compile - time, just set `export AFL_LLVM_DOCUMENT_IDS=/path/to/a/file`. - This file will have one assigned edge ID and the corresponding - function per line. - - b) For PCGUARD instrumented binaries it is much more difficult. Here you - can either modify the __sanitizer_cov_trace_pc_guard function in - instrumentation/afl-llvm-rt.o.c to write a backtrace to a file if the ID in - __afl_area_ptr[*guard] is one of the unstable edge IDs. - (Example code is already there). - Then recompile and reinstall llvm_mode and rebuild your target. - Run the recompiled target with afl-fuzz for a while and then check the - file that you wrote with the backtrace information. - Alternatively you can use `gdb` to hook __sanitizer_cov_trace_pc_guard_init - on start, check to which memory address the edge ID value is written - and set a write breakpoint to that address (`watch 0x.....`). - - c) in all other instrumentation types this is not possible. So just - recompile with the two mentioned above. This is just for - identifying the functions that have unstable edges. - - 2. Second step: Identify which edge ID numbers are unstable - - run the target with `export AFL_DEBUG=1` for a few minutes then terminate. - The out/fuzzer_stats file will then show the edge IDs that were identified - as unstable in the `var_bytes` entry. You can match these numbers - directly to the data you created in the first step. - Now you know which functions are responsible for the instability - - 3. Third step: create a text file with the filenames/functions - - Identify which source code files contain the functions that you need to - remove from instrumentation, or just specify the functions you want to - skip for instrumentation. Note that optimization might inline functions! - - Simply follow this document on how to do this: [instrumentation/README.instrument_list.md](../instrumentation/README.instrument_list.md) - If PCGUARD is used, then you need to follow this guide (needs llvm 12+!): - [http://clang.llvm.org/docs/SanitizerCoverage.html#partially-disabling-instrumentation](http://clang.llvm.org/docs/SanitizerCoverage.html#partially-disabling-instrumentation) - - Only exclude those functions from instrumentation that provide no value - for coverage - that is if it does not process any fuzz data directly - or indirectly (e.g. hash maps, thread management etc.). - If however a function directly or indirectly handles fuzz data then you - should not put the function in a deny instrumentation list and rather - live with the instability it comes with. - - 4. Fourth step: recompile the target - - Recompile, fuzz it, be happy :) - - This link explains this process for [Fuzzbench](https://github.com/google/fuzzbench/issues/677) + Block E + ``` + + Every line between two blocks is an `edge`. Note that a few basic block loop + to itself, this too would be an edge. +</p></details> + +## Targets + +<details> + <summary id="how-can-i-fuzz-a-binary-only-target">How can I fuzz a binary-only target?</summary><p> + + AFL++ is a great fuzzer if you have the source code available. + + However, if there is only the binary program and no source code available, + then the standard non-instrumented mode is not effective. + + To learn how these binaries can be fuzzed, read + [fuzzing_binary-only_targets.md](fuzzing_binary-only_targets.md). +</p></details> + +<details> + <summary id="how-can-i-fuzz-a-network-service">How can I fuzz a network service?</summary><p> + + The short answer is - you cannot, at least not "out of the box". + + For more information on fuzzing network services, see + [best_practices.md#fuzzing-a-network-service](best_practices.md#fuzzing-a-network-service). +</p></details> + +<details> + <summary id="how-can-i-fuzz-a-gui-program">How can I fuzz a GUI program?</summary><p> + + Not all GUI programs are suitable for fuzzing. If the GUI program can read the + fuzz data from a file without needing any user interaction, then it would be + suitable for fuzzing. + + For more information on fuzzing GUI programs, see + [best_practices.md#fuzzing-a-gui-program](best_practices.md#fuzzing-a-gui-program). +</p></details> + +## Performance + +<details> + <summary id="how-can-i-improve-the-fuzzing-speed">How can I improve the fuzzing speed?</summary><p> + + There are a few things you can do to improve the fuzzing speed, see + [best_practices.md#improving-speed](best_practices.md#improving-speed). +</p></details> + +<details> + <summary id="why-is-my-stability-below-100percent">Why is my stability below 100%?</summary><p> + + Stability is measured by how many percent of the edges in the target are + "stable". Sending the same input again and again should take the exact same + path through the target every time. If that is the case, the stability is + 100%. + + If, however, randomness happens, e.g., a thread reading other external data, + reaction to timing, etc., then in some of the re-executions with the same data + the edge coverage result will be different across runs. Those edges that + change are then flagged "unstable". + + The more "unstable" edges, the more difficult for AFL++ to identify valid new + paths. + + A value above 90% is usually fine and a value above 80% is also still ok, and + even a value above 20% can still result in successful finds of bugs. However, + it is recommended that for values below 90% or 80% you should take + countermeasures to improve stability. + + For more information on stability and how to improve the stability value, see + [best_practices.md#improving-stability](best_practices.md#improving-stability). +</p></details> + +## Troubleshooting + +<details> + <summary id="i-got-a-weird-compile-error-from-clang">I got a weird compile error from clang.</summary><p> + + If you see this kind of error when trying to instrument a target with + afl-cc/afl-clang-fast/afl-clang-lto: + + ``` + /prg/tmp/llvm-project/build/bin/clang-13: symbol lookup error: /usr/local/bin/../lib/afl//cmplog-instructions-pass.so: undefined symbol: _ZNK4llvm8TypeSizecvmEv + clang-13: error: unable to execute command: No such file or directory + clang-13: error: clang frontend command failed due to signal (use -v to see invocation) + clang version 13.0.0 (https://github.com/llvm/llvm-project 1d7cf550721c51030144f3cd295c5789d51c4aad) + Target: x86_64-unknown-linux-gnu + Thread model: posix + InstalledDir: /prg/tmp/llvm-project/build/bin + clang-13: note: diagnostic msg: + ******************** + ``` + + Then this means that your OS updated the clang installation from an upgrade + package and because of that the AFL++ llvm plugins do not match anymore. + + Solution: `git pull ; make clean install` of AFL++. +</p></details> \ No newline at end of file |