DeepState 现已支持集成式模糊测试 - Trail of Bits 博客
Alan Cao, 纽约皇后区弗朗西斯·刘易斯高中
2019年9月3日
fuzzing, internship-projects
我们自豪地宣布将集成式模糊测试(ensemble fuzzing)整合到DeepState中——这是一个基于模糊测试与符号执行的单元测试框架。集成式模糊测试允许测试人员在单个测试活动中执行具有不同启发式策略的多个模糊器,同时保持跨模糊器队列同步生成输入种子的架构。
这个全新的集成式模糊器包含新的 deepstate-ensembler 工具,以及通过全新开源的 DeepState 前端 API/SDK 驱动的多个知名模糊器引擎。该 SDK 使开发人员能够为 DeepState 集成前端执行器,并为我们的集成器工具提供种子同步支持。
智能模糊器的谬误
模糊器是安全研究人员工具箱中最有效的工具之一。近年来,为了构建更好的启发式方法(即模糊器用于探索程序的策略),它们得到了广泛研究。然而有一点始终明确:模糊器启发式方法很少能达到其宣传的效果。当将所谓的智能模糊器扩展到真实世界程序时,其性能往往不尽如人意,最终我们不得不回退到如 AFL 和 LibFuzzer 这样的“傻瓜式”标准工具。
既然我们过去已经探讨过评估模糊测试研究的主题,现在让我们换个角度,探索在不牺牲测试工作流程时间的前提下,结合各种模糊器启发式方法以最大化模糊器性能的可能性。这便促成了我夏季实习项目——将集成式模糊测试整合到 DeepState 中。
什么是集成式模糊测试?
集成式模糊测试的洞见在于:虽然某些启发式方法在特定情境下表现良好,但将它们组合起来应能产生比单一策略的单个模糊器更好的结果。这一想法最初由 Chen 等人的 EnFuzz 论文提出,但目前尚无开源或商业实现。
我们的集成式模糊器实现遵循 EnFuzz 中实施的架构,如下图所示:
给定一组预定的多样化基础模糊器(各自具有本地种子队列),我们可以集成一个全局异步-本地同步(GALS)的种子同步机制,该机制在执行周期内将有趣的种子从本地队列拉取到共享的全局队列。因此,当基础模糊器的启发式方法无法提高覆盖率或发现有趣的输入种子时,它可以在下一个执行周期中从全局队列拉取其他模糊器的种子。此外,一旦测试活动终止,我们可以从集成器接收关于基础模糊器性能、崩溃分类/去重或任何其他后处理统计信息的模糊测试反馈。
通过使用集成式模糊测试和我们原本就强大的支持模糊测试/符号执行的单元测试框架 DeepState,我们能够在测试过程中解决以下问题:
- 模糊器性能多样性——不同的模糊器启发式方法是否会贡献不同的有用种子,从而最大化提高覆盖率和发现崩溃的潜力?
- 模糊器工作流程——我们如何在简化工作流程的同时进行详尽的模糊测试和/或符号执行?
- 不变性一致性——不同的模糊器是否会返回不同的结果,表明我们的测试中可能存在非确定性来源?
启动前端
由于 DeepState 已支持 Eclipser 作为后端,我们选择首先构建一个前端 API,开发人员可以为此编写模糊器后端的前端包装器。这可以协调运行的模糊器进程,并执行编译时插桩、前后处理以及种子同步。它还通过统一工具构建方式同时实现功能,简化了模糊测试环境设置。
以下代码片段展示了 AFL 前端包装器的示例。它继承自基础 DeepStateFrontend 类,并包含定义模糊器相关功能的方法。
|
|
为了构建前端包装器,我们的模糊器对象应包含以下方法:
每个模糊器都有自己的集成方法,提供专门的 rsync 调用来从全局和本地队列目录推送和拉取种子:
|
|
构建完成后,我们可以这样使用前端包装器:
|
|
有关模糊器前端 API 及如何实现自己的前端的更详细说明,请参阅本教程。DeepState 目前已有适用于 AFL、libFuzzer、Angora、Eclipser 和 Honggfuzz 的前端执行器。
构建集成器
使用统一的 API,我们现在可以构建一个集成式模糊器,它能够配置前端对象并并发执行模糊器,同时保持种子同步。
首先,获取一个 DeepState 测试工具输入,并通过每个前端对象暴露的 compile() 调用,“集成编译”多个插桩二进制文件到工作区目录。
|
|
完成后,每个并行模糊器进程通过 run() 实例化。由于每个前端包装器通过 ensemble() 调用 rsync 风格的同步,集成器只需在指定的同步周期(以秒为单位)后从每个前端调用它来同步种子。
这个实现出奇地简单,仅用约 300 行 Python 代码构建。以下是在我们的测试示例之一 Crash.cpp 上运行集成器的快速演示。
全面模糊测试!
受 Google 的 fuzzer-test-suite 和前述模糊器性能测试工作的启发,我们决定一个由 DeepState 驱动的测试套件 deepstate-test-suite 可以帮助进行模糊器性能 A/B 测试和实际的漏洞挖掘。借助我们易于使用的模糊器和集成器,让我们评估它们在真实测试案例基准上的表现!
大数(Bignum)漏洞是一类特别有趣的错误,因为边缘情况更难发现,甚至具有概率性。这使它们成为 DeepState 属性测试的理想目标。
我们为基础模糊器和集成器模糊器设定了基准,测试它们在重现现有测试案例和真实世界大数漏洞(TweetNaCl 中的进位传播错误)方面的性能。遵循这篇模糊测试评估论文中的评估方法,使用来自良好初始输入的 10 个崩溃实例测量每个测试案例的平均时间:
这些结果提供了关于模糊器多样性的一些有趣见解。在较小范围的测试案例(如 Runlen 示例)上运行更智能的模糊器(如 Angora 和 Eclipser)效果良好。然而,当扩展到真实世界软件中的实际漏洞发现场景(如 TweetNaCl 错误)时,它们的性能下降。集成式模糊器的性能表明它能够很好地扩展以适应这两种测试案例。
集成式模糊测试的未来是什么?
集成式模糊测试是一种强大的技术,可扩展到真实世界的软件库和程序。将集成式模糊器集成到 DeepState 中,通过简化的工作流程增强了单元测试能力,并为许多其他研究和工程工作开辟了可能性。
根据我们当前的基准测试结果,我们不能明确说集成式模糊测试是最佳模糊测试策略,但值得注意的是,在评估模糊器时总是存在随机性和概率行为的元素。有效的集成式模糊测试可能依赖于基础模糊器的选择——根据分析的目标类型或错误类别来确定调用哪些模糊器以及何时调用。
也许我们当前的模糊器集成在重现大数漏洞方面有效,但它们在其他类型的错误上也能同样有效吗?如果我们以特定顺序调用模糊器,是否会更加有效?这些问题可以通过对不同目标进行更多基准测试来更准确地回答。
致谢!
作为 Trail of Bits 的安全工程实习生,这始终是一次美妙的经历。与优秀的员工和实习生一起工作极大地推动了我对安全研究的理解,以及我们如何将有见地的学术研究转化为可工作的软件实现,就像我之前使用 Manticore 分析密码学原语的工作一样。我特别兴奋能在纽约大学继续这项工作,我将在春季开始学习!
如果您喜欢这篇文章,请分享:
Twitter、LinkedIn、GitHub、Mastodon、Hacker News