Loading...

文章背景图

AFL++:Google AFL 的增强分支模糊测试框架|部署与使用全指南

2026-11-02
0
- 字
- 分钟
|

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

编译完成后,以一个有源码的目标为例开始模糊测试:

  1. 用插桩编译器编译目标:
CC=/path/to/afl-cc CXX=/path/to/afl-c++ ./configure --disable-shared
make clean all
  1. 准备一个小而有效的输入文件作为种子;对 SQL、HTTP 等结构化语法,按 dictionaries/README.md 准备字典。

  2. 若程序从 stdin 读取输入,运行:

./afl-fuzz -i seeds_dir -o output_dir -- \
  /path/to/tested/program [...program's cmdline...]
  • 需要字典时加 -x /path/to/dictionary.txt。
  • 若程序从文件读取输入,在命令行中放置 @@,AFL++ 会自动替换为生成的临时文件名。
  1. 在 fuzzer 界面中关注红色高亮提示,按 docs/afl-fuzz_approach.md 排查。

  2. 发现的崩溃与挂起样本分别位于 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 数等动态数据。
评论交流

文章目录