L1E6N0A2

监督自己不断学习

0%

每日一题3-2

模糊测试结合符号执行

概述

模糊测试与符号执行作为两大主流测试技术已被广泛研究并应用到学术界与工业界中,这两种技术都具有一定的优缺点:模糊测试随机变异生成测试用例并动态执行程序,可以执行并覆盖到较深的分支,但其很难通过变异的方法生成覆盖到复杂条件分支的测试用例;而符号执行依赖约束求解器,可以生成覆盖复杂条件分支的测试用例,但在符号化执行过程中往往会出现状态爆炸问题,因此很难覆盖到较深的分支。分析符号执行与模糊测试的优缺点,提出了一种基于分支覆盖将两种方法结合的混合测试方法,结合双方优点从而可以生成具有更高分支覆盖率的测试用例。具体来说,模糊测试(例如AFL)为程序快速生成大量可以覆盖较深分支的测试用例,符号执行(例如Angr)基于模糊测试的覆盖信息进行搜索,当模糊测试处于低速或阻塞状态,则调用符号分析程序以生成新输入,这可以帮助模糊测试遍历未遍历的分支,为未覆盖到的分支生成测试用例。

Driller为CTF团队开发,结合了AFL和该团队的符号执行工具Angr。Driller在AFL的基础上加入了动态符号执行引擎,当模糊测试发生stuck时,使用动态符号执行去突破这些限制,生成满足fuzz需求的新输入,使得fuzz能够继续执行。Driller结合了AFL的高效、低消耗、快速的优点和动态符号执行探索能力强的优点,又避免了AFL较难突破特殊的边界和动态符号执行路径爆炸的问题。

基本原理

我们使用AFL模糊测试器作为符号辅助Fuzzing的基础,并使用angr作为它的符号执行工具。通过监测AFL的执行,我们能够决定什么时候开始符号执行AFL产生的输入。为了做出这个决定,我们按照模糊器发现新状态转换的速率采取行动。如果AFL报告说,在执行了一轮输入变化后没有发现新的状态转换,我们假设模糊器难以取得进展,并且在AFL被认为是唯一的所有路径上引用angr,寻找AFL无法找到输入的转换。
Driller的符号组件是通过使用angr的符号执行引擎来实现的,以便根据AFL提供的具体输入来符号性地追踪路径。这避免了符号执行固有的路径爆炸问题,因为每个具体输入对应于单个(追踪)路径,并且这些输入经AFL严格过滤以确保仅追踪有希望的输入。每个具体输入对应于PathGroup中的单个路径。 在PathGroup的每一步中,检查每个分支以确保最新的跳转指令引入先前AFL未知的路径。 当发现这样的跳转时,SMT求解器被查询以创建一个输入来驱动执行到新的跳转。这个输入反馈给AFL,AFL在未来的模糊步骤中进行变异。 这个反馈循环使我们能够将昂贵的符号执行时间与廉价的模糊时间进行平衡,并且减轻了模糊对程序操作的低语义洞察力。

安装

driller工具是由Python语言写的,主要依赖于angr,afl等2个工具。我们可以通过shellphfuzz工具来使用driller,使用方式如下,“-i”选项指定afl-fuzz的线程数,“-d”选项指定driller(即符号执行工具)的线程数,如果不使用-d或者-d 0,则不使用符号执行。

1
2
3
4
5
# fuzz with 4 AFL cores
shellphuzz -i -c 4 /path/to/binary

# perform symbolic-assisted fuzzing with 4 AFL cores and 2 symbolic tracing (drilling) cores.
shellphuzz -i -c 4 -d 2 /path/to/binary