本文档旨在简要解释 Choronzon 背后的理论。此外,它还提供了关于其内部机制以及如何扩展 Choronzon 以满足新需求的详细信息。Choronzon 架构的概述最初在 ZeroNights 2015 会议 上提出。该演讲的录像和幻灯片也已提供。
Choronzon 是一种进化模糊测试工具。它试图模仿进化过程,以持续产生更好的结果。为此,它配备了一套评估系统,用于判断哪些被模糊处理过的文件是有趣的,哪些应该被丢弃。
此外,Choronzon 是一种基于知识的模糊测试工具。它利用用户定义的信息来读写目标文件格式的文件。为了熟悉 Choronzon 的术语,您应该认为每个文件都表示为一个 染色体(chromosome)。用户需要描述所考虑文件格式的基本结构。更倾向于对文件格式进行高层概述,而不是描述每一个细节和方面。每个用户定义的基本结构被称为一个 基因(gene)。每个染色体包含一个基因树,并能够根据该树构建相应的文件。
Choronzon 分为三个子系统:追踪器(Tracer) 模块、染色体(Chromosome) 模块和模糊测试器。
简单来说,染色体 组件用于描述目标文件格式。用户可以编写自己的模块来支持新的或自定义的格式。作为一个测试案例,Choronzon 提供了一个 PNG 模块。
另一方面,追踪器 组件负责监控目标应用程序并收集其执行过程中的各种信息。此版本的 Choronzon 使用 Intel 的 Pin 二进制插桩工具来记录执行期间访问过的基本块。然而,Choronzon 也支持其他追踪后端。请注意,在 Choronzon 的下一个版本中,由于 Pin 对性能的巨大影响,它将被替换。
最后,模糊测试器组件用于修改待测试文件的内容。该模块包含一组 变异器(Mutators) 和 重组器(Recombinators)。变异器 简单地像常见模糊测试工具那样修改文件。例如,它们执行字节翻转、字节交换、随机字节变异等操作。但 Choronzon 还有一个不常见的特性:重组器 利用由 染色体 模块提供的文件格式结构信息来进行智能模糊测试。
在 chromosome/parsers 目录中,您可以找到 PNG.py 文件。这个 Python 模块向模糊测试器描述了 PNG 文件格式。您可以在此目录中添加其他文件格式的自定义模块。
染色体 子系统的基本思想是使用 反序列化器(Deserializer) 将初始种子文件转换为 基因 树。在某个时刻,(被模糊处理过的)基因 会通过 序列化器(Serializer) 写入文件。
请注意,在 Choronzon 中,解析器模块的目标是提供文件格式的基本结构,而不是每一个微小细节。这将帮助模糊测试器构造出大致合理的文件,避免目标应用程序过早退出。此外,这种方法节省时间,因为描述文件格式的每一个方面既耗时又带来显著的开发开销。
一个新的解析器模块必须导入:
并且必须实现:
在 Choronzon 附带的示例中,每个 PNGGene 对应一个 PNG 块。通常,您可以将 Gene 视为目标格式的基本数据结构。每个 染色体 由一个 基因 树组成,代表一个独特的文件。每个 Gene 必须能够生成一个字节串,其中包含其自身数据以及树中较低级别 Gene 的数据。
当给定一个 基因 列表时,PNGSerializer 必须能够生成(大致合理的)文件。另一方面,PNGDeserializer 必须能够解析一个有效的目标格式文件,并将其反序列化为 基因 树。
请查看 chromosome/parsers/PNG.py,其中包含一个 PNG 格式的注释示例。
追踪器 模块用于反汇编目标应用程序(和/或其一个或多个库)。在此版本的 Choronzon 中,这是通过 IDA 实现的。我们采用这种方法是因为我们可以将模糊测试活动中任何有趣的信息与我们的 IDB 关联起来。然而,我们可能在不远的将来放弃对 IDA 的依赖,以使 Choronzon 更具可移植性和易用性。
文件借助 Pin 工具在应用程序上进行测试。在 analyzer/coverage 目录中,有该 Pin 工具的源代码,它在目标应用程序的每个基本块开头插入钩子。当执行完成时,我们将被命中的基本块与二进制文件中的基本块进行关联。这样,我们就能计算出对我们有价值的指标(如覆盖率等)。
模糊测试器 组件使用 染色体 表示来模糊处理文件。如前所述,Choronzon 有两种模糊测试方法。
对于第一种方法,Choronzon 从一个或多个基因中获取内容,并应用其中一个 变异器。变异器 实现了常见但有效的模糊测试方法,如随机字节变异、高位设置、字节交换等等。您也可以编写自己的自定义变异器,并将其添加到 fuzzers/mutators.py 中。
第二种模糊测试方法称为重组。重组器 用于更改文件的结构。以下是一个 PNG 格式的示例。
PNG 文件由连续的块组成,每个块包含四个字段:
假设我们有一个只有 IHDR、IDAT 和 IEND 块的 PNG 文件。其结构如下所示:
[ PNG 签名 ] [ IHDR ] [ IDAT ] [ IEND ]
由于 Choronzon 了解这些基本结构(即 PNG 块),它能够改变它们的顺序。成功重组后,模糊处理后的 PNG 输出文件可能如下所示:
[ PNG 签名 ] [ IDAT ] [ IHDR ] [ IEND ]
Choronzon 包含更多重组策略,使其能够应对甚至复杂的文件格式。
Choronzon 已在 Python 2.7、Pin 3、IDA Pro 6.6 至 6.9、Ubuntu 16.04 LTS(Linux 内核 4.4)和 Windows 10 上测试通过。
要运行它,您需要安装 sortedcontainers Python 包。您可以在此处找到它(链接)或通过 pip 安装。
此外,Choronzon 需要 IDA Pro(实际上是其终端版本)。IDA Pro 的路径应在您的配置文件中指定,如下所示:
DisassemblerPath = 'C:\\Program Files (x86)\\IDA 6.6'
它已成功在 IDA Pro 6.6、6.7、6.8 和 6.9 上测试。
Choronzon 的覆盖率 Pin 工具位于 analyzer/coverage 目录,需要编译。您可以查看 Pin 的文档以获取详细信息,或者执行以下步骤:
coverage.cpp 和 makefile.rules 文件复制到 /path/to/pin/source/tools/MyPinToolmake。如果您使用 Windows,则应运行 Visual Studio 命令行,并通过 Cygwin 使用 make 工具及其依赖项。obj-intel64 目录(对于 32 位系统则为 obj-ia32)复制回 /path/to/choronzon/analysis/coverage要使用 Choronzon 进行模糊测试,您必须提供一个配置文件。在 settings 目录中有一个 Choronzon 配置的示例。