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 的建议,而不是一段散文,人工介入成本会低一个数量级。
相关推荐
小七在进步15 小时前
string的使用(1)
c++·visual studio
白杨尚青16 小时前
C++进阶篇(六):map 和 set 的模拟实现——用红黑树封装 mymap/myset(迭代器 + operator[])
开发语言·c++·迭代器·stl·set·map·红黑树
用户别睡觉19 小时前
有时候放弃也是一种收获
人工智能·github
kloc19 小时前
聊天室项目入口网关子服务的实现
linux·c++
愚坤20 小时前
前端真有意思,JS还能独立做项目?
前端·javascript·github
dong_junshuai20 小时前
每天一个开源项目#157 Modern Web Guidance:让Agent按需查浏览器能力
github
csdn_aspnet1 天前
C++ 3个有序点的方向(Orientation of 3 ordered points)
c++·算法
小七在进步1 天前
string的使用(2)
c++
青少儿编程课堂1 天前
蓝桥杯·全国青少年信息素养大赛·电子学会Python/C++考级:折半搜索优化子集枚举(Meet in the Middle)解析
c++·python·算法·bfs·信息学竞赛
一条Go1 天前
OnCall 时段路由:跨午夜、左闭右开与「Local 不是时区」
后端·架构·github