GitHub Security Lab 开源 Fuzzing Taskflow:让 LLM 智能体自己跑完 C/C++ 模糊测试

GitHub Security Lab 开源 Fuzzing Taskflow:让 LLM 智能体自己跑完 C/C++ 模糊测试

原文:GitHub Blog - AI-powered fuzzing with the GitHub Security Lab Taskflow Agent(https://github.blog/security/application-security/ai-powered-fuzzing-with-the-github-security-lab-taskflow-agent)

模糊测试做安全研究的人都懂:写 harness、跑 AFL++、盯覆盖率、分诊崩溃,每一环都枯燥且重复。GitHub Security Lab 的 Antonio Morales 最近开源了 Fuzzing Taskflow,把这条流水线整个交给 LLM 智能体:只要指向一个 GitHub 仓库,它就能自动识别入口点、分析构建系统、编写 harness、运行 AFL++、读取覆盖报告、改进 harness、分诊每一个崩溃,并为每个唯一 bug 写出漏洞报告,全程无需人盯着。

一、三层架构:决策与执行分离

这个项目最值得 Agent 开发者看的不是模糊测试本身,而是它的架构。整个系统分三层:

  1. Shell driver:run_fuzzing.sh 脚本把各个 pipeline stage 串起来。
  2. Taskflow YAML:每个 stage 对应一份 YAML,本质上是告诉 LLM 智能体每一步该做什么的 prompt。
  3. MCP tools:智能体实际调用的工具集,比如运行 AFL、编译 harness、存储 crash、读取覆盖报告。

官方强调的设计原则是一句话:LLM agent owns the decisions, and the MCP tools own the execution。智能体决定 fuzz 什么、写什么 harness、追哪个覆盖缺口,但它从不直接调用 AFL 或 clang,只能调用工具暴露的原语。

另一个容易被忽略的细节:所有状态存在 SQLite 数据库 fuzz_context.db 中,各 stage 之间通过数据库交互,而不是靠内存传递。这意味着流水线可以断点续跑,stage 之间彻底解耦。

二、全流程拆解

1. 双二进制构建

每个 harness 会被编译两次,各干各的活:

  • .afl 二进制:用 afl-clang-lto 加 -fsanitize=address,undefined 编译,负责实际跑 fuzzing;
  • .cov 二进制:用 clang 加 -fprofile-instr-generate -fcoverage-mapping 编译,负责事后重放 AFL 队列,生成真实的源码行和分支覆盖报告。

一个跑性能,一个跑精度,这个拆分思路在覆盖率敏感的场景里可以复用。

2. 覆盖反馈循环

这是整条管线的核心,把工程师手动的"跑一轮、看覆盖、改一改"循环自动化了。每轮迭代中,智能体对每个 harness 在时间预算内运行 AFL,用 .cov 二进制重放队列拿真实覆盖报告,读出未覆盖的分支列表,然后自主选择行动:

  • 造一个专门命中未覆盖分支的新种子;
  • 修改 harness 源码,让它多调用一个 API;
  • 把守卫比较的 magic constants 自动补进 AFL 字典;
  • 如果是冷错误路径或第三方 vendor 代码,直接跳过。

时间预算按 30s → 60s → 120s → 240s → 480s → 960s 逐轮翻倍,每个目标累计约 32 分钟:早期短轮次抓低垂果实,后期长轮次突破硬守卫。停止条件是 plateau 检测------连续两轮迭代各自增益低于阈值(默认 1% 绝对行覆盖)就判定收益递减,移步下一个目标。

3. 结构感知模糊测试

针对常见格式,管线提供四种互补机制生成结构化输入:预建的 AFL 字典和 LLVMFuzzerCustomMutator 变异器(覆盖 JSON、XML、正则、PNG、长度前缀 TLV);扫描目标源码提取字符串字面量和 32 位数值常量的源码级字典;覆盖驱动的动态字典------每轮覆盖后检查 strncmp、memcmp、case 分支等守卫并追加新 token(数值常量同时给出大小端两种表示);以及把语料目录文件随机拼接子区域的 corpus-splice 算子。

4. 语料库演进与崩溃分诊

每个 harness 拥有稳定的语料目录,跨迭代、跨 campaign 保留。每轮结束把 AFL 队列合并进语料并用 afl-cmin 去重限大小。

fuzzing 结束后自动进入三阶段分诊:先用 afl-tmin 最小化每个崩溃输入,在 ASan 下重放捕获栈回溯,按归一化栈顶帧哈希去重;再对已知崩溃在新二进制上重放,检测上游是否已修复;最后智能体阅读 harness 源码与崩溃函数,回溯到公开 API 调用链,为每个崩溃写 markdown 报告。

报告的 verdict 分为 vulnerability、library_hardening、harness_bug、OOM、timeout、assertion_failure、duplicate 几类,内容包括 file:line 级别的根因分析、可达性论证、可利用性评估,以及 unified diff 形式的修复建议和回归测试草案。

三、怎么跑起来

最简单的方式是打开官方仓库 seclab-taskflows-fuzzing 的 Codespace,然后:

复制代码
./scripts/fuzzing/run_fuzzing.sh tukaani-project/xz
./scripts/fuzzing/run_fuzzing.sh DaveGamble/cJSON

参数就是 GitHub 的 owner/repo 名。启动 campaign 后,8765 端口会自动开放一个实时仪表板,展示每个 harness 的运行状态、带迷你走势图的覆盖率表格、崩溃热力图和迭代时间线(Codespace 会自动转发端口)。

必须原样转述官方的安全警告:这个 taskflow 直接在宿主机上运行 afl-fuzz、clang 和 LLM 选定的任意构建命令,中间没有任何容器隔离。一个被 prompt injection 的智能体原则上可以做你的用户账号能做的一切。所以务必只在一次性环境(Codespace 或临时虚拟机)中、以非特权身份运行。

四、模型选择与局限

默认模型是 Claude Sonnet 5,原因是它通过了全部内部测试;部分前沿模型因为对输出施加安全护栏,反而不适合这个 taskflow。想换模型可以改 src/seclab_taskflows_fuzzing/configs/model_config.yaml(以仓库最新文档为准,未验证最新版本)。

局限也要说清楚:目前只支持 C/C++ 项目;智能体的分析受限于模型对目标代码的理解,确实会出错,作者建议所有补丁标记 review required,verdict 只是人工分析的起点而非结论;fuzzing 仍然需要 human in the loop,这套工具只是把最重复的劳动交了出去。

五、给 Agent 开发者的四个可复用模式

抛开模糊测试,这个项目里有四个模式值得搬回你自己的 Agent 项目:

  1. 决策与执行分离。智能体只做决策,工具只暴露原语,出问题时边界清晰,也更容易做权限收敛。
  2. 状态外置到数据库。stage 之间靠 SQLite 而不是内存传状态,长任务天然获得断点续跑能力。
  3. 预算递增加 plateau 检测。时间预算逐轮翻倍、连续低增益就止损换目标,这是 Agent 长循环里很通用的停止条件设计。
  4. 输出带 unified diff。让智能体给出可 diff、可 review 的建议,而不是一段散文,人工介入成本会低一个数量级。
相关推荐
朝朝辞暮i1 小时前
C++ 第 13 课:值传递 —— 为什么函数里改了,外面却没变?
java·c++·算法
网络毒刘2 小时前
Token 账单的「隐形税」:系统提示、工具定义与历史滚动为何比生成贵
agent·token·cursor·成本·mcp
TOOLS指南2 小时前
GitHub 和 ai.github 是什么?两者有什么区别
人工智能·github
贾斯汀frank2 小时前
Fleurdelix OS已预装办公套件ONLYOFFICE桌面编辑器
github
吃饱了得干活3 小时前
Agent 的记忆与工具:从上下文窗口到 MCP
python·agent·mcp
无忧.芙桃3 小时前
C++语言原理与实践(十):vector类的底层实现
开发语言·c++·算法
无名猿3 小时前
std::variant 完全指南:类型安全的 union 与 std::visit 用法
c++·stl·标准库·现代c++
wflynn3 小时前
GitHub 日榜趋势速报 | 2026-09-30
开源·github
VIP_CQCRE3 小时前
让 Claude 实时联网搜索:Ace Data Cloud Serp MCP 接入指南
ai·claude·搜索·mcp·acedatacloud