Skip to content
KitploitKITPLOIT
工具漏洞利用博客
Log in
提交
工具漏洞利用博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
seclab-taskflows-fuzzing — 一个由 GitHub Security Lab Taskflow Agent 驱动的 LLM 驱动模糊测试流水线 | Kitploit
工具/GitHubGitHub/githubsecuritylab/seclab-taskflows-fuzzing
静态分析漏洞扫描器动态分析 (沙盒)漏洞分析代码分析脚本与自动化模糊测试恶意软件分析实用工具与框架

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
AI 安全
GitHubgithubsecuritylab/seclab-taskflows-fuzzing

seclab-taskflows-fuzzing

一个由 GitHub Security Lab Taskflow Agent 驱动的 LLM 驱动模糊测试流水线

查看仓库
1224天前尚未审核
分享

Seclab Taskflows Fuzzing

一个由 LLM 驱动的、OSS-Fuzz 风格的针对原生 C/C++ 项目的模糊测试流水线。 使用 AFL++ 执行,clang+lcov 进行覆盖率统计,LLM 代理负责 测试框架编写、覆盖率反馈决策、分类和报告。

  • 完全自主:给它一个 GitHub 仓库,它就能处理从目标识别到漏洞报告的所有事情。
  • OSS-Fuzz 风格技术:按格式的变异器/字典、结构感知的 token 拼接、覆盖率驱动的测试框架改进。
  • 生成机器可读的崩溃报告,包含可利用性判定和建议的补丁。
  • 实时 HTML 仪表板,用于实时活动监控。
  • 使用 Python 编写(taskflows/toolboxes/configs),并为 AFL++ 生成 C 测试框架。
  • 状态:积极开发中。

背景

此仓库包含 GitHub Security Lab Taskflow Agent 的模糊测试任务流。 它依赖于 seclab-taskflows 配套仓库中的一些共享构建块 (fetch_source_code 任务流、local_file_viewer / gh_file_viewer 工具箱,以及默认的 model_config)——这些会作为 Python 依赖项 自动安装。

欢迎贡献!请参阅 CONTRIBUTING.md 了解指南。

要求

  • Python 3.11+
  • 一个可访问 apt 的 Linux 环境(或 Codespace)
  • AFL++、clang、lcov、ctags、cscope、graphviz(如果缺失,流水线会自动安装)
  • Git 和 GitHub CLI(gh)

安装```bash

pip install git+https://github.com/GitHubSecurityLab/seclab-taskflows-fuzzing

root@kitploit:~
这会传递性地引入 `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` 的点分引用在运行时都会从父级发行版中解析。

---

## 目录

1. [这是什么](#what-this-is)
2. [快速开始](#quick-start)
3. [架构](#architecture)
4. [流水线,逐阶段解析](#the-pipeline-stage-by-stage)
5. [覆盖率反馈循环](#the-coverage-feedback-loop)
6. [结构感知模糊测试](#structure-aware-fuzzing)
7. [跨迭代和跨活动的持久化语料库](#persistent-corpus-across-iterations-and-campaigns)
8. [分类与漏洞报告](#triage-and-vulnerability-reports)
9. [实时仪表盘](#live-dashboard)
10. [输出文件](#output-files)
11. [数据库模式](#database-schema)
12. [MCP 工具(智能体的词汇表)](#mcp-tools-the-agents-vocabulary)
13. [可调参数(环境变量)](#tunable-knobs-environment-variables)
14. [扩展流水线](#extending-the-pipeline)
15. [基准项目与结果](#benchmark-projects-and-results)
16. [局限性与注意事项](#limitations-and-gotchas)
17. [安全警告](#security-warning)
18. [开发:测试、代码检查、贡献](#development-testing-linting-contributing)
19. [术语表](#glossary)

---

## 这是什么

此任务流是一个完全自主的模糊测试流水线。给定一个原生 C/C++ 项目的 GitHub 仓库,它将:

1. 在缺失时安装 AFL++ + clang/llvm/lcov + ctags/cscope/graphviz,
2. 获取源代码,
3. 识别候选模糊测试目标(解析器、解码器、验证器等),
4. 分析构建系统,
5. 为每个目标编写一个或多个测试桩候选,将每个构建为 AFL 插桩的 `.afl` 二进制文件和覆盖率插桩的 `.cov` 二进制文件,
6. (可选)通过 60 秒覆盖率对候选进行资格筛选并保留最佳者,
7. 运行模糊测试/覆盖率/改进循环,时间预算逐轮翻倍,
8. 对每个崩溃进行分类,确认先前已知的崩溃仍可复现,并编写每个崩溃的 markdown 漏洞报告,包含判定、可利用性、建议补丁和回归测试草图,
9. 为下一轮活动构建 Fuzz-Introspector 风格的调用图 + 未触及 API 报告,
10. 将所有内容发布到实时 HTML 仪表盘。

该流水线在精神上是 **OSS-Fuzz 风格**的:它使用许多相同的技术(按格式的变异器和字典、结构感知的令牌拼接、覆盖率驱动的测试桩改进、机器可读报告、去重的栈哈希崩溃),但它要小得多且自包含。

---

## 快速开始```bash
# 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 会被 自动转发——在任意浏览器中打开它即可实时查看进度。

如需快速冒烟测试,请使用一个小型目标:```bash ./scripts/fuzzing/run_fuzzing.sh DaveGamble/cJSON

root@kitploit:~
---

## 架构

三层结构,自上而下:```
┌────────────────────────────────────────────────────────────────────┐
│  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                           │
└────────────────────────────────────────────────────────────────────┘

关键设计规则:

  • MCP 工具中无全局状态。 每个工具函数都接受显式参数;持久化状态保存在 fuzz_context.db 中。
  • LLM 智能体负责决策,MCP 工具负责执行。 智能体决定要 fuzz 什么、要编写什么 harness、下一步要追查什么缺口;MCP 工具只暴露 run_afl_for、compile_harness、store_crash 等。
  • 在成本低廉处尽量保证幂等性。 对同一仓库重新运行流水线时,会 upsert 目标/harness/运行记录,而不是重复创建。这正是持久化语料库和跨 campaign 延续得以工作的原因。
  • 每个 harness 有两个二进制文件。 AFL 的边缘插桩不适合生成人类可读的覆盖率报告,因此每个 harness 都会构建两次:一次使用 afl-clang-lto -fsanitize=address,undefined(即 .afl 二进制文件),一次使用 clang -fprofile-instr-generate -fcoverage-mapping(即 .cov 二进制文件)。.afl 二进制文件用于 fuzz;.cov 二进制文件重放 AFL 队列,以生成真实的源码行/函数/分支覆盖率。

流水线,逐阶段说明

每个阶段都是一个自包含的 taskflow YAML,由智能体端到端运行。各阶段仅通过 fuzz_context.db 中的 SQLite 数据库通信——不存在内存中的交接。


覆盖率反馈循环

这是流水线的核心。时间预算每次迭代翻倍:``` 30s → 60s → 120s → 240s → 480s → 960s (≈ 32 min/target)

root@kitploit:~
每次迭代、每个 harness,agent 会:

1. 调用 `get_persistent_corpus_dir(harness_id)` 获取该 harness 的稳定
   corpus 目录。
2. 调用 `run_afl_for(afl_binary_path, seed_dir=<persistent corpus>,
   output_dir=<run dir>, seconds=<budget>, dictionary=<auto.dict>)`。
3. 调用 `run_coverage(cov_binary_path, inputs_dir=<run>/default/queue,
   output_dir=<run>/coverage)` 生成 LCOV tracefile 和 HTML 报告。
4. 调用 `store_coverage_from_lcov(run_id, lcov_path, html_path)` 持久化
   一条 `coverage_report` 记录 + 每个未覆盖项的 `coverage_gap` 记录。
5. 调用 `fold_queue_into_persistent_corpus(...)` 将 AFL 的迭代
   queue 合并到持久化 corpus 中,并运行 `cmin` 以保持大小有界。
6. 读取 `get_coverage_summary` + `get_coverage_gaps`,然后要么:
   - 添加一个新种子(标记为 `coverage_feedback`)以到达未覆盖的
     分支,
   - 编辑 harness 源码以调用额外的 API,
   - 调用 `enrich_dictionary_from_uncovered(...)` 自动为 AFL 满足 guard 所需的 magic 常量添加字典
     条目,或者
   - 跳过该 gap(冷错误路径 / 厂商代码)。
7. 调用 `store_iteration_note(repo, iteration_number, harness_id, note=<one
   line summary>)`,以便 dashboard 的迭代时间线跟踪
   变更内容。

**平台期检测。** 一旦连续两次迭代的行覆盖率绝对百分点增益均 < `FUZZ_PLATEAU_THRESHOLD_PCT`(默认 `1.0`),循环就会提前退出。

---

## 结构感知模糊测试

三种互补机制可产生比原始字节变异更强的输入。

### 1. 按格式的字典 + 自定义变异器

对于 `input_kind` 匹配已知格式的目标,taskflow 附带
预构建的字典和 `LLVMFuzzerCustomMutator` C 源文件:

| 格式 | 字典 | 变异器 | 备注 |
|--------|------------|---------|-------|
| `json` | `json.dict` | `json_mutator.c` | Token 拼接、平衡括号复制/删除、类型翻转 |
| `xml` | `xml.dict` | `xml_mutator.c` | 标签、实体、DTD、billion-laughs token |
| `regex` | `regex.dict` | `regex_mutator.c` | 锚点、字符类、量词、真实 ReDoS 模式 |
| `binary_tlv` | _(none)_ | `binary_tlv_mutator.c` | 长度前缀记录:长度溢出 / 复制 / 删除 |
| `png` | `png.dict` | _(reuses binary_tlv)_ | PNG 字典 + binary_tlv 变异器 |

这些会被 `write_initial_harnesses`(字典复制到种子旁边)和
`build_harnesses`(变异器链接到 AFL 二进制文件中)自动拾取。每个变异器将 50% 的变异委托给 AFL 的默认字节
变异器,这样我们就不会丢失引擎的随机化能力。

要添加新格式:将 `<name>.dict` 和/或 `<name>_mutator.c` 放入
`src/seclab_taskflows/dictionaries/`,然后在
`fuzz_runner.py` 底部的 `_FORMAT_ASSETS` 映射中注册它。

### 2. 源码感知(项目特定)智能变异器

对于不熟悉的格式,或者当你想要更强的项目特定
token 时,`generate_smart_mutator` 会扫描目标仓库自身的 `.c`/`.h`
文件,并生成一个 `LLVMFuzzerCustomMutator` C 文件,其拼接
字典提取自:

- 具有 ≥3 个字母字符的字符串字面量(在过滤编译器/许可证
  噪声、路径、头文件、asm 约束、格式说明符之后),
- 来自 `#define`、`case` 和 `enum` 的 32 位数值常量(在
  过滤 0、1、256、0xff… 等通用小整数噪声之后)。

有三种 focus 可用:

| Focus | 拼接内容 | 使用时机 |
|-------|-----------------|-------------|
| `strings` | 仅项目字符串字面量 | 文本格式(JSON、XML、YAML、CSV) |
| `constants` | 仅 32 位数值 magic 值 | 二进制协议、带 magic number 的头文件 |
| `combined` | 两者 | 默认;通常最佳 |

将 `generate_smart_mutators(...)`(复数)与 `HARNESS_CANDIDATES >= 3`
配对,这样每个 focus 都会成为资格轮中的一个候选 harness。

### 3. 项目感知 AFL 字典 + 覆盖率驱动增强

两个互补工具会在 campaign 进行过程中构建并扩展 AFL `-x` 字典:

- **`generate_project_dictionary(source_root, output_path)`** — 在第 1 次迭代前运行一次,静态提取与
  智能变异器相同的源码 token 集,并将其写为 AFL 字典。数值常量
  会以两种字节序同时输出,这样无论主机字节序如何,fuzzer 都能满足
  `memcmp(x, &magic, 4)`。

- **`enrich_dictionary_from_uncovered(source_root, dictionary_path,
  uncovered_locations)`** — 在每次迭代的覆盖率步骤之后运行,
  扫描未覆盖行附近的条件 guard
  (`strncmp/memcmp/strstr`、`case 0xN:`、`== 0xN`、`== 'X'`),并将任何新 token 追加到字典中。幂等:
  绝不会重新添加已存在的条目。

### 4. Corpus 拼接操作

当将 `corpus_dir` 传递给 `generate_smart_mutator` 时,生成的 C
还会获得一个 corpus 拼接操作符:首次调用时,它会从该目录加载最多 64 个文件
(每个上限为 4 KiB),此后可以将这些文件的随机子区域拼接到变异后的输入中。这为
变异器提供了一个重组式操作符,而 AFL 自带的 havoc 在这方面做得不好。与 `get_persistent_corpus_dir(...)` 配对,这样拼接库
就是“重新混合 AFL 已经发现的内容”。

---

## 跨迭代和 campaign 的持久化 corpus

每个 harness 都有一个稳定的 corpus 目录,位于:```
<workspace>/corpus/harness_<id>/

fuzz_iteration 将此处用作 run_afl_for 的 seed_dir(而非 <harness>/seeds)。每次迭代结束时,fold_queue_into_persistent_corpus(...) 会将 AFL 的迭代队列合并到此目录,并运行 afl-cmin 以保持其大小有界。

结果是:昨天的队列会延续到今天的运行中,并且跨同一项目的多次重运行持续存在。停止并重启活动不会丢失任何进度。


分类与漏洞报告

在模糊测试/覆盖率/改进循环结束后,三个阶段会自动运行:

1. triage_crashes

对于 <run>/default/crashes/ 中的每个崩溃文件:

  • 使用 afl-tmin 最小化输入,
  • 使用 replay_under_asan 捕获堆栈跟踪和 stack_top_hash (前 N 个规范化帧;模板、libcxx 内联命名空间、匿名 命名空间和 LTO 数字后缀会被剥离,以便语义 相同的崩溃具有相同的哈希值),
  • 按哈希去重,持久化一条 crash 记录,包含缺陷类别分类 + 置信度说明(高 / 中 / 低)。

2. confirm_fixed_crashes

通过当前的 AFL+ASan 二进制文件重放每个先前已分类的崩溃(其判定结果尚未为 fixed/duplicate/non_reproducible)。 如果它不再崩溃,则标记 verdict="fixed"。当针对自上次活动以来已应用上游修复的项目重新运行活动时,此功能非常有用。

3. write_vuln_reports

对于每个唯一崩溃,代理会读取测试框架源代码 + 崩溃 函数的源代码,从公共 API 遍历调用链,然后分配 十种 OSS-Fuzz 风格判定结果之一,并编写 markdown 漏洞报告:

每个漏洞报告包括:

  • 判定结果 + 缺陷类别 + CWE + 严重性 + 置信度
  • 带有文件:行号引用的根本原因分析
  • 从公共 API 的可达性(具体调用链)
  • 可利用性评估(读 vs. 写、攻击者控制、缓解措施)
  • 建议修复,以统一 diff 形式呈现(标记为“需要审查”)
  • 回归测试草图

实时仪表板

仪表板由 run_fuzzing.sh 自动在后台启动。使用 FUZZ_NO_DASHBOARD=1 禁用;使用 FUZZ_DASHBOARD_PORT 覆盖端口(默认 8765)。

在 Codespace 中,端口 8765 会自动转发——在任何浏览器中打开转发的 URL。页面每 5 秒自动刷新,并显示:

  • 判定结果摘要标签 — 每个判定类别的计数、总运行次数、 路径、总执行计数、崩溃
  • 实时“运行中”脉冲指示器 — 按仓库和按测试框架显示正在进行的 fuzz_run
  • 覆盖率趋势表,带有内联 SVG 迷你图和每次迭代的 增量列
  • 调用图与未触及的 API 表面 — Fuzz-Introspector-lite 快照
  • 崩溃表 — 按判定结果排序(vulnerability 优先),链接 到每个漏洞报告和最小化输入
  • 崩溃热力图 — 按(测试框架 × 迭代)的崩溃计数网格, 不透明度随计数缩放
  • 迭代时间线 — 代理编写的一行注释按时间顺序排列, 描述每次迭代的变化
  • 未覆盖函数排行 — 默认折叠

JSON API

仪表板还暴露了一个小型只读 JSON API 供脚本使用:```bash

All known repos

curl http://127.0.0.1:8765/api/json

Per-repo: harnesses, per-iteration coverage, crashes with verdicts

curl 'http://127.0.0.1:8765/api/json?repo=kkos/oniguruma' | jq .

root@kitploit:~
---

## 输出文件

全部位于 `~/.local/share/seclab-taskflow-agent/seclab-taskflows/` 下。

| 路径 | 内容 |
|------|----------|
| `fuzz_context/fuzz_context.db` | SQLite — 目标、测试框架、运行记录、覆盖率、崩溃、判定结果、调用图、测试框架建议、迭代笔记 |
| `fuzz_runner/builds/` | 构建的 `.afl` 和 `.cov` 二进制文件 |
| `fuzz_runner/runs/` | AFL 输出目录 + LCOV 文件 + HTML 覆盖率报告 |
| `fuzz_runner/corpus/harness_<id>/` | 每个测试框架的持久化语料库(跨迭代和活动周期保留) |
| `fuzz_runner/repo/<owner>__<repo>/REPORT.md` | Markdown 活动摘要,崩溃按判定结果分组 |
| `fuzz_runner/repo/<owner>__<repo>/vuln_<crash_id>.md` | 每个崩溃的 Markdown 漏洞报告 |
| `fuzz_runner/repo/<owner>__<repo>/call_graph.{dot,svg,md}` | 静态调用图 + 已到达/未到达覆盖层 |

---

## 数据库模式

`fuzz_context.db` 中的表(通过 SQLAlchemy 使用 SQLite):

| 表 | 关注的列 |
|-------|--------------------|
| `fuzz_target` | `repo, file, function, signature, input_kind` |
| `harness` | `target_id, repo, harness_path, afl_binary_path, cov_binary_path, build_status, version, sanitizers` |
| `seed_corpus` | `target_id, source, path, bytes_count, added_in_iteration` |
| `fuzz_run` | `harness_id, iteration_number, exec_per_sec, paths_total, crashes_count, status, output_dir, started_at, ended_at` |
| `coverage_report` | `run_id, lines_total, lines_hit, line_pct, fns_*, branches_*, lcov_path, html_path` |
| `coverage_gap` | `report_id, file, function, line, kind, reason_hint` |
| `crash` | `run_id, input_blob_path, minimized_path, stack_top_hash, sanitizer_output, verdict, bug_class, cwe, severity, vuln_report_path, reproducer_path, classification, notes` |
| `call_graph` | `repo, target_id, dot_path, svg_path, functions_total, functions_in_graph, functions_reached, functions_unreached, untouched_surface_json` |
| `harness_suggestion` | `repo, function_name, file, rationale, input_kind, priority` |
| `iteration_note` | `repo, harness_id, iteration_number, note, created_at` |

模式迁移位于 `fuzz_context.py` 中的 `_migrate()`。新表由
`Base.metadata.create_all()` 自动创建;只有新增列需要
基于 PRAGMA 的 `ALTER TABLE`。

---

## MCP 工具(智能体的词汇表)

智能体从不直接调用 AFL 或 clang — 它通过调用 MCP 工具来组合流水线。
完整工具集按用途分组如下:

### 持久化(`fuzz_context.py`)

- `store_fuzz_target`, `get_fuzz_targets`
- `store_harness`, `update_harness_build`, `get_harnesses`
- `store_seed`, `start_fuzz_run`, `finish_fuzz_run`, `get_fuzz_runs`
- `store_coverage_from_lcov`, `get_coverage_summary`, `get_coverage_gaps`,
  `coverage_plateau_reached`
- `store_crash`, `update_crash_verdict`, `get_crashes`,
  `get_crashes_grouped`, `suggest_severity`
- `store_call_graph`, `get_call_graphs`, `get_repo_reached_functions`
- `store_harness_suggestion`, `get_harness_suggestions`
- `store_iteration_note`, `get_iteration_notes`

### 构建 / 模糊测试 / 覆盖率(`fuzz_runner.py`)

- `check_tooling`, `workspace_paths`
- `compile_harness` — 构建 `.afl` 和 `.cov` 二进制文件
- `run_afl_for`, `cmin`, `tmin`, `replay_under_asan`, `reproduce_crash`
- `run_coverage` — 针对 `.cov` 二进制文件重放 AFL 队列,导出 LCOV
- `extract_dictionary` — 从二进制文件中挖掘可打印字符串
- `package_reproducer` — 打包单个崩溃的 `.tgz`

### 持久化语料库(v8)

- `get_persistent_corpus_dir`, `fold_queue_into_persistent_corpus`

### 格式资产(C5)

- `list_format_assets`, `get_format_dictionary`, `write_format_mutator`

### 智能变异器 + 项目感知字典

- `generate_smart_mutator`, `generate_smart_mutators`
- `generate_project_dictionary`, `enrich_dictionary_from_uncovered`

工具函数使用 `@mcp.tool()`(FastMCP)装饰。在测试中,
通过 `.fn` 属性调用它们,例如
`fr.run_afl_for.fn(afl_binary_path=..., ...)`。

---

## 可调参数(环境变量)

| 变量 | 默认值 | 用途 |
|----------|---------|---------|
| `HARNESS_CANDIDATES` | `1` | 每个目标生成的候选测试框架数量。设为 2 或 3 以进行 OSS-Fuzz-Gen 风格的竞争。资格筛选阶段对每个候选运行 `QUALIFIER_SECONDS` 秒,并按行覆盖率百分比保留最佳者。 |
| `QUALIFIER_SECONDS` | `60` | 资格筛选阶段中每个候选的墙钟时间预算。 |
| `FUZZ_PLATEAU_THRESHOLD_PCT` | `1.0` | 行覆盖率增益(以绝对百分点计)低于此值时,连续两次迭代被视为进入平台期,循环提前停止。 |
| `FUZZ_DASHBOARD_PORT` | `8765` | 实时仪表盘的端口。 |
| `FUZZ_NO_DASHBOARD` | (未设置) | 设为 `1` 以跳过启动仪表盘。 |
| `FUZZ_RUNNER_TIMEOUT` | `1200` | `fuzz_runner` 中每个工具子进程的超时时间(秒)。 |
| `LOCAL_SHELL_TIMEOUT` | `180` | `local_shell` 中每条命令的超时时间(秒)。 |

以及标准智能体变量(`COPILOT_TOKEN`、`LOG_DIR`、
`FUZZ_CONTEXT_DIR`、……)。完整列表请参阅项目根目录 README。

---

## 扩展流水线

### 添加新格式(变异器 + 字典)

1. 放入 `dictionaries/<name>.dict`(AFL `-x` 格式)和/或
   `dictionaries/<name>_mutator.c`(libFuzzer 自定义变异器)。
2. 在 `fuzz_runner.py` 底部的 `_FORMAT_ASSETS` 中注册:   ```python
   "<name>": {
       "dictionary": "<name>.dict",
       "mutator": "<name>_mutator.c",
       "description": "Short one-liner about the format",
   },
  1. agent 会通过 list_format_assets() 自动获取它。

添加新的 MCP 工具

  1. 在 fuzz_context.py(用于持久化)或 fuzz_runner.py(用于子进程工作)中添加一个用 @mcp.tool() 装饰的函数。
  2. 为每个参数使用 Annotated[type, Field(description=...)] —— 描述就是 LLM 看到的内容。
  3. 在 tests/test_fuzz_context.py / tests/test_fuzz_runner.py 中添加单元测试。通过工具的 .fn 属性调用它(FastMCP 约定)。
  4. 在相关 taskflow YAML 的 user_prompt 中引用新工具。

添加新的流水线阶段

  1. 在 src/seclab_taskflows/taskflows/fuzzing/ 中创建一个新的 YAML。使用现有文件之一(例如 triage_crashes.yaml)作为模板。
  2. 将其接入 scripts/fuzzing/run_fuzzing.sh 中正确的两个现有阶段之间。
  3. (可选)在 scripts/fuzzing/dashboard.py 中添加阶段特定的仪表板部分。

Schema 迁移

添加新的 SQL 表时:

  • 在 fuzz_context_models.py 中添加 SQLAlchemy 模型。
  • 无需其他操作 —— Base.metadata.create_all() 在引擎初始化时被调用,并自动创建新表。

向现有表添加新 COLUMN 时:

  • 更新 SQLAlchemy 模型。
  • 在 fuzz_context.py 的 _migrate() 中添加 PRAGMA table_info + ALTER TABLE ADD COLUMN 块,以便旧数据库被透明升级。
  • 如果该列被仪表板读取,还需更新 scripts/fuzzing/dashboard.py 中的 _migrate_if_writable()。

基准项目和结果

benchmark/projects.yaml 列出了参考项目。选择它们是为了让完整的 v4+ 流水线能够在 codespace 开发镜像上端到端运行,无需人工干预。

在 codespace 开发镜像上运行完整 v4 流水线的参考数据(约 32 分钟/目标):

xz / cJSON / libexpat 的零崩溃结果是预期的:这些项目在上游已被大量模糊测试。oniguruma 中两个被归类为 vulnerability 的发现是 onig_snprintf_with_pattern 警告格式化代码路径中真实的越界读取(当模式以反斜杠结尾时,读取超过 pat_end 一个字节);每个崩溃的 markdown 报告包含建议的补丁。

要添加新的基准项目,请在 benchmark/projects.yaml 中添加一个条目,并(可选)在 benchmark/README.md 中记录原因。任何现有 analyze_build_system 阶段能够使用 clang + AFL++ 标志构建的项目都是合理的候选。纯 C 解析器、解码器和序列化器往往效果最好。


限制和注意事项

  • 仅限 C / C++。 AFL++ 是原生插桩模糊测试器。
  • 依赖构建系统。 具有非平凡构建系统的项目(自定义 Bazel 规则、vendored libc、专有构建工具)可能无法使用 clang/AFL 标志构建。agent 会将这些目标标记为 BUILD_FAILED: 并跳过它们。
  • Codespace AFL 警告。 AFL++ 需要 kernel.core_pattern=core 和 CPU governor 调整。在 Codespace 中这些不可用,因此 taskflow 默认导出 AFL_SKIP_CPUFREQ=1 和 AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1。AFL 会打印警告,但仍通过 libFuzzer 风格的 abort 处理找到崩溃。
  • 受模型限制。 agent 的 harness 编写质量受限于底层模型对目标代码的理解。
  • 仅 POSIX 的智能变异器语料拼接。 语料拼接操作使用 <dirent.h>。适用于 Linux/macOS;无法在 Windows 上编译。
  • stdin 模式注意事项。 通过 compile_harness 构建的 AFL 二进制文件在 argv 模式下使用 libAFLDriver。因此 replay_under_asan 和 tmin 默认 stdin_input=False,因为 libAFLDriver 在通过 stdin 驱动时会无限循环。
  • generate_smart_mutator + generate_smart_mutators 使用 Python —— C 模板中的每个字面 / 都必须加倍( / )。如果你编辑模板并开始看到 ,原因就在于此。

安全警告

此 taskflow 运行 afl-fuzz、clang、llvm-cov,以及由 LLM 选择的任意构建命令,直接在主机上(无容器)。被提示注入的 agent 原则上可以做你的用户能做的任何事情。仅在以下情况下运行:

  • 在一次性环境中(GitHub Codespaces、一次性 VM 等),
  • 无提升权限,
  • 网络访问范围限定为 git、apt 和构建系统所需的内容。

local_shell 工具箱不在确认提示之后 —— taskflow 是自主的,没有人在环路中运行,因此交互式确认只会永远阻塞。每个 shell 命令都记录到 $LOG_DIR/mcp_local_shell.log 以供事后审查。


开发:测试、linting、贡献```bash

Run the test suite (Python 3.11+ required by hatch-test envs)

hatch test

Run the linter

hatch fmt --linter --check

Auto-fix lint issues

hatch fmt --linter

Lint a single file

hatch fmt --linter --check -- src/seclab_taskflows/mcp_servers/fuzz_runner.py

root@kitploit:~
代码库约定(另请参阅 `benchmark/improvements.md` 中这些约定的活动历史版本):

- 使用 `os.environ.get(NAME) or "default"` 而非
  `os.environ.get(NAME, "default")`。否则 YAML 模板替换产生的空字符串
  会被返回。
- 在新注解中使用 `X | None`(PEP 604),而非 `Optional[X]`。
- 测试通过 `.fn(...)` 调用 MCP 工具,而非直接使用装饰后的名称。
- 避免在测试中使用 `/tmp/...` 字面量——使用 `tmp_path` pytest fixture
  (lint 规则 `S108`)。
- 测试方法内的所有内联导入,如果无法将其移至文件顶部(例如在
  `pytest.skip` 之后条件导入时),都需要添加 `# noqa: PLC0415`。
- 复合真值测试每行仅一个断言(lint 规则 `PT018`)。

改进追踪器(`benchmark/improvements.md`)是跨版本记录流水线中新增内容的
持久日志。当你添加实质性功能时,请在其中添加一节,描述变更内容、
所在位置以及哪些测试对其进行守护。

---

## 术语表

- **AFL++** — 覆盖率引导的灰盒模糊测试器;此处的执行引擎。
- **libAFLDriver** — 静态库,允许 AFL++ 测试框架使用
  libFuzzer 入口点约定(`LLVMFuzzerTestOneInput`)。
- **LCOV** — 行业标准的覆盖率跟踪文件格式。我们通过
  `llvm-cov export -format=lcov` 导出并自行解析。
- **`stack_top_hash`** — ASan/UBSan 堆栈跟踪中顶部 N 个规范化帧的
  16 字符哈希。用于崩溃去重。
- **持久语料库** — 位于
  `<workspace>/corpus/harness_<id>/` 的每个测试框架目录,用于在迭代和
  同一活动的重新运行之间保留 AFL 的有趣输入。
- **智能变异器** — 一种 `LLVMFuzzerCustomMutator`,其拼接令牌从
  目标自身的源代码中提取(`generate_smart_mutator`)。
- **自定义变异器(libFuzzer)** — 用户提供的 C 函数,由引擎调用,
  可完全自由地决定如何变异缓冲区;AFL++ 支持相同的 ABI。
- **MCP 工具** — 经 FastMCP 装饰的函数,LLM 代理可调用。
- **OSS-Fuzz / Fuzz-Introspector** — Google 的开源模糊测试
  基础设施及其配套的调用图/覆盖率分析工具。
  此任务流的若干功能(按格式变异器、按堆栈去重、
  调用图 + 未触及 API 报告、多候选测试框架)均受其启发。

---

## 许可证

本项目根据 MIT 开源许可证的条款授权。请参阅 [LICENSE](https://github.com/githubsecuritylab/seclab-taskflows-fuzzing/blob/main/LICENSE.txt) 文件了解完整条款。

## 维护者

请参阅 [CODEOWNERS](https://github.com/githubsecuritylab/seclab-taskflows-fuzzing/blob/main/CODEOWNERS) 或联系 GitHub Security Lab 团队。

## 支持

请参阅 [SUPPORT.md](https://github.com/githubsecuritylab/seclab-taskflows-fuzzing/blob/main/SUPPORT.md) 了解如何获取此项目帮助的详细信息。

## 致谢

本项目基于 [AFL++](https://github.com/AFLplusplus/AFLplusplus)、[OSS-Fuzz](https://github.com/google/oss-fuzz) 和 [Fuzz-Introspector](https://github.com/ossf/fuzz-introspector) 的概念和技术构建。
下载工具
#阶段Taskflow YAML
1安装 AFL++ + 工具链scripts/fuzzing/install_afl.sh
2获取源码seclab_taskflows.taskflows.audit.fetch_source_code
3识别 fuzz 目标seclab_taskflows_fuzzing.taskflows.fuzzing.identify_fuzz_targets
4分析构建系统seclab_taskflows_fuzzing.taskflows.fuzzing.analyze_build_system
5a编写初始 harness(如请求则 ×N 个候选)seclab_taskflows_fuzzing.taskflows.fuzzing.write_initial_harnesses
5b构建 harness(AFL + 覆盖率)seclab_taskflows_fuzzing.taskflows.fuzzing.build_harnesses
5c筛选候选(当 HARNESS_CANDIDATES > 1 时)seclab_taskflows_fuzzing.taskflows.fuzzing.qualify_harnesses
6Fuzz/覆盖率/改进循环(×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编写 campaign 报告seclab_taskflows_fuzzing.taskflows.fuzzing.write_report
判定结果含义
vulnerability真实存在,可通过公共 API 利用
library_hardening真实缺陷,但没有现实的公共 API 路径;库仍应自我防御
harness_bug缺陷在我们的测试框架中,而非库中
non_reproducible重放无法在最小化输入上复现崩溃
oom内存耗尽;仅当攻击者可控的大小无界时才为漏洞
timeout通过算法爆炸导致的 DoS
assertion_failure触发了 assert();安全相关性各异
fixed由 confirm_fixed_crashes 设置:输入不再复现
duplicate与另一个具有不同堆栈哈希的崩溃具有相同根本原因
needs_investigation无法确定;标记为需要人工审查
#RepoWhy it's interestingNotes
1tukaani-project/xz真实世界中解析器密集型库(liblzma);丰富的过滤器链 + 整数/VLI 解析面基线
2DaveGamble/cJSON小型单文件 C JSON 解析器;简单的 CMake流水线的快速冒烟测试
3akheron/jansson紧凑的 C JSON 库,具有文档化的 json_loadb() 字节缓冲区入口点CMake;非常快的 exec/sec
4libexpat/libexpat成熟的流式 XML 解析器;许多历史 CVECMake 或 autotools
5kkos/oniguruma正则引擎;接受攻击者模式 + 主题Autotools;模式编译是热点路径
RepoTargetsHarnessesAFL runsCrashesVerdicts
tukaani-project/xz88480—
DaveGamble/cJSON66360—
akheron/jansson773510harness_bug、library_hardening、duplicate、needs_investigation
libexpat/libexpat33180—
kkos/oniguruma10106013vulnerability(×2 在 regerror.c 中的 OOB 读取)、library_hardening、harness_bug、non_reproducible
.format()
{
}
{{
}}
KeyError