从开始到结束的fuzz(AFL)
字数 1141 2025-08-24 16:48:07

AFL模糊测试从入门到精通:完整工作流程指南

1. 模糊测试概述

模糊测试(Fuzzing)是一种自动化软件测试技术,通过向目标程序提供非预期的输入并监控异常结果来发现软件漏洞。AFL(American Fuzzy Lop)是目前最流行的覆盖率引导的模糊测试工具之一。

2. 选择合适的测试目标

2.1 目标选择标准

  • 语言支持:AFL在C/C++应用程序上效果最佳
  • 可编译性:最好能从源代码构建,使用afl-clang-fast或afl-clang-fast++
  • 示例代码:项目包含简单示例代码更易上手
  • 测试用例:有独特且易获取的测试用例(如单元测试文件)

2.2 目标搜索方法

推荐在GitHub上搜索:

  • 使用C/C++编写
  • 最近更新的项目
  • 星标数较高(如200星以上)
  • 示例:yaml-cpp项目符合所有标准

3. 目标程序准备

3.1 编译设置

git clone https://github.com/jbeder/yaml-cpp.git
cd yaml-cpp
mkdir build
cd build
cmake -DCMAKE_CXX_COMPILER=afl-clang-fast++ ..
make

3.2 启用持久模式

修改源代码(如parse.cpp)以启用AFL持久模式:

if (argc > 1) {
    std::ifstream fin;
    fin.open(argv[1]);
    parse(fin);
} else {
    while (__AFL_LOOP(1000)) {  // 持久模式循环
        parse(std::cin);
    }
}

4. 测试用例准备

4.1 初始测试用例获取

从项目测试目录中获取:

  • 如yaml-cpp的specexamples.h文件
  • 提取其中的YAML示例作为初始测试用例

4.2 测试用例最小化

使用AFL工具优化测试用例:

  1. afl-cmin:去除冗余测试用例
afl-cmin -i in -o in_min -- ./parse
  1. afl-tmin:最小化单个测试用例
afl-tmin -i testcase -o testcase.min -- ./parse
  1. 批量最小化脚本
#!/bin/bash
for i in *; do 
    afl-tmin -i $i -o $i.min -- ~/parse; 
done
mkdir ~/testcases && cp *.min ~/testcases

5. 启动模糊测试

5.1 基本命令

afl-fuzz -i in -o out ./parse

5.2 主从模式

  1. 主模糊器(确定性策略)
afl-fuzz -i in -o out -M fuzzer1 -- ./parse
  1. 从模糊器(随机策略)
afl-fuzz -i in -o out -S fuzzer2 -- ./parse

5.3 监控进度

  • 主模糊器完成第一个周期(可能需要10-24小时)
  • 观察发现的路径和崩溃数量

6. 中期优化

6.1 合并队列

mkdir queue_all
afl-cmin -i queue_all/ -o queue_cmin -- ../parse

6.2 并行最小化

使用afl-ptmin脚本加速:

~/afl-ptmin 8 ./queue_cmin/ ./queue/

6.3 更新模糊器

rm -rf fuzzer1/queue fuzzer2/queue
cp -r queue/ fuzzer1/queue
cp -r queue/ fuzzer2/queue
afl-fuzz -i- -o syncdir/ -S fuzzer2 -- ./parse
afl-fuzz -i- -o syncdir/ -M fuzzer1 -- ./parse

7. 崩溃分析

7.1 使用crashwalk工具

安装:

apt-get install gdb golang
mkdir src
cd src
git clone https://github.com/jfoote/exploitable.git
cd && mkdir go
export GOPATH=~/go
go get -u github.com/bnagy/crashwalk/cmd/...

分析崩溃:

~/go/bin/cwtriage -root syncdir/fuzzer1/crashes/ -match id -- ~/parse @@

8. 覆盖率分析

8.1 编译支持覆盖率的版本

cd ~/yaml-cpp/build/
rm -rf ./*
cmake -DCMAKE_CXX_FLAGS="-O0 -fprofile-arcs -ftest-coverage" \
      -DCMAKE_EXE_LINKER_FLAGS="-fprofile-arcs -ftest-coverage" ..
make
cp util/parse ~/parse_cov

8.2 使用afl-cov

afl-cov -d ~/syncdir/ --live --coverage-cmd "~/parse_cov AFL_FILE" \
        --code-dir ~/yaml-cpp/

9. 最佳实践总结

  1. 目标选择:优先选择C/C++项目,有简单示例和现成测试用例
  2. 编译优化:使用afl-clang-fast系列编译器,启用持久模式
  3. 测试用例:精心准备和最小化初始测试用例
  4. 模糊策略:结合主从模式提高效率
  5. 中期优化:定期合并和最小化队列
  6. 结果分析:全面分析崩溃和代码覆盖率

10. 常见问题解决

  1. 编译失败:尝试使用afl-g++替代afl-clang-fast++
  2. 持久模式不适配:某些程序架构不支持简单添加循环
  3. 性能问题:调整__AFL_LOOP参数(如从1000降到500)
  4. 长时间无进展:检查测试用例质量,考虑添加字典

通过遵循这个完整的工作流程,您可以系统地进行高效的模糊测试,最大化发现目标程序中潜在漏洞的机会。

AFL模糊测试从入门到精通:完整工作流程指南 1. 模糊测试概述 模糊测试(Fuzzing)是一种自动化软件测试技术,通过向目标程序提供非预期的输入并监控异常结果来发现软件漏洞。AFL(American Fuzzy Lop)是目前最流行的覆盖率引导的模糊测试工具之一。 2. 选择合适的测试目标 2.1 目标选择标准 语言支持 :AFL在C/C++应用程序上效果最佳 可编译性 :最好能从源代码构建,使用afl-clang-fast或afl-clang-fast++ 示例代码 :项目包含简单示例代码更易上手 测试用例 :有独特且易获取的测试用例(如单元测试文件) 2.2 目标搜索方法 推荐在GitHub上搜索: 使用C/C++编写 最近更新的项目 星标数较高(如200星以上) 示例:yaml-cpp项目符合所有标准 3. 目标程序准备 3.1 编译设置 3.2 启用持久模式 修改源代码(如parse.cpp)以启用AFL持久模式: 4. 测试用例准备 4.1 初始测试用例获取 从项目测试目录中获取: 如yaml-cpp的 specexamples.h 文件 提取其中的YAML示例作为初始测试用例 4.2 测试用例最小化 使用AFL工具优化测试用例: afl-cmin :去除冗余测试用例 afl-tmin :最小化单个测试用例 批量最小化脚本 : 5. 启动模糊测试 5.1 基本命令 5.2 主从模式 主模糊器(确定性策略) : 从模糊器(随机策略) : 5.3 监控进度 主模糊器完成第一个周期(可能需要10-24小时) 观察发现的路径和崩溃数量 6. 中期优化 6.1 合并队列 6.2 并行最小化 使用afl-ptmin脚本加速: 6.3 更新模糊器 7. 崩溃分析 7.1 使用crashwalk工具 安装: 分析崩溃: 8. 覆盖率分析 8.1 编译支持覆盖率的版本 8.2 使用afl-cov 9. 最佳实践总结 目标选择 :优先选择C/C++项目,有简单示例和现成测试用例 编译优化 :使用afl-clang-fast系列编译器,启用持久模式 测试用例 :精心准备和最小化初始测试用例 模糊策略 :结合主从模式提高效率 中期优化 :定期合并和最小化队列 结果分析 :全面分析崩溃和代码覆盖率 10. 常见问题解决 编译失败 :尝试使用afl-g++替代afl-clang-fast++ 持久模式不适配 :某些程序架构不支持简单添加循环 性能问题 :调整__ AFL_ LOOP参数(如从1000降到500) 长时间无进展 :检查测试用例质量,考虑添加字典 通过遵循这个完整的工作流程,您可以系统地进行高效的模糊测试,最大化发现目标程序中潜在漏洞的机会。