>_ DevTrendszh

语言

首页

语言

板块

前端 后端 移动端 DevOps AI / ML 游戏开发 区块链 安全
C

AFL++ - 永不懈怠的私人漏洞猎手

6,629 星标
AFL++ logo

听起来很熟悉吧?你已经写好了代码,运行了单元测试、集成测试,甚至负载测试——一切都是绿灯。但然后,在最糟糕的时刻,用户发现了某个疯狂场景,导致程序崩溃,或者更糟——出现安全漏洞。很让人沮丧,对吧?漏洞,特别是那些隐藏在不明显输入数据中的漏洞,对任何开发者来说都是真正的头疼问题。如果有一个工具不只是等待你编写测试用例,而是主动"轰炸"你的代码,用数百万个不可预测的输入来发现最隐蔽的错误呢?

今天我们要聊的正是这样一个项目,它把搜寻这些隐藏"地雷"的过程从苦差事变成了高效甚至有趣的过程。欢迎认识 AFL++,即 American Fuzzy Lop plus plus。这不仅仅是一个模糊测试器——它是 Google 传奇级 AFL 的强大继承者,经过庞大社区的努力而臻于完善。如果你曾经做过安全测试、漏洞研究,或者只是想确保你的代码坚如磐石,AFL++ 就是你武器库中必备的工具。

什么是 AFL++,为什么你需要它?

想象你有一个处理输入数据的程序。模糊测试器就像一个非常执着且富有创造力的测试员,开始向这个程序输入最疯狂、最扭曲、最意想不到的数据。目标是什么?触发失败、崩溃、挂起或任何其他表明代码中存在 bug 的异常行为。

Google 的原始 AFL 是这个领域的先驱,但 AFL++ 走得更远。这不仅仅是一个分支——它是这个理念的全面进化。AFL++ 的开发者们从前辈那里吸取了所有精华,并添加了:

  • 更快的速度:每个模糊测试周期都变得更快,允许在相同时间内处理更多输入数据。
  • 智能变异:修改输入数据的算法变得更加复杂。AFL++ 不仅仅随机更改字节——它尝试"理解"数据结构,生成更有意义但仍能"破坏"的用例。
  • 深度插桩:这就像给模糊测试器装上了 X 光视觉。它不仅仅喂数据,还能精确看到每个输入文件触达了代码的哪些部分。这让它能够更有效地发现新的执行路径,从而发现新的漏洞。

本质上,AFL++ 就是你个人的、不知疲倦的、打了类固醇的漏洞猎手。

让 AFL++ 不可或缺的关键特性

让我们深入了解是什么让 AFL++ 如此特别:

1. 速度、精准、效率

正如我提到的,AFL++ 在速度上显著优于其前身。这通过模糊测试器核心优化和更高效的变异策略实现。例如,像 collision-free coverage(无碰撞覆盖率)和改进的 laf-intelredqueen 算法等技术,让模糊测试器能够更精确地跟踪代码执行路径,生成更多"有趣"的输入数据。这意味着你在更短时间内发现更多漏洞,这在资源受限的情况下至关重要。

2. 通用性:任何东西都能 fuzz

AFL++ 最酷的特性之一是其适应性。无论你处理的是什么:

  • 源代码:如果你有源码,可以用特殊的 afl-ccafl-c++ 编译器进行编译,添加必要的插桩。
  • 无源码的二进制文件:没错,你没听错!得益于 QEMU 集成,AFL++ 甚至可以 fuzz 没有源码的程序。这为审计第三方软件或固件开辟了巨大机会。
  • 网络服务:Web 服务器、守护进程、任何通过网络接受数据的应用程序——AFL++ 也能处理。
  • GUI 程序:即使是图形应用程序也不会被遗漏。

这种通用性使 AFL++ 成为安全性和软件质量领域各种任务的强大工具。

3. 模块化和可定制性

AFL++ 不仅仅是一个"黑盒"。它提供了广泛的扩展和适配能力。你可以为项目特定需求添加自己的自定义模块来微调模糊测试器的行为。

值得单独一提的是 unicorn_mode。这是一种使用 Unicorn Engine 模拟器的模式。它允许对非常特定的代码片段进行模糊测试,例如物联网设备的固件或需要特殊环境(普通操作系统中不可用)的代码片段。这就像拥有自己的沙箱来处理最复杂和最奇特的测试目标。

它底层是如何工作的?一些技术细节

AFL++ 的核心是"覆盖率引导"模糊测试的概念。这不仅仅是随机猜测。以下是它的工作原理:

  1. 初始数据(种子):你给模糊测试器一些输入数据的"好"例子(例如,用于图像编辑器的有效 JPEG 文件)。
  2. 插桩:你的程序以 AFL++ 能够跟踪处理每个输入文件时执行了哪些代码分支的方式进行编译。
  3. 变异:AFL++ 获取一个输入文件并开始修改它——更改字节、插入随机数据、复制块等等。
  4. 执行和分析:修改后的文件被喂给程序。AFL++ 检查哪些新的执行路径被触达。
  5. 保存"有趣"的用例:如果一个新的输入文件导致程序执行了之前未探索的代码部分,AFL++ 认为它"有趣",并将其添加到队列中进一步变异。
  6. 异常检测:如果任何变异后的文件导致崩溃、挂起或其他异常行为,AFL++ 会保存该文件并将其标记为潜在漏洞。

这个循环会重复数百万次,不断"探测"你的代码,努力触达最深、最隐蔽的角落——漏洞最常隐藏的地方。

实际应用:将 AFL++ 集成到你的工作流程中

所以你相信 AFL++ 很酷。但如何在实际生活中使用它呢?

1. CI/CD 集成

最明显、可以说最有效的方式是将模糊测试纳入你的持续集成和交付流程。每次你或你的团队对代码进行更改时,AFL++ 都可以在后台自动运行,在漏洞到达生产环境之前搜寻新的安全问题。这是一种主动的安全方法,可以显著降低风险。

2. 第三方软件安全审计

如果你使用第三方库或组件,或者做渗透测试,AFL++ 将成为你不可或缺的助手。它将帮助你发现被开发者遗漏或故意留下的隐藏漏洞(这不幸时有发生)。

3. 提高产品整体稳定性

即使你的目标不是发现关键漏洞,模糊测试也是发现常规崩溃和挂起的绝佳方式。AFL++ 将帮助你的产品变得更可靠、更能抵御意外的输入数据——这对于用户体验来说显然非常重要。

4. 研究协议和数据格式

在使用自定义网络协议或复杂文件格式?AFL++ 可以帮助你发现其实现中的异常,识别不正确的数据处理,并验证解析器的可靠性。

如何开始?比看起来更容易!

AFL++ 的开发者确保了入门门槛尽可能低。最快的入门方式是使用现成的 Docker 镜像:

docker pull aflplusplus/aflplusplus
docker run -ti -v /location/of/your/target:/src aflplusplus/aflplusplus

这样,你将在短短几分钟内获得一个完全配置好的模糊测试环境。如果你更喜欢从源码构建,详细说明在 docs/INSTALL.md 文件中等着你。

要对有源码的程序进行模糊测试,你需要使用 AFL++ 的特殊编译器进行编译:

CC=/path/to/afl-cc CXX=/path/to/afl-c++ ./configure --disable-shared
make clean all

然后运行模糊测试器本身,指定输入数据目录(seeds_dir)和输出结果目录(output_dir):

./afl-fuzz -i seeds_dir -o output_dir -- \
/path/to/tested/program [...program's cmdline...]

别忘了阅读 docs/fuzzing_in_depth.md——里面有大量有效模糊测试的有用信息!

结论:AFL++ 值得你关注吗?

绝对是肯定的!AFL++ 不仅仅是一个工具——它是一套完整的测试理念。它让你从一个全新的角度审视代码,发现那些传统方法永远无法发现的错误。这是一种主动、积极的质量和安全保障方法,已经在全世界数千开发者和研究人员的手中证明了其有效性。

如果你想提高软件质量的上限,在别人之前发现漏洞,或者只是想更深入地了解你的代码在极端条件下的行为方式,AFL++ 绝对值得你的关注。查看仓库,研究文档——也许这个模糊测试器会成为你对抗漏洞战斗中的新好朋友!它不仅能让你高枕无忧,知道你的代码已经通过了严格测试,还可能为你在安全和测试的世界中开辟新的视野。

相关项目