lakhand7/detonator

GitHub: lakhand7/detonator

detonator 通过代理 MCP 流量并注入对抗性负载,对 AI agent 进行动态可利用性测试,以可重放的日志判定特定攻击场景是否真实可触达。

Stars: 1 | Forks: 0

# 引爆器 [![CI](https://static.pigsec.cn/wp-content/uploads/repos/cas/ad/ad5834178f7599af9fdda11629d49cae07f2997beec49821b2920eff5bfd50e7.svg)](https://github.com/lakhand7/detonator/actions/workflows/ci.yml) ![Python](https://img.shields.io/badge/python-3.11%20%7C%203.12%20%7C%203.13-blue) ![License: MIT](https://img.shields.io/badge/license-MIT-green) **针对 AI agent 及其使用的 MCP server 的动态可利用性测试。** 静态的 AI/MCP 扫描器回答的是“这有危险吗?”——召回率高,误报率也高。 detonator 回答的是更难也更有用的问题:**给定一个 agent 及其工具,特定的 对抗性输入是否真的会促使其采取有害行动?**——并通过捕获的、 可重放的 trace 来证明这个答案。 两种最终判定: - **REACHABLE**——触发了陷阱(tripwire);漏洞被证实,并附带最小化复现(minimal repro)。 - **UNREACHABLE**——对抗性条件已运行但未触发任何陷阱;证明被标记的风险 在此配置下不会触发。 ## 工作原理 detonator 向 agent 提供了一个指向 **`detonate proxy`** 而非真实 server 的 MCP server 条目——agent 连接到我们,*是因为它自己的配置如此指定*(基于配置,而非基于拦截)。 该代理是一个字节级精确的 stdio 中继,它会**精准毒化(poison)一条工具消息**并**记录每一条 JSON-RPC 消息**。随后,确定性的 evaluator 会扫描该日志: ``` TARGET (any agent + runbook) │ benign task fires MCP tool calls ▼ detonate proxy ── relays to the real MCP server, poisons one message, logs everything │ ▼ detonate eval ── deterministic tripwires over the log ──► REACHABLE / UNREACHABLE (the verdict of record) ``` 判定结果完全由纯代码(`detonate eval`)生成,而非由 orchestrator 生成——*裁判退出评审团*。 ## 安装 ``` git clone https://github.com/lakhand7/detonator.git cd detonator uv venv && uv pip install -e ".[dev]" # or: pip install -e ".[dev]" ``` 要求 Python ≥ 3.11。**仅**在运行上游的 Slack 实时示例时才需要 Node.js——detonator 本身及其测试均不需要。 ## 快速开始(完全封闭——无需 Node,无需 token) 运行测试套件,然后直接从 golden fixture 中重现核心结果——*相同的毒化输入产生了截然相反的 判定结果*: ``` pytest -q # agent 服从了 injection -> canary 被泄露 -> REACHABLE detonate eval --replay fixtures/slack_exploit.jsonl --scenario scenarios/slack-ops-indirect-injection.yaml # agent 忽略了它 -> 任何 downstream 调用中均无 canary -> UNREACHABLE detonate eval --replay fixtures/slack_clean.jsonl --scenario scenarios/slack-ops-indirect-injection.yaml ``` 两个 fixture 都带有**字节级完全一致**的毒化 `conversations_history` 结果;它们的区别仅在于 agent 是否据此采取了行动。输入相同,判定结果相反,通过日志扫描加以证明。 ## 工作示例:Slack 运维 agent(实时) 将 detonator 指向一个真实的“总结 #incidents,将摘要发布到 #ops-summary”的 agent,该 agent 连接着 Slack MCP server。使用你自己的 agent + `SLACK_BOT_TOKEN`;detonator 不会对其硬编码任何内容。目标完全由一个 **runbook**(`targets/slack-ops-agent/RUNBOOK.md`)描述,而攻击则由一个 **scenario**(`scenarios/slack-ops-indirect-injection.yaml`)定义。具体命令请查看 runbook。 ## 将*任何* MCP agent 指向它 此仓库中没有任何特定于目标的代码。要测试你自己的 agent,请编写一个 runbook(复制 `targets/RUNBOOK.template.md`),填入几个字段: - `mcp_config_path` / `mcp_server_name`——其 MCP 配置的位置,以及需要代理哪个 server。 - `trigger`(+ 可选的 `launch`/`wait`/`stop`)+ `task`——如何**同步**运行良性任务 (它必须仅在任务真正完成时才退出——请参阅 `DESIGN.md` 第 12 节中的完成契约)。 ## CLI | 命令 | 用途 | |---|---| | `detonate validate ` | 加载并通过安全门检查 scenario(退出码 0 为通过 / 1 为失败) | | `detonate config show ` | 打印 MCP 条目 JSON,以便粘贴到目标配置中 | | `detonate config apply --runbook R --scenario S` | 修改目标的 MCP 配置以启动代理(幂等备份) | | `detonate config restore --runbook R` | 从备份恢复目标的 MCP 配置 | | `detonate proxy --scenario S --server N` | 作为目标的 MCP server 运行(*由*目标启动) | | `detonate eval \| --replay [--json]` | 确定性的判定;写入 `report.json` | | `detonate list` | 列出目录树中的 scenario 和 target | ## 仓库布局 ``` src/detonator/ the package ├─ model/ frozen value objects: scenario, wire messages, context, verdict ├─ proxy/ the async stdio relay — transport, session, poison-and-log ├─ poison/ inject transforms (splice, description) + JSON Pointer targeting ├─ eval/ deterministic tripwires (canary_exfil, unauthorized_tool) + runner ├─ inventory.py scenario/target discovery for `detonate list` └─ cli.py the `detonate` CLI scenarios/ attack definitions (poison + tripwires), e.g. the Slack injection targets/ runbooks describing how to launch a benign task against an agent fixtures/ hand-authored golden JSON-RPC logs for hermetic replay tests orchestrator/ the Claude Code red-team skill (SKILL.md + RED-TEAM.md) tests/ hermetic suite — pure-Python fake MCP upstream, no Node/tokens DESIGN.md the full design spec; docs/ has supporting primers ``` ## Orchestrator(Claude Code skill) 红队循环——*了解真实的工具形态 → 构造毒化变体 → 触发良性任务 → 读取判定结果 → 迭代*——是一个 Claude Code skill(`orchestrator/SKILL.md` + `RED-TEAM.md`),而不是 定制代码。它驱动 `detonate` CLI,并在首次出现 REACHABLE 时(或在 N 个变体之后)停止, 报告 `exploit_rate` 和复现路径。该 skill 可以读取判定结果以决定是否迭代; 但它**从不**亲自生成判定结果。 ## 架构 纯函数核心(注入转换和陷阱评估器是对冻结 值对象进行操作的纯函数)包裹在命令式外壳(异步代理 + CLI)中。三个统一的扩展点,每个 扩展点都是 Protocol + 模块注册表 + `@register` 装饰器: - **Transport**——`stdio`(V1);`http_sse` 延后。 - **InjectTransform**——`splice`,`description`(V1);`overwrite`/`error`/`structured` 延后。 - **Tripwire**——基于 MCP 日志的 `canary_exfil`,`unauthorized_tool`(V1);`egress`/`fs_audit`/ `syscall`/`approval_bypass` 延后(它们需要隔离层)。 完整规范请参阅 `DESIGN.md`,关于 stdio + MCP 如何协同工作的入门介绍请参阅 `docs/stdio-and-mcp.md`,如需独立的可视化演练请查看 `docs/detonator-explainer.html`(在 浏览器中打开)。 ## 范围(V1) 包含:基于配置的 stdio 代理(记录 + 毒化),两种注入策略,两个 `mcp_log` tripwire, CLI,orchestrator skill,Slack 工作示例,以及完全封闭的重放测试。不包含(延后): container/隔离,MCP 外泄露检测,HTTP/SSE 传输,LLM 裁决,出处/签名。 **已知的 V1 限制:**代理日志仅观察那些体现为代理 MCP 工具调用的危害; 设计上无法察觉 MCP 外的泄露(那是延后至未来的 `egress`/`fs_audit` 层)。 ## 开发 ``` uv run --no-sync pytest -q # hermetic suite (also what CI runs, across Python 3.11–3.13) ``` ## 许可证 MIT——请参阅 [LICENSE](LICENSE)。
标签:AI代理, Maven, MCP协议, 人工智能, 安全测试, 攻击性安全, 文档结构分析, 漏洞验证, 用户模式Hook绕过, 计算机取证, 逆向工具