AFL++: Combining Incremental Steps of Fuzzing Research

摘要

在本文中,我们介绍了AFL++,一个社区驱动的开源工具,它结合了最先进的模糊研究,使研究具有可比性,可重复性,可组合性,最重要的是可用性。它提供了各种新颖的功能,例如它的Custom Mutator API,能够在许多阶段扩展模糊过程。有了它,经验丰富的安全测试人员也可以编写针对特定目标的突变。我们希望AFL++不仅能成为当前研究的新基准工具,也能成为未来研究的新基准工具,因为它可以快速测试新技术,不仅可以评估单一技术与最新技术的有效性,还可以与其他技术相结合。本文对精挑细选的模糊测试技术进行了评价,指出虽然每种新的模糊测试方法都能提高某些目标的性能,但却会降低其他目标的性能。这是未来模糊研究在评估时应该考虑的一个问题。

这里的Custom Mutator可以用来用户根据特定的需求和场景编写自己的变异器。

自定义 Mutator |AFL++

1 介绍

在2016年发表的论文(State of) The Art of War: Offensive Techniques in Binary Analysis中提到用符号辅助fuzz所识别的漏洞产出是符号执行的三倍。在本文中,我们试图通过提高广泛可用性、研究支持、模糊测试的标准,以及为研究人员提供可扩展的API来解决这些问题,即AFL++。AFL++以AFL为基础,这是因为AFL的长时间没有维护,但却仍有很多可用补丁。而不是正在维护中的两种fuzz:Libfuzzer和Honggfuzz。同时文章还提到了与AFL研究路线不同的fuzz:Redqueen。AFL++应该广泛吸收不同的特点。

对于Redqueen指出了AFL的两个基本问题,一个是文件格式的问题,测试输入缺乏正确的魔数,目标程序可能会拒绝处理该输入;另一个是校验问题,如果测试输入中的校验和或哈希值不正确,目标程序可能会拒绝处理该输入,导致模糊测试无法进行。

跟着白泽读论文丨REDQUEEN: Fuzzing with Input-to-State* - 知乎 (zhihu.com)

目标:

  1. 我们提出afl++,将最近的模糊研究纳入一个可用的工具。

  2. 我们讨论了afl++新颖的自定义Mutator API,这是一种可接近的、面向未来的实现方式,并结合了未来的研究。

  3. 使用afl++,我们评估了一系列合并的技术和特性,以及它们之间的相互作用。

AFL++源码

2 AFL和一些它的改进

2.1 AFL

AFL是以覆盖率为导向的fuzz,在测试过程中应该尽可能的提高代码的覆盖率,它以块为单位,边做分支,保存路径到一个共享图中。对于AFL的突变包括翻转,加减,替换,甚至是无规律的增删改插等等。AFL还使用了forkserver用来减少程序开销,对于持久化测试还会patch文件来提高性能。

2.2 智能调度

调度器的目标通常是通过智能的测试用例选择来提高总体覆盖率和bug检测。

对于AFLfast来说,强调了两个问题:

​ 1.为了走低频路径,fuzzer应该以什么顺序挑选种子 (一套新的搜索策略)

​ 2.调整每颗种子得输入量。(引入6种功率调度,在fuzz中收集参数中的计算能量。)

对于MOPT来说,强调了种子调度的横向问题,引入了突变调度,使用自定义粒子群优化算法为突变算子提供不同概率的可能性。这种优化提高了模糊器快速发现覆盖范围的能力。

1
2
摘要:
基于变异的模糊测试是目前最流行的漏洞发现方法之一。其生成有趣测试用例的性能很大程度上取决于变异调度策略。然而,现有的模糊测试通常遵循一个特定的(例如,统一的)分布来选择变异算子,这在寻找通用程序上的漏洞方面效率很低。因此,本文提出了一种新的突变调度方案MOPT,使基于突变的模糊测试更有效地发现漏洞。MOPT采用一种定制的粒子群优化算法(PSO),从模糊有效性的角度寻找算子的最优选择概率分布,并提供一种引领模糊测试模式,以加快PSO的收敛速度。我们将MOPT应用于最先进的模糊测试工具AFL、AFLFAST和Vuzzer,分别实现了MOPT-AFL、-AFLFAST和-Vuzzer,并在13个真实的开源程序上进行了评估。结果表明,MOPT-AFL发现的安全漏洞比AFL多170%,崩溃率比AFL高350%。MOPT AFLFAST和MOPT Vuzzer的表现也优于其对手。此外,广泛的评价也表明,MOPT具有良好的合理性、兼容性和稳定性,同时引入了可忽略不计的成本。

2.3 一些障碍

传统上,覆盖引导的模糊测试会受到阻碍,无法探索其背后的代码。典型的障碍是较大的比较,如字符串和校验和检查。和上文中提到的Redqueen说法类似。

对于LAF-Intel来说,多字节的比较工作,常常拆分为单字节比较,具体来说:

  1. 将>=(和<=)操作符简化为>(<)和==比较链;
  2. 将有符号整数比较改为有符号比较和无符号比较链;
  3. 将所有位宽为64、32或16位的无符号整数比较拆分为8位的多个比较链;

对于Readqueen来说,上文已经指出解决的两个基本问题。这个模糊器主要关注定义为“输入到状态”(input - to - state, I2S)的比较,这是一种直接依赖于至少一个操作数的输入的比较。作者表明,许多障碍比较都是这种类型的,并开发了一种技术来定位和绕过它们。REDQUEEN首先在其着色阶段增加输入的熵,用随机数据替换字节,同时保持测试用例的覆盖率。通过这种方式,观察I2S比较的操作数,模糊器可以减少猜测的次数,以确定其在输入中的位置。然后,REDQUEEN改变输入,替换从比较中提取的I2S令牌,并再次使用该信息来定位校验和检查并将其修补。在每个模糊测试阶段结束时,REDQUEEN再次使用I2S替换来修复新生成的有趣输入的校验和。如果失败,则检测到补丁的校验和为误报,补丁被删除。

2.4改变结构化输入

fuzzer的一个常见问题是,它们可能生成大部分无效的输入,使解析阶段后的程序状态无法访问。

对于AFLSmart来说,灰盒测试是基于程序运行时刻的外部表现同时又结合程序内部逻辑结构来设计用例,执行程序并采集程序路径执行信息和外部用户接口结果的测试技术。具有结果反馈功能的模糊测试即属于灰盒 fuzz,如 AFL,会对待测程序进行插装,从而监控每个输入的路径覆盖率,为下一次选择输入文件进行变异提供依据。smart fuzz 是面向具有高度结构化输入(如,PPT,mp3,PDF 等)的程序进行测试的一类模糊测试工具,典型的 smart fuzz 工具如 Peach。使用 Peach 的关键在于名为「Peach Pit」的 xml 配置文件。「Peach Pit」主要包含了文件的数据信息。AFLSmart 在 AFL 的基础上,参照了 Peach 的 File Cracker 组件,将文件按 chunk 划分,抽象为一个可以用 xml 文件描述的树形的结构。

3 AFL++

3.1 种子调度

AFL++这部分结合的是AFLFast的超强调度算法,调度形式包括 fast, coe, explore, quad, lin, exploit,这些调度对应的是以下参数的功能:

  1. 从队列中选择种子的次数;
  2. 种子覆盖率相同生成的输入的数量;
  3. 相同覆盖率下的生成测试用例平均数;

默认的调度算法是exploit,AFL++在这些调度方案的基础上又添加了mmopt和rare方案。Mmopt 调度增加了最新的种子用例的分数,以深入研究新发现的路径;Rare 调度忽略了种子的运行时间,并且另外将重点放在边缘很少被其他种子用例执行后覆盖的种子上

3.2 突变

这里引入了Custom Mutator API,来支持自定义的突变操作。自定义mutator允许模糊研究在afl++之上构建新的调度、突变和最小化,而不需要像许多当前工具那样对AFL进行分支和修补。这里有很多API操作,需要在实际项目修改fuzz中慢慢学习。

对于输入状态到I2s的替换,还是基于Readqueen来实现,同时还对此进行了一些优化,比如扩展了着色方面,增加执行速度以及提高有效的概率模糊化。这个mutator不像在最初的REDQUEEN实现中那样使用断点记录比较操作数,而是使用一个类似于WEIZZ中使用的共享表。

实现了Mopt的core个pilot模式。

3.3 插桩

AFL++支持LLVM,GCC,QEMU,Unicorn,QBDI的插桩。

引入NeverZero 和Saturated Counters优化技术。前者解决 AFL 在处理具有全零字节的输入时可能出现的性能问题,避免无限循环。后者处理 AFL 在测试过程中覆盖率计数器溢出的问题,提高准确度。

在小节中,AFL++详细描述了这些模式的处理细节,这些细节在使用和查看源码后再具体分析。

3.4 模式支持

可以支持GNU/Linux, Android、iOS、macOS、FreeBSD、OpenBSD、NetBSD。

打包在流行版本Debian、Ubuntu、NixOS、Arch Linux、FreeBSD、Kali Linux。

3.5 内核模块快照技术

基于fork()的AFL状态恢复机制对于大量目标来说是一个性能瓶颈,基于Perffuzz实现了内核状态快照,在单核中的平均性能高于fork的2倍。

4 评估

作为一款优秀的终极缝合怪,如何把优秀的fuzz结合好是一个关键的步骤。文中选择了9个案例,和6个fuzz组合来测试性能。

image-20240514214000846

5 未来工作

1 多线程扩展不理想。(LKM是第一步工作)

2 对于哈希表的碰撞处理,速度和准确性的平衡。

3 提前的静态分析再fuzz之前

4 插件系统。