一个由 GitHub Security Lab Taskflow Agent 驱动的 LLM 驱动模糊测试流水线
一个由 LLM 驱动的、OSS-Fuzz 风格的针对原生 C/C++ 项目的模糊测试流水线。 使用 AFL++ 执行,clang+lcov 进行覆盖率统计,由 LLM 智能体负责 测试桩编写、覆盖率反馈决策、分类和报告。
本仓库包含
GitHub Security Lab Taskflow Agent
的模糊测试 taskflow。
它依赖
seclab-taskflows
配套仓库中的一些共享构建模块
(fetch_source_code taskflow、local_file_viewer / gh_file_viewer
toolboxes,以及默认的 model_config)——这些会
作为 Python 依赖自动安装。
欢迎贡献!请参阅 CONTRIBUTING.md 了解指南。
apt 的 Linux 环境(或 Codespace)gh)pip install git+https://github.com/GitHubSecurityLab/seclab-taskflows-fuzzing
这会传递性地引入 seclab-taskflow-agent 和 seclab-taskflows(父级),因此所有形如
seclab_taskflows.taskflows.audit.*、
seclab_taskflows.toolboxes.local_file_viewer、
seclab_taskflows.toolboxes.gh_file_viewer 和
seclab_taskflows.configs.model_config 的点分引用在运行时都会从父级发行版中解析。
此任务流是一个完全自主的模糊测试流水线。给定一个原生 C/C++ 项目的 GitHub 仓库,它将:
.afl 二进制文件、AFL++ CMPLOG 插桩的 .cmplog 二进制文件和 clang 覆盖率插桩的 .cov 二进制文件,该流水线在精神上是 OSS-Fuzz 风格的:它使用许多相同的技术(按格式的变异器和字典、结构感知的 token 拼接、覆盖率驱动的 harness 改进、机器可读报告、去重的栈哈希崩溃),但它更小且自包含。
# Inside the codespace (or a host with python + git available):
./scripts/fuzzing/run_fuzzing.sh tukaani-project/xz
这就是整个界面。该脚本是自主运行的;它会在首次运行时安装 AFL++,然后驱动其余的任务流程。输出文件写入 ~/.local/share/seclab-taskflow-agent/seclab-taskflows/。
仪表盘会在后台自动启动;在 Codespace 中,端口 8765 会被自动转发——在任何浏览器中打开它即可实时查看进度。
如需快速冒烟测试,请使用一个小型目标:
./scripts/fuzzing/run_fuzzing.sh DaveGamble/cJSON
三层结构,自上而下:
┌────────────────────────────────────────────────────────────────────┐
│ scripts/fuzzing/run_fuzzing.sh │
│ shell driver; chains the taskflow stages with `set +e` │
└────────────────────┬───────────────────────────────────────────────┘
│
▼
┌────────────────────────────────────────────────────────────────────┐
│ src/seclab_taskflows/taskflows/fuzzing/*.yaml │
│ LLM agent prompts; one YAML per pipeline stage │
└────────────────────┬───────────────────────────────────────────────┘
│ (calls MCP tools)
▼
┌────────────────────────────────────────────────────────────────────┐
│ src/seclab_taskflows/mcp_servers/ │
│ ├ fuzz_context.py persistence (SQLite via SQLAlchemy) │
│ └ fuzz_runner.py subprocess wrappers (AFL, clang, lcov, ...) │
│ │
│ scripts/fuzzing/dashboard.py │
│ read-only HTML view of fuzz_context.db │
└────────────────────────────────────────────────────────────────────┘
关键设计规则:
fuzz_context.db 中。run_afl_for、compile_harness、store_crash 等接口。afl-clang-lto++ -fsanitize=address,undefined 构建(即 .afl 二进制文件),并使用 clang++ -fprofile-instr-generate -fcoverage-mapping 构建(即 .cov 二进制文件)。.afl 二进制文件用于模糊测试;.cov 二进制文件重放 AFL 队列以生成真实的源码行/函数/分支覆盖率。第三个无 sanitizer 的 .cmplog 二进制文件(使用 afl-clang-lto++ 并设置 AFL_LLVM_CMPLOG=1)被传递给 afl-fuzz -c,以便 AFL++ 的 CMPLOG/RedQueen 阶段能够求解魔术值和校验和。所有三种构建都是强制性的:CMPLOG 构建失败即导致测试框架构建失败,且 run_afl_for 在没有 .cmplog 二进制文件时拒绝运行。如果未安装 afl-clang-lto++,AFL++ 构建将改用 afl-clang-fast++,并且 compile_harness 会返回警告。C++ 驱动程序链接 C++ 标准库,因此 C 和 C++ 测试框架及库均可正常工作;.c 文件仍按 C 编译(-x c)。| # | 阶段 | Taskflow YAML |
|---|---|---|
| 1 | 安装 AFL++ 及工具链 | scripts/fuzzing/install_afl.sh |
| 2 | 获取源码 | seclab_taskflows.taskflows.audit.fetch_source_code |
| 3 | 识别模糊测试目标 | seclab_taskflows_fuzzing.taskflows.fuzzing.identify_fuzz_targets |
| 4 | 分析构建系统 | seclab_taskflows_fuzzing.taskflows.fuzzing.analyze_build_system |
| 5a | 编写初始测试框架(如请求,×N 个候选) | seclab_taskflows_fuzzing.taskflows.fuzzing.write_initial_harnesses |
| 5b | 构建测试框架(AFL++ 边缘 + AFL++ CMPLOG + clang 覆盖率) | seclab_taskflows_fuzzing.taskflows.fuzzing.build_harnesses |
| 5c | 筛选候选(当 HARNESS_CANDIDATES > 1 时) | seclab_taskflows_fuzzing.taskflows.fuzzing.qualify_harnesses |
| 6 | 模糊测试/覆盖率/改进循环(×N 次迭代) | seclab_taskflows_fuzzing.taskflows.fuzzing.fuzz_iteration |
| 7 | 崩溃分类 | seclab_taskflows_fuzzing.taskflows.fuzzing.triage_crashes |
| 8 | 确认先前已知的崩溃仍可复现 | seclab_taskflows_fuzzing.taskflows.fuzzing.confirm_fixed_crashes |
| 9 | 构建调用图 + 未触及 API 报告 | seclab_taskflows_fuzzing.taskflows.fuzzing.analyze_call_graph |
| 10 | 编写每个崩溃的漏洞报告 | seclab_taskflows_fuzzing.taskflows.fuzzing.write_vuln_reports |
| 11 | 编写活动报告 | seclab_taskflows_fuzzing.taskflows.fuzzing.write_report |
每个阶段都是一个自包含的 taskflow YAML,由智能体端到端运行。各阶段仅通过 fuzz_context.db 中的 SQLite 数据库进行通信——不存在内存中的交接。
这是流水线的核心。时间预算每次迭代翻倍:
30s → 60s → 120s → 240s → 480s → 960s (≈ 32 min/target)
每次迭代、每个 harness,agent 会:
get_persistent_corpus_dir(harness_id) 获取该 harness 的稳定
语料库目录。run_afl_for(afl_binary_path, cmplog_binary_path, seed_dir=<persistent corpus>, output_dir=<run dir>, seconds=<budget>, dictionary=<auto.dict>)。run_coverage(cov_binary_path, inputs_dir=<run>/default/queue, output_dir=<run>/coverage) 生成 LCOV tracefile 和 HTML 报告。store_coverage_from_lcov(run_id, lcov_path, html_path) 持久化
一条 coverage_report 记录 + 每个未覆盖项的 coverage_gap 记录。fold_queue_into_persistent_corpus(...) 将 AFL 的迭代队列合并
到持久语料库中,并运行 cmin 以保持大小有界。get_coverage_summary + get_coverage_gaps,然后要么:
coverage_feedback)以到达未覆盖的
分支,enrich_dictionary_from_uncovered(...) 自动为 AFL 满足
guard 所需的魔法常量添加字典条目,或者store_iteration_note(repo, iteration_number, harness_id, note=<one line summary>),以便仪表板的迭代时间线跟踪变更内容。平台期检测。 一旦连续两次迭代的行覆盖率绝对百分点增益均
< FUZZ_PLATEAU_THRESHOLD_PCT(默认 1.0),循环即提前退出。
三种互补机制可产生比原始字节变异更强的输入。