American Fuzzy Lop plus plus(AFL++)· Google AFL 的增强分支 · 模糊测试(Fuzzing)框架部署与使用全指南
项目仓库: https://github.com/AFLplusplus/AFLplusplus
开源协议:GNU AGPL-3.0-or-later(含 Apache-2.0 单文件与可选商业许可)
· 语言:C / C++ / Rust 工具链 · 容器化:Docker 官方镜像(x86_64 /
arm64) · Release 版本:5.03c(GitHub 开发版 5.04a) ·
分支:stable(默认) / dev /
release
1 项目简介
AFL++(American Fuzzy Lop plus plus)是 Google 经典模糊测试工具 AFL(由 Michal "lcamtuf" Zalewski 原始开发)的高级增强分支:在原始 AFL 的覆盖引导模糊测试(coverage-guided fuzzing)基础上,提供更快的执行速度、更多更好的变异策略、更强的插桩能力(LLVM 插桩、QEMU 模式、Frida 模式)以及自定义模块支持,是目前学术研究与工业界广泛使用的开源模糊测试框架之一。
AFL++ 由 Marc "van Hauser" Heuse、Dominik Maier、Andrea Fioraldi、Heiko "hexcoder-" Eissfeldt 等人维护,frida_mode 由 @Worksbutnottested 维护。它通过向被测程序持续注入半随机输入、监控程序是否崩溃或挂起,从而自动发现内存破坏、逻辑漏洞等缺陷。
1.1 核心信息一览
| 项目项 | 内容 |
|---|---|
| 项目名称 | AFL++(American Fuzzy Lop plus plus) |
| 仓库地址 | github.com/AFLplusplus/AFLplusplus |
| 项目定位 | 覆盖引导的模糊测试框架,用于自动发现程序崩溃、挂起与漏洞 |
| 开源协议 | GNU AGPL-3.0-or-later(单文件按头标注;可选商业许可) |
| 语言 / 工具链 | C / C++,配套 LLVM、GCC、QEMU、Frida 插桩模式 |
| 部署方式 | Docker 官方镜像;或源码编译安装 |
| 默认端口 | 无网络服务(本地命令行工具,默认不监听端口) |
| 系统入口 | afl-fuzz(模糊测试主进程)、afl-cc /
afl-c++(插桩编译器) |
| 输出目录 | -o 指定的输出目录,内含
crashes/、hangs/、queue/ 等 |
1.2 适用场景
- C/C++ 编写的开源库、命令行程序、网络服务在发布前做自动化缺陷挖掘。
- 安全研究人员在源码可获取时做覆盖率引导模糊测试,或在仅有二进制时用 QEMU / Frida 模式做二进制模糊测试。
- 学术论文与漏洞挖掘课程中,使用
afl-clang-fast+AFL_LLVM_CMPLOG=1进行标准化对比实验。 - 配合 Google fuzzbench 的
aflplusplus配置做模糊测试系统性能对比。
1.3 能力边界(官方口径)
- AFL++
是工具链而非一键服务:它需要你自行编译被测目标(用
afl-cc/afl-c++插桩),并准备一个小而有效的种子语料库(seeds)。 - 官方强调:开始之前务必阅读
docs/fuzzing_in_depth.md中的“common sense risks of fuzzing(模糊测试的常识风险)”,模糊测试会运行不可信输入,建议在隔离环境中进行。 - 官方不保证在任意平台开箱即用;对网络服务、GUI
程序另有专门文档(
docs/best_practices.md)。
2 功能特性
- 更强的变异与插桩:相对原始 AFL 提供更快速度、更多更好的变异、更多更好的插桩与自定义模块支持。
- 多插桩后端:LLVM
插桩(
afl-clang-fast)、GCC 插件、QEMU 模式(无源码二进制)、Frida 模式(动态插桩)。 - 字典增强:对 SQL、HTTP 等结构化语法,可按
dictionaries/README.md准备字典并用-x传入。 - 崩溃 /
挂起自动分离:发现的崩溃样本与超时挂起样本分别落入输出目录的
crashes/与hangs/子目录。 - 种子语料最小化:
queue/目录记录引起新覆盖率的输入样本。 - Docker 一键环境:官方镜像
aflplusplus/aflplusplus同时支持 x86_64 与 arm64,推送 stable 分支时自动发布。 - 覆盖率分析配套工具:官方推荐 cov-analysis(基于语料的覆盖率报告)与 fuzz-reachability(静态可达性分析)。
- 学术可引用:官方提供 WOOT'20 论文与 BibTeX 引用格式。
3 官方界面预览
AFL++ 的运行界面是终端(TTY)中的实时状态面板:正在显示 exec/s
速度、与已知路径相比的位图、pending 种子数、已发现崩溃数等;官方文档
docs/afl-fuzz_approach.md
中的“understanding-the-status-screen”章节逐项解释面板含义。运行中出现红色高亮的行,需按该文档立即排查。
4 官方跳转链接汇总
| 类别 | 链接 | 说明 |
|---|---|---|
| 仓库主页 | https://github.com/AFLplusplus/AFLplusplus | 源码、README、Issues |
| Releases | github.com/AFLplusplus/AFLplusplus/releases | Release 版本(当前 5.03c) |
| 文档总览 | docs/README.md | 图形化指南入口 |
| 安装文档 | docs/INSTALL.md | 源码编译安装 |
| 深入文档 | docs/fuzzing_in_depth.md | 模糊测试方法论与风险 |
| 教程 | docs/tutorials.md | 入门教程 |
| FAQ | docs/FAQ.md | 常见问题 |
| 许可证说明 | LICENSING.md | AGPL / 商业许可说明 |
| 社区 | Fuzzing Zulip | 实时交流 |
| 论文 | WOOT'20 Fioraldi et al. | 学术引用 |
5 前置要求与服务器配置
5.1 软件前提
- 操作系统:Linux 为主(官方文档与 Docker 镜像均基于 Linux 环境);macOS 与 Windows 可作为开发环境但模糊测试性能最佳在原生 Linux。
- 编译工具链:
gcc/clang/llvm(使用afl-cc/afl-clang-fast时需要);源码安装还需要make等基础构建工具。 - Docker(可选):使用官方镜像时需要 Docker Engine,Compose 非必需。
- 被测目标源码:源码可获取时用插桩编译器;仅二进制时使用 QEMU / Frida 模式,无需目标源码。
5.2 硬件与系统建议
- 模糊测试是 CPU 密集型任务,官方建议使用多核 CPU 并通过
-M/-S启动多个并行 fuzzer 实例。 - 需要在隔离环境中运行被测程序(它会处理不可信输入);官方在
docs/fuzzing_in_depth.md中明确列出 fuzzing 的常识风险。 - 准备一个小而有效的种子目录(
seeds_dir),种子应是被测程序可接受的合法输入样本。
5.3 端口与资源
- AFL++ 本身是本地命令行工具,不监听任何网络端口,无需在防火墙开放端口。
- 输出目录(
-o指定)会持续增长,需预留足够磁盘空间存放queue/、crashes/、hangs/。
6 方式一:Docker 一键运行(推荐快速上手)
官方在 Docker Hub 发布了预编译镜像,x86_64 与 arm64 均可用:
docker pull aflplusplus/aflplusplus
docker run -ti -v /location/of/your/target:/src aflplusplus/aflplusplus- 把你自己的目标源码目录挂载到容器内的
/src;镜像内已带全套 AFL++ 工具。 - 如需最新开发状态,可拉取
aflplusplus/aflplusplus:dev。 - 进入容器后,按第 7 节的插桩编译与
afl-fuzz流程对待测程序进行模糊测试。
7 方式二:源码编译与本地运行
官方推荐自行编译(docs/INSTALL.md),而非仅使用镜像。基本步骤如下:
git clone https://github.com/AFLplusplus/AFLplusplus.git
cd AFLplusplus
# 安装系统依赖与编译(详见 docs/INSTALL.md,按发行版选择)
make
make install编译完成后,以一个有源码的目标为例开始模糊测试:
- 用插桩编译器编译目标:
CC=/path/to/afl-cc CXX=/path/to/afl-c++ ./configure --disable-shared
make clean all准备一个小而有效的输入文件作为种子;对 SQL、HTTP 等结构化语法,按
dictionaries/README.md准备字典。若程序从 stdin 读取输入,运行:
./afl-fuzz -i seeds_dir -o output_dir -- \
/path/to/tested/program [...program's cmdline...]- 需要字典时加
-x /path/to/dictionary.txt。 - 若程序从文件读取输入,在命令行中放置
@@,AFL++ 会自动替换为生成的临时文件名。
在 fuzzer 界面中关注红色高亮提示,按
docs/afl-fuzz_approach.md排查。发现的崩溃与挂起样本分别位于
output_dir/crashes/与output_dir/hangs/;以 stdin 目标为例复现:
cat output_dir/crashes/id:000000,* | /path/to/tested/program [...program's cmdline...]8 配置项说明
AFL++ 没有集中式配置文件,主要通过命令行参数与环境变量控制(官方文档为准):
| 配置项 | 用途 | 说明 |
|---|---|---|
-i seeds_dir |
种子语料输入目录 | 提供初始有效输入样本 |
-o output_dir |
输出目录 | 存放 queue / crashes / hangs |
-x dictionary.txt |
加载字典 | 提升结构化语法输入的命中率 |
-M / -S |
主 / 从并行 fuzzer 实例 | 多核并行时的实例命名 |
@@ |
文件输入占位符 | AFL++ 自动替换为临时文件路径 |
CC=afl-cc / CXX=afl-c++ |
插桩编译器 | 让目标在编译期被插桩 |
AFL_LLVM_CMPLOG=1 |
开启 CMPLOG | 官方对比实验推荐配置 |
aflplusplus:dev 标签 |
开发版镜像 | 需最新功能时使用 |
9 常用运维命令
- 拉取 /
更新镜像:
docker pull aflplusplus/aflplusplus - 启动容器并挂载源码:
docker run -ti -v /your/target:/src aflplusplus/aflplusplus - 启动模糊测试:
./afl-fuzz -i seeds_dir -o output_dir -- /path/to/program - 复现崩溃:
cat output_dir/crashes/id:000000,* | /path/to/program - 查看已发现崩溃:
ls output_dir/crashes/ - 查看挂起样本:
ls output_dir/hangs/ - 停止 fuzzer:在交互终端按
Ctrl-C或官方文档中记录的快捷键。
10 常见故障排查
- 界面出现红色告警:按
docs/afl-fuzz_approach.md的“understanding-the-status-screen”逐项处理,常见于 CPU 性能模式、core 转储配置、ASLR 等系统设置问题。 - 执行速度(exec/s)过低:检查是否使用了未插桩的二进制;对源码目标应改用
afl-cc/afl-clang-fast重新编译;CPU 性能模式应调整为 performance。 - 找不到崩溃 /
覆盖率不增长:补充种子语料,或为结构化输入添加字典;阅读
docs/fuzzing_in_depth.md。 - QEMU / Frida 模式问题:见
docs/fuzzing_binary-only_targets.md(无源码二进制目标)。 - 网络服务 / GUI 目标:见
docs/best_practices.md中的“fuzzing-a-network-service”与“fuzzing-a-gui-program”。 - Issues 与求助:仅对 AFL++ 本身缺陷提
issue;一般使用问题先看
docs/FAQ.md,或加入 Fuzzing Zulip 社区。
11 风险与合规说明
- 许可证:AFL++ 主体为 GNU
AGPL-3.0-or-later;若将修改版作为网络服务对外提供,AGPL
要求向用户提供对应源码。个别文件按其 SPDX 头标注为 Apache-2.0;无法遵循
AGPL 的组织可通过向 EFF 或 CCC 捐赠 €20,000 获得为期一年的商业许可(详见
LICENSE.COMMERCIAL)。 - 运行风险:模糊测试会让程序运行不可信输入,可能触发崩溃、core dump 甚至资源耗尽;官方明确要求在隔离环境中运行,并先阅读 fuzzing 的常识风险章节。
- 合法性边界:请仅对你拥有授权的程序、自家代码或已获授权的目标进行模糊测试;不要用于未经授权的破坏性测试。
- 本文整理自官方 README 与官方文档链接,命令与参数以官方仓库最新说明为准;不包含 star 数等动态数据。