About Directed Fuzzing and Use-After-Free: How to Find Complex & Silent Bugs?

Conference:  BlackHat USA 2020



The presentation discusses a reactive fuzzing framework for detecting use-after-free bugs at the binary level, which is more effective and efficient than traditional directed fuzzing. The framework uses a combination of static analysis and dynamic testing to prioritize inputs and identify potential vulnerabilities.
  • The proposed framework combines static analysis and dynamic testing to detect use-after-free bugs at the binary level
  • The framework uses a live weight-cut excave metric to prioritize inputs based on their similarity to the expected target sequence
  • The framework was evaluated on two applications and outperformed state-of-the-art coverage-guided and read-fuzzing techniques
  • The presentation emphasizes the importance of integrating fuzzing into the software development process and developing vulnerability-oriented fuzzing techniques
  • The presentation also highlights the need to find and fix the variance of bug classes
The presentation describes how the framework was able to identify 30 new bugs, four of which were incomplete, and seven CVEs in critical programs. One example of an incomplete fix was found in GNU Pass, which used the block tray of an existing double free. The presentation concludes by emphasizing the practicality and effectiveness of fuzzing in detecting complex bugs and the need for vulnerability-oriented fuzzing techniques.


Fuzzing is a popular and effective automated approach to vulnerability detection. Directed fuzzing focuses on automatically testing specific parts of the code by taking advantage of additional information such as bug stack traces or patches. Key applications include bug reproduction and patch-oriented testing. While very successful, recent fuzzing techniques (directed or not) are not well suited for Use-After-Free vulnerabilities (UAF), where some deallocated memory is reused through a dangling pointer (UAF represent only 1% of issues found by OSS-Fuzz in 2017). This is unfortunate as UAF possibly lead to data corruption, information leaks, or denial of service. Fuzzing UAF is hard for two reasons: (1) UAF bugs are complex – need to find input covering three events (alloc, free, use) in sequence; (2) UAF bugs are silent – they often do not crash immediately. The obvious solution is to pair fuzzing with memory sanitizaters such as Valgrind, however the induced runtime overhead is terrible for fuzzing. We propose UAFuzz, the first (binary-level) directed greybox fuzzer dedicated to UAF bugs. The technique features a fuzzing engine tailored to UAF specifics (adapting standard fuzzing components: seed selection, distance metric and power schedule), a lightweight code instrumentation and an efficient bug triage step allowing to send only a fraction of the generated input to the sanitizer for bug confirmation. Our technique is implemented on top of AFL-QEMU and Valgrind. UAFuzz outperforms state-of-the-art directed fuzzers (AFLGO and Hawkeye) on bug reproduction (detection rate, time-to-exposure). UAFuzz has also been proven effective in patch-oriented testing, leading to the discovery of 30 new bugs, 7 CVEs and 4 buggy patches. Several fuzzing talks have already been given to Black Hat. Our proposal is the first to focus on directed fuzzing and use-after-free.Finally, we will publicly release our UAF fuzzing benchmark and the UAFuzz tool.