介绍一下 fuzz 的流程,从选取目标开始
1. 选取目标
Fuzzing 不是盲目的,你需要选择一个合适的、有价值的目标。好的目标通常具有以下特点:
- 处理复杂或不受信任的输入:比如文件解析器、网络协议栈、命令行参数处理程序。这些程序是攻击者的首要目标,因为它们直接暴露在外部输入之下
- 高权限运行:如果一个程序以
root
或SYSTEM
权限运行,它将是更具吸引力的攻击目标 - 处理多种数据格式:例如,一个视频解码器需要处理各种容器格式(MP4, AVI)、编码格式(H.264, VP9)等
- 有公开源码或已知的开源版本:如果你有源码,可以使用更高效的源码插桩(Source-based Instrumentation)模式,如 AFL++ 或 LibFuzzer。如果没有,则需要使用二进制插桩(Binary Instrumentation)模式,如 QEMU
2. 准备工作
在开始模糊测试之前,需要做好充分的准备,这直接影响到 Fuzzing 的效率和成功率
- 获取种子文件(Seed Corpus):种子文件是模糊测试的起点。你需要收集一批高质量的、能代表正常输入的样本文件。这些样本应该尽可能地覆盖程序的不同功能。高质量的种子文件能显著提高 Fuzzing 效率
- 编译目标程序:如果是源码模式,你需要使用 Fuzzer 专用的编译器(例如
afl-clang-fast
)来编译目标程序。这会在程序中植入探针,用于收集代码覆盖率信息 - 创建 Fuzzing 脚本:你需要编写一个脚本,作为 Fuzzer 和目标程序之间的适配器(Harness)。这个脚本负责将 Fuzzer 生成的输入数据传递给目标程序。对于文件输入,适配器通常很简单,可能就是
read()
或fopen()
函数。对于更复杂的网络协议,适配器需要解析并发送数据包 - 配置 Fuzzer:根据你的目标和环境,你需要选择并配置一个合适的 Fuzzer(例如 AFL++)。配置参数包括:
- Fuzzing 模式(源码、QEMU、网络等)
- Fuzzing 进程数量
- 字典文件(如果目标程序有特定的关键字)