uafuzz: Binary-level Directed Fuzzing for Use-After-Free Vulnerabilities
UAFuzz: Binary-level Directed Fuzzing for Use-After-Free Vulnerabilities
Directed Greybox Fuzzing (DGF) like AFLGo aims to perform stress testing on pre-selected potentially vulnerable target locations, with applications to different security contexts: (1) bug reproduction, (2) patch testing or (3) static analysis report verification. There is recently more research work that improved directed fuzzing’s effectiveness and efficiency (see awesome-directed-fuzzing).
We propose UAFuzz which is a directed fuzzer dedicated to Use-After-Free (UAF) bugs at binary-level by carefully tuning the key components of directed fuzzing to meet specific characteristics of this bug class. UAF bugs appear when a heap element is used after having been freed. Detecting UAF bugs is hard: (1) complexity because a Proof-of-Concept (PoC) input needs to trigger a sequence of three events – alloc, free, and use – on the same memory location, spanning multiple functions of the tested program and (2) silence with no segmentation fault.
Overall, UAFuzz has a similar workflow as directed fuzzers with our modifications highlighted in orange along the whole fuzzing process, as shown in the following figure. As we focus on (1) bug reproduction and (2) patch testing applications, it is more likely we have (mostly) complete stack traces of all memory-related UAF events. Unlike existing general directed approaches where targets could be selected independently, we take into account the relationship among targets (e.g., the ordering which is essential for UAFs) to improve the directedness. First, the static precomputation of UAFuzz is fast at the binary level. Second, we introduce new ordering-aware input metrics to guide the fuzzer towards targets at runtime. Finally, we triage only potential inputs covering all targets in the expected trace and pre-filter for free inputs that are less likely to trigger the bug.
More details in our paper at RAID’20 and our talk at Black Hat USA’20. Thanks also to Sébastien Bardin, Matthieu Lemerre, Prof. Roland Groz, and especially Richard Bonichon (@rbonichon) for his help on Ocaml.