写在前面的话
定向灰盒模糊测试(DGF)类似AFLGo,旨在对预先选择的潜在易受攻击的目标位置执行压力测试,应用于不同的安全场景:(1)漏洞复现;(2)补丁测试;(3)静态分析报告验证;近期,研究人员也做了很多工作,有效地提高了定向模糊测试的有效性和效率。
为此,我们开发出了UAFuzz,它是一个在二进制代码级别上专门针对用后释放漏洞(UAF)的定向模糊测试工具。该工具可以通过仔细调整定向模糊测试的关键组件来满足这个类型漏洞的特定特性。在释放堆元素之后,如果再次使用堆元素时便会触发用后释放漏洞。大家都知道,检测UAF漏洞是比较困难且复杂的,因为PoC输入需要在同一内存位置触发三个事件序列(分配、释放和使用),这里涉及到目标程序的多个功能。
总体而言,UAFuzz的工作流与定向模糊测试工具相似,并且对模糊测试过程的相关数据进行了高亮处理,以橙色高亮显示。该工具能够对所有与内存相关的UAF事件进行完整的堆栈跟踪。与现有的可独立选择目标的一般定向方法不同,我们考虑了目标之间的关系来提高方向性。首先,UAFuzz的静态预计算在二进制级别上很快。其次,我们引入了新的排序感知输入指标,以引导模糊测试器在运行时朝着正确的方向走下去。最后,我们只对覆盖预期跟踪中所有目标的潜在输入进行分类,并对不太可能触发漏洞的输入进行预过滤。
工具安装
首先,我们需要在本地主机上安装好IDA Pro v6.9(32位)和Python v2.7,之后我们还会添加针对更多开源代码反汇编工具的支持,比如说Radare等等。
除此之外,我们还需要使用Graph-Easy v0.7.6来转换IDA的调用图。
在本地主机安装Valgrind分析工具、二进制源码分析框架BINSEC和基于覆盖引导的灰盒模糊测试工具AFL v2.52b。
我们的工具测试环境为Ubuntu 16.04(64位),安装配置代码如下:
# Install Ocaml and prerequisite packages for BINSEC via OPAM sudo apt update sudo apt install ocaml ocaml-native-compilers camlp4-extra opam opam init opam switch 4.05.0 opam install merlin ocp-indent caml-mode tuareg menhir ocamlgraph ocamlfind piqi zmq.5.0.0 zarith llvm.6.0.0 # Install Python's packages sudo pip install networkx pydot # Checkout source code git clone https://github.com/strongcourage/uafuzz.git # Environment variables export IDA_PATH = /path/to/ida-6.9/idaq export GRAPH_EASY_PATH=/path/to/graph-easy cd uafuzz; export UAFUZZ_PATH=`pwd` # Compile source code ./scripts/build.sh uafuzz # Help for IDA/UAFuzz interface ./binsec/src/binsec -ida-help ./binsec/src/binsec -uafuzz-help
代码结构
我们的模糊测试工具基于QEMU模式的AFL v2.52b实现,以实现针对轻量级静态分析的模糊测试。我们当前使用IDA Pro v6.9来提取目标代码的控制流图以及调用图。
uafuzz ├── binsec/src │ └── ida: a plugin to import and process IDA's CFGs and call graph │ └── uafuzz: fuzzing code │ │ └── afl-2.52b: core fuzzing built on top of AFL-QEMU │ │ └── uafuzz_*.ml(i): a plugin to compute static information and communicate with AFL-QEMU └── scripts: some scripts for building and bug triaging
应用场景一:漏洞复现
我们先用一个简单的UAF漏洞举个例子。针对这个漏洞,无论是AFL-QEMU,甚至是带有源代码级目标的定向模糊测试工具AFLGo都无法在6小时内检测到它,而UAFuzz可以在Valgrind的帮助下在几分钟内检测到它。
# Run AFL-QEMU $UAFUZZ_PATH/tests/example.sh aflqemu 360 # Run AFLGo given targets at source-level $UAFUZZ_PATH/tests/example.sh aflgo 360 # Run UAFuzz $UAFUZZ_PATH/tests/example.sh uafuzz 360 $UAFUZZ_PATH/tests/example/example.valgrind
对于真实场景,我们还需要使用UAF模糊化基准进行评估。
# Checkout the benchmark git clone https://github.com/strongcourage/uafbench.git cd uafbench; export UAFBENCH_PATH=`pwd`
Valgrind获得的这个UAF 漏洞的堆栈跟踪如下:
// stack trace for the bad Use ==5358== Invalid read of size 1 ==5358== at 0x40A9393: vfprintf (vfprintf.c:1632) ==5358== by 0x40A9680: buffered_vfprintf (vfprintf.c:2320) ==5358== by 0x40A72E0: vfprintf (vfprintf.c:1293) [6] ==5358== by 0x80AB881: error (elfcomm.c:43) [5] ==5358== by 0x8086217: process_archive (readelf.c:19409) [1] ==5358== by 0x80868EA: process_file (readelf.c:19588) [0] ==5358== by 0x8086B01: main (readelf.c:19664) // stack trace for the Free ==5358== Address 0x4221dc0 is 0 bytes inside a block of size 80 free'd ==5358== at 0x402D358: free (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) [4] ==5358== by 0x8086647: process_archive (readelf.c:19524) [1] ==5358== by 0x80868EA: process_file (readelf.c:19588) [0] ==5358== by 0x8086B01: main (readelf.c:19664) // stack trace for the Alloc ==5358== Block was alloc'd at ==5358== at 0x402C17C: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) [3] ==5358== by 0x80AD97E: make_qualified_name (elfcomm.c:906) [2] ==5358== by 0x8086350: process_archive (readelf.c:19435) [1] ==5358== by 0x80868EA: process_file (readelf.c:19588) [0] ==5358== by 0x8086B01: main (readelf.c:19664)
应用场景二:补丁测试
我们使用GNU补丁的CVE-2018-6952来说明产生不同漏洞触发输入以支持漏洞修复过程的重要性。这个GNU补丁中存在一个双重释放漏洞,不过开发人员已经在9c98635中修复了该漏洞。但是,通过使用CVE-2018-6952的堆栈跟踪,UAFuzz发现了最新版本2.7.6(commit 76e7758)中仍然存在问题。总的来说,我们使用现有缺陷的PoC输入和模糊语料库中的有效文件作为高质量的种子。
# Fuzz patched version of CVE-2018-6952 $UAFBENCH_PATH/CVE-2019-20633.sh uafuzz 360 $UAFBENCH_PATH/valgrind/CVE-2018-6952.valgrind
应用场景三:静态分析报告验证
一种可能的混合方法是将UAFuzz与GUEB相结合,GUEB是唯一使用Ocaml并针对UAF漏洞编写的二进制级静态分析器。然而,GUEB会产生许多误报,并且目前无法正确处理复杂的二进制文件。因此,我们目前对GUEB进行改进,并将其整合到BINSEC中,然后使用GUEB报告中提取的目标来指导UAFuzz。
项目地址
UAFuzz:【GitHub传送门】
参考资料
https://github.com/strongcourage/uafuzz/blob/master/raid20-final286.pdf
https://github.com/strongcourage/uafuzz/blob/master/scripts/preprocess.py
https://github.com/strongcourage/uafbench/blob/master/CVE-2018-20623.sh
https://savannah.gnu.org/bugs/index.php?53133
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-20633
https://github.com/strongcourage/fuzzing-corpus
https://github.com/montyly/gueb
https://github.com/strongcourage/uafbench
https://sourceware.org/bugzilla/show_bug.cgi?id=24049
https://github.com/strongcourage/uafuzz/blob/master/binsec/src/uafuzz/README.md