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.