了解fuzz
安装apt install bsdmainutils
exif格式:https://www.media.mit.edu/pia/Research/deepview/exif.html
fuzz文件目标类型git clone https://github.com/ianare/exif-samples.git
详细技术对比与漏洞挖掘应用
| 特性 | AFL++ | LibFuzzer |
|---|---|---|
| Fuzzing 类型 | 进程外 (Out-of-Process), 灰盒 Fuzzing | 进程内 (In-Process), 白盒 Fuzzing |
| 目标对象 | 完整的可执行程序,通过 stdin 或文件接收输入。 | 程序中的特定函数或库 API。 |
| 反馈机制 | 编译时插桩 (Instrumentation),通过 fork server 和共享内存与 Fuzzer 通信。 | 编译器内置的覆盖率反馈机制 (SanitizerCoverage),无进程间通信开销。 |
| 执行速度 | 相对较慢 (几百到几千 execs/sec) | 非常快 (几万到几十万 execs/sec) |
| 上手难度 | 较低。对于简单的程序,只需用 afl-clang-fast 编译即可,无需写代码。 | 中等。需要为目标函数编写一个 Harness (测试驱动程序)。 |
| 发现 Bug 类型 | 各种类型,包括程序初始化/退出时的 Bug,内存竞争等。 | 主要集中在被测函数内部的逻辑 Bug,如解析错误、缓冲区溢出等。 |
在漏洞挖掘中如何选择?
你应该使用 AFL++ 的场景:
- 目标是一个完整的应用程序:比如一个图像查看器、一个 PDF 阅读器、一个命令行解压工具 (exiv2, objdump, unzip 等)。
- 你没有源代码,只有二进制文件:AFL++ 的 QEMU 模式或 Unicorn 模式可以对闭源程序进行 Fuzzing (虽然效率较低)。
- 你想快速上手:对于一个简单的、接收文件输入的程序,用 AFL++ 开始 Fuzzing 几乎是零代码成本的。
- 程序状态复杂:如果程序的 Bug 需要复杂的全局状态或多次交互才能触发,AFL++ 的模型更接近真实使用情况。
你应该使用 LibFuzzer 的场景:
- 目标是一个库 (library):比如一个 JSON 解析库、一个加解密库、一个网络协议解析库。你想测试它的某个核心 API。
- 你想对一个大型项目中某个特定的复杂函数进行深度测试:例如,你想测试 Web 浏览器中的 URL 解析函数,或者操作系统内核中的文件系统解析函数。
- 追求极致的速度和效率:当你知道“漏洞最可能出现在这个函数里”时,用 LibFuzzer 直接对它进行“饱和式攻击”是最高效的选择。
- 你想把它集成到持续集成 (CI) 系统中:LibFuzzer 的 Harness 本质上就是一个单元测试,非常适合自动化。Google 的 OSS-Fuzz 项目就大量使用了 LibFuzzer。
总结
AFL++ 和 LibFuzzer 不是竞争关系,而是互补关系。
一个专业的漏洞研究员通常会同时使用这两种工具。
- 广度优先,用 AFL++:先用 AFL++ 对整个程序进行一轮广泛的 Fuzzing,快速找到一些表层的、容易触发的 Bug。
- 深度优先,用 LibFuzzer:在对程序有了一定了解后,识别出其中最复杂、最可能出问题的核心处理函数,然后为它编写一个 Harness,用 LibFuzzer 进行深度、高速的 Fuzzing,挖掘更深层次的漏洞。