使用 afl-fuzz 进行模糊测试

为了正确运行,模糊器需要一个或多个起始文件,其中包含目标应用程序通常期望的输入数据的良好示例。有两个基本规则:

  • 保持文件小。小于 1 kB 是理想的,尽管不是绝对必要的。有关大小为何重要的讨论,请参阅性能提示
  • 仅当它们在功能上彼此不同时才使用多个测试用例。使用 50 张不同的假期照片来模糊图像库是没有意义的。

您可以在此工具附带的 testcases/ 子目录中找到许多很好的启动文件示例。

PS。如果有大量数据可用于筛选,您可能需要使用 afl-cmin 实用程序来识别功能不同的文件的子集,这些文件在目标二进制文件中使用不同的代码路径。

模糊二进制文件

模糊测试过程本身由afl-fuzz实用程序执行。这个程序需要一个带有初始测试用例的只读目录,一个单独的地方来存储它的发现,以及一个要测试的二进制文件的路径。

对于直接从标准输入接受输入的目标二进制文件,通常的语法是:

$ ./afl-fuzz -i testcase_dir -o findings_dir /path/to/program [...params...]

对于从文件中获取输入的程序,使用“@@”在目标命令行中标记输入文件名应放置的位置。fuzzer 会用这个代替你:

$ ./afl-fuzz -i testcase_dir -o findings_dir /path/to/program @@

您还可以使用-f选项将变异数据写入特定文件。如果程序需要特定的文件扩展名左右,这很有用。

可以在 QEMU 模式(在命令行中添加-Q)或传统的盲目模糊器模式(指定-n)中对非检测二进制文件进行模糊测试。

您可以使用-t-m来覆盖执行进程的默认超时和内存限制;可能需要涉及这些设置的目标的罕见示例包括编译器和视频解码器。

性能提示中讨论了优化模糊测试性能的提示

请注意,afl-fuzz 首先执行一系列确定性模糊测试步骤,这可能需要几天时间,但往往会产生整洁的测试用例。如果您想立即获得快速而肮脏的结果 - 类似于 zzuf 和其他传统的模糊器 -在命令行中添加-d选项。

解释输出

有关如何解释显示的统计信息和监控进程运行状况的信息,请参阅了解状态屏幕。请务必查阅本节,尤其是当任何 UI 元素以红色突出显示时。

模糊测试过程将一直持续到您按下 Ctrl-C。至少,您希望 fuzzer 完成一个队列周期,这可能需要几个小时到一周左右的时间。

在输出目录中创建了三个子目录并实时更新:

  • queue/ - 每个独特的执行路径的测试用例,加上所有

    用户给定的起始文件。这是第 2 节中提到的合成语料库。在将此语料库用于任何其他目的之前,您可以使用 afl-cmin 工具将其缩小到更小的尺寸。该工具将找到提供等效边缘覆盖的文件的较小子集。

  • crash/ - 独特的测试用例导致被测程序收到一个

    致命信号(例如,SIGSEGV、SIGILL、SIGABRT)。条目按接收到的信号分组。

  • hangs/ - 导致被测程序超时的独特测试用例。这

    将某事归类为挂起之前的默认时间限制是 1 秒和 -t 参数的值中的较大者。该值可以通过设置 AFL_HANG_TMOUT 进行微调,但这很少需要。

如果相关的执行路径涉及之前记录的故障中未出现的任何状态转换,则崩溃和挂起被认为是“唯一的”。如果可以通过多种方式解决单个错误,则在此过程的早期会出现一些计数膨胀,但这应该会迅速减少。

崩溃和挂起的文件名与父级、非故障队列条目相关。这应该有助于调试。

当您无法重现 afl-fuzz 发现的崩溃时,最可能的原因是您没有设置与该工具使用的相同的内存限制。尝试:

$ LIMIT_MB=50
$ ( ulimit -Sv $[LIMIT_MB << 10]; /path/to/tested_binary ... )

更改LIMIT_MB以匹配传递给 afl-fuzz 的-m参数。在 OpenBSD 上,还将-Sv更改为-Sd

任何现有的输出目录也可用于恢复中止的作业;尝试:

$ ./afl-fuzz -i- -o existing_output_dir [...etc...]

如果您安装了 gnuplot,您还可以使用 afl-plot 为任何活动的模糊测试任务生成一些漂亮的图表。有关其外观的示例,请参阅 [ http: //lcamt​​uf.coredump.cx/afl/plot/](http://lcamt​​uf.coredump.cx/afl/plot/ )。

并行化模糊测试

afl-fuzz 的每个实例大约占用一个核心。这意味着在多核系统上,并行化是充分利用硬件所必需的。有关如何在多核或多台联网机器上对共同目标进行模糊测试的技巧,请参阅并行模糊测试技巧

并行模糊模式还提供了一种将 AFL 连接到其他模糊器、符号或联合执行引擎等的简单方法;再次,请参阅技巧的最后一部分并行模糊测试技巧。

模糊器字典

默认情况下,afl-fuzz 变异引擎针对紧凑的数据格式进行了优化——比如图像、多媒体、压缩数据、正则表达式语法或 shell 脚本。它不太适合那些特别冗长和冗长的语言——尤其是 HTML、SQL 或 JavaScript。

为了避免构建语法感知工具的麻烦,afl-fuzz 提供了一种方法来使用可选的语言关键字字典、魔术头或与目标数据类型相关的其他特殊标记来为 fuzzing 过程播种 - 并使用它来重建随时随地的基础语法:

要使用此功能,您首先需要以 dictionaries/README.dictionaries 中讨论的两种格式之一创建字典;然后通过命令行中的 -x 选项将模糊器指向它。

(该子目录中也已经提供了几个常用字典。)

没有办法提供对底层语法的更结构化的描述,但模糊器可能会仅根据检测反馈找出其中的一些。这实际上在实践中有效,例如:

PS。即使没有给出明确的字典,afl-fuzz 也会通过在确定性字节翻转期间非常密切地观察检测来尝试提取输入语料库中现有的语法标记。这适用于某些类型的解析器和语法,但不如 -x 模式好。

如果字典真的很难获得,另一种选择是让 AFL 运行一段时间,然后使用作为 AFL 配套实用程序提供的令牌捕获库。为此,请参阅 libtokencap/README.tokencap。

崩溃分类

基于覆盖率的崩溃分组通常会产生一个小的数据集,可以手动或使用非常简单的 GDB 或 Valgrind 脚本快速分类。每次崩溃还可以追溯到队列中的父非崩溃测试用例,从而更容易诊断故障。

话虽如此,重要的是要承认,如果没有大量的调试和代码分析工作,一些 fuzzing 崩溃可能难以快速评估可利用性。为了协助完成这项任务,afl-fuzz 支持使用 -C 标志启用的非常独特的“崩溃探索”模式。

在这种模式下,fuzzer 将一个或多个崩溃测试用例作为输入,并使用其反馈驱动的模糊测试策略非常快速地枚举程序中可以到达的所有代码路径,同时保持程序处于崩溃状态。

不会导致崩溃的突变被拒绝;任何不影响执行路径的更改也是如此。

输出是一个小的文件语料库,可以非常快速地检查攻击者对错误地址的控制程度,或者是否有可能通过初始越界读取 - 并查看下面的内容.

哦,还有一件事:为了最小化测试用例,试试 afl-tmin。该工具可以以非常简单的方式操作:

$ ./afl-tmin -i test_case -o minimized_result -- /path/to/program [...]

该工具适用于崩溃和非崩溃测试用例。在崩溃模式下,它将愉快地接受检测和非检测二进制文件。在非崩溃模式下,最小化器依赖于标准 AFL 工具来使文件更简单,而无需更改执行路径。

最小化器以与 afl-fuzz 兼容的方式接受-m-t-f@@语法。

AFL 最近新增的另一个功能是 afl-analyze 工具。它接受一个输入文件,尝试顺序翻转字节,并观察测试程序的行为。然后,它根据哪些部分看起来是关键的,哪些不是,对输入进行颜色编码;虽然不是万无一失的,但它通常可以提供对复杂文件格式的快速洞察。有关其操作的更多信息可以在AFL 如何工作的结尾处找到。

超越崩溃

Fuzzing 也是一种发现非崩溃设计和实现错误的绝妙且未被充分利用的技术。通过修改目标程序以调用 abort() 发现了很多有趣的错误,例如:

  • 当给定相同的模糊器生成的输入时,两个 bignum 库会产生不同的输出,
  • 当要求连续多次解码相同的输入图像时,图像库会产生不同的输出,
  • 当迭代序列化和反序列化模糊器提供的数据时,序列化/反序列化库无法产生稳定的输出,
  • 当要求压缩然后解压缩特定 blob 时,压缩库会产生与输入文件不一致的输出。

实施这些或类似的健全性检查通常需要很少的时间;如果您是特定包的维护者,您可以使用#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION(也与 libfuzzer 共享的标志)或#ifdef __AFL_COMPILER(这仅用于 AFL)使此代码成为条件。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值