iamkorun/hydra
GitHub: iamkorun/hydra
一个基于三层 LLM 监督的自主 CTF 批量解题工具,用于高效解决各类安全挑战。
Stars: 0 | Forks: 0
# Hydra
[](https://github.com/iamkorun/hydra/actions/workflows/ci.yml)    
**自主式 CTF 批量解题器。** 输入 JSON,输出 flag。
```
hydra challenges.json
# ✓ baby-rsa → flag{w1ener_w1ns} (47秒)
# ✓ login → flag{sqli_r0ck5} (2分13秒)
# ✗ pwn2 → (超时,超过60分钟)
# # 在48分21秒内解决42/50题 → ./flags.json
```
*(以上 flag 仅为示例)*
**专为**以下用户打造:希望一夜清空某个类别的 CTF 选手,
在 pwn/crypto/web/rev/forensics/misc 领域对智能体能力进行基准测试的研究员,
以及研究如何让长时运行的 LLM 智能体保持正轨的工具开发者。
每个题目都在其独立的 Docker 容器中运行,容器内搭载 Claude Code。
分诊智能体 ([`CLAUDE.md`](CLAUDE.md)) 对题目进行分类并分派给 **7 个专家子智能体** 之一 ([`.claude/agents/`](.claude/agents/)),
这些子智能体从 **约 30 种攻击模式手册** ([`.claude/skills/`](.claude/skills/) — RSA / ECC / padding-oracle / LFI-to-RCE / prototype-pollution / volatility / anti-debug / …) 中提取方案。Hydra 在整个批次中收割并聚合结果——支持实时日志流式传输、自动恢复和 pass@k 并行尝试。
**三层监督机制**确保智能体守规矩:
1. **操作员看护** — 一个独立的 Claude 会话,运行 [`prompts/hydra-babysit.md`](prompts/hydra-babysit.md) 手册,每 270 秒监控批次一次,并根据决策矩阵(继续 / 终止 / 升级 / 暂停)采取行动。
2. **确定性看门狗** — 每个 worker 的一个 sidecar 容器,捕获循环 / OOM / 成本上限 / 空闲失败等故障,无需 LLM 调用。
3. **预提交 flag 门控** — `hydra/flag_gate.py` 在候选 flag 写入 `flags.json` 之前,否决格式错误或来源可疑的候选者。
## 架构
```
┌── L1: operator babysit (separate Claude session)
│ ScheduleWakeup 270s → jq logs → decision matrix
│ codified in prompts/hydra-babysit.md
│
challenges.json │
│ ▼
▼ [hydra batch — running, monitored]
┌─────────────┐
│ orchestrator│ ── spawns N workers (--parallel)
└──────┬──────┘
│
▼
┌──────────────────────────┐
│ Docker container │ ◀── L2: watchdog sidecar
│ │ (loop / OOM / cost / idle — 0 token)
│ Claude Code (triage) │
│ └─ specialist agent │
│ └─ flag.txt │
└──────────┬───────────────┘
│
▼
flag_extractor ──▶ L3: flag_gate ──▶ flags.json + results.json
(deterministic, 0 token)
```
详见 [监督](#supervision) 部分了解决策矩阵和信号。
## 前置条件
- Python 3.12+
- Docker CE (或 Podman — 设置 `HYDRA_CONTAINER_ENGINE=podman`)
- Claude Code 认证:登录的 `~/.claude/` (首选) 或 `ANTHROPIC_API_KEY`
## 安装
```
git clone https://github.com/iamkorun/hydra.git
cd hydra
python3 -m venv .venv && .venv/bin/pip install -e ".[dev]"
docker build -t hydra-worker . # 10–20 min on first build
```
## 快速开始
先尝试玩具题目——它们在约 45 秒内运行整个流水线(编排器 + 看门狗 + flag 门控),并且不需要真实的 CTF 目标:
```
hydra examples/challenges-toy.json
```
参见 [`examples/quickstart.md`](examples/quickstart.md) 进行 5 分钟上手演练。
对于真实的 CTF 批次:
```
# 1. 创建 challenges.json (参见下方输入格式)。
# 2. 解题:
hydra challenges.json
# 输出位于:
# ./flags.json —— 仅含标志,可供CTF平台上传
# ./results.json —— 含汇总统计的完整结果
# ./runs// —— 各题目的生成文件 (输入、临时文件、日志)
# ./failures/.md —— 每个未解决题目的事后分析
```
## 认证
Hydra 自动检测认证方式。推荐使用订阅。
| 方法 | 设置 |
|---|---|
| Claude Max / Pro 订阅 | 在主机上运行 `claude` 一次以登录。Hydra 将 `~/.claude` 以只读方式绑定挂载到每个容器中。 |
| Anthropic API 密钥 | `export ANTHROPIC_API_KEY=sk-ant-...`。用作备用,或通过 `--use-api-key` 强制使用。 |
使用 `--credentials-dir /path/to/.claude` 覆盖自动检测的凭证目录。
## 输入格式
顶层是一个 JSON 数组。Hydra 通过嗅探字段名——每个条目需要:
- 一个 **name** 字段(`name`、`title` 或 `id`)— 如果缺失,则根据内容哈希自动生成。
- 至少一个 **description / task / prompt** 或 **files / attachments / paths**
可选字段:`category`、`points`、`hints`、`remote`。
```
[
{"name": "baby-rsa", "description": "Decrypt this.", "files": ["/path/chal.py"]},
{"name": "login", "description": "http://ctf.example.com:8080"},
{"name": "pwn1", "category": "pwn", "points": 200, "description": "ret2libc",
"files": ["/tmp/pwn1"], "remote": "nc chal.example.com 1337"}
]
```
## CLI 参考
| 标志 | 默认值 | 描述 |
|---|---|---|
| `--parallel N` | 题目数量 | 并发 worker 数——默认为输入 JSON 中的题目数量 |
| `--timeout S` | `3600` | 每道题目的墙钟时间(秒) |
| `--model NAME` | `claude-opus-4-7` | Claude 模型 |
| `--attempts K` | `1` | pass@k — 每道题目 K 次并行尝试,首个 flag 获胜 |
| `--retry-failed` | 关闭 | 重新运行标记为失败 / 超时 / 错误的条目 |
| `--only A,B,C` | — | 逗号分隔的要运行的名称(跳过其他) |
| `--runs-dir PATH` | `.//runs` | 每道题目的工件目录 |
| `--results PATH` | `.//results.json` | 聚合输出 |
| `--jsonl PATH` | `.//results.jsonl` | 每道题目一行,流式输出 |
| `--flags-out PATH` | `.//flags.json` | 仅输出 flag |
| `--credentials-dir PATH` | `~/.claude` | 主机目录,挂载到 `/root/.claude:ro` |
| `--use-api-key` | 关闭 | 即使找到订阅也强制使用 API 密钥模式 |
| `--dry-run` | 关闭 | 规范化 + 准备工作目录,但不运行 |
| `--rebuild-image` | 关闭 | 运行前执行 `docker build` |
运行 `hydra --help` 获取规范列表。
## 输出文件
所有输出默认在 `.//` 目录下(例如 `hydra phase-1.json` 写入 `./phase-1/`)。标准输入 (`-`) 回退到当前目录。任何显式指定的 `--runs-dir` / `--results` / `--jsonl` / `--flags-out` 将覆盖默认值。
| 文件 | 内容 |
|---|---|
| `/flags.json` | `{"name": "flag", ..., "__failed__": [names]}` — 可直接上传至平台 |
| `/results.json` | 包含每道题目状态和摘要统计的最终聚合结果 |
| `/results.jsonl` | 每道已完成的题目一行,实时追加 |
| `/runs//` | 输入文件、智能体草稿、完整会话日志 |
| `/runs//logs/claude.stdout.jsonl` | 完整的智能体会话记录,实时流式传输 (`tail -f` 有效) |
| `/failures/.md` | 每道未解题目的事后分析 + 最后 50 行日志 |
| `/failures/SUMMARY.md` | 所有失败的索引,包含原因列 |
## 恢复
使用相同的输出文件重新运行是幂等的:
- `status == "solved"` 的条目将自动跳过。
- 失败的条目(`failed` / `timeout` / `error`)默认也会跳过,避免长时间批次在无望的题目上重复消耗预算。
显式重试失败题目:
```
hydra challenges.json --retry-failed
```
删除 `results.jsonl` 以从头开始。
## pass@k(并行尝试)
每道题目运行 K 次尝试——首个 flag 获胜,其他兄弟尝试将被取消:
```
hydra challenges.json --attempts 3 --parallel 8
```
每次尝试消耗一个 `--parallel` 槽位,因此 K=3 会使跨题目的有效并发降低 3 倍。作为交换,解题率在不稳定的题目上会上升——Palisade (arxiv 2412.02776) 报告在 InterCode-CTF 上,从 k=1 到 k=10,解题率从 83% 提升到 95%。
## 调试失败
```
cat failures/SUMMARY.md # index of all failures
cat failures/.md # postmortem + log tail
less runs//logs/claude.stdout.jsonl # full agent transcript
ls runs//work/ # solver scratch files
```
日志在智能体运行时实时流式写入磁盘,因此在批次运行期间可以使用 `tail -f runs//logs/claude.stdout.jsonl` 实时查看。
## 漏洞利用纪律
Hydra 在提示层面强制执行“推导,而非回忆”——CTF 的解题必须通过针对目标运行代码产生,而非从训练记忆中导入:
- **`.claude/skills/meta/exploit-debug.md`** — 当载荷未生效时,专家智能体会在迭代 *之前* 执行一个 6 步诊断阶梯(可达 → 载荷到达 → 端点存活 → 响应差异 → 预言机检查 → 公开 PoC 差异)。这减少了我们在基于时间的 SQLi 题目上看到的“写 v1 → 无响应 → 写 v2(基本上就是 v1)”的上下文消耗。
- **`.claude/skills/meta/no-prior-knowledge.md`** — 如果专家智能体诉诸训练记忆(“我知道这个房间的凭证是 `mitch:secret`”),它必须将推导尝试 + 风险审计日志记录到 `./work/prior-knowledge.log`。
验证器专家会自动将任何运行中发出该日志的候选标记为 `SUSPECT`,这样分诊智能体会以“推导被跳过的步骤”重新分派任务。跳过日志 = 捏造;验证器通过来源检查可以捕获它。
为什么这很重要:没有这个机制,专家智能体可以通过回忆答案而非利用漏洞来在标准题目上得分,并在任何变体上失效。该日志将静默的捷径变成了可审计的信号。
## 监督
Hydra 的故障模式明确分为两类:**机械性**(循环、OOM、成本失控、格式错误输出)和**语义性**(方向错误、事实幻觉、范围漂移、不完整 flag)。监督栈围绕这种划分设计。
- **机械性故障**由确定性代码捕获——看门狗 sidecar 和 flag 门控,两者都是 0 token,都作为 Python 代码在本仓库中提供。
- **语义性故障**由一个运行编码操作手册的独立 Claude 会话捕获。该手册作为版本化的提示存在于 [`prompts/hydra-babysit.md`](prompts/hydra-babysit.md) 中,而非 Python 代码,因此它保持可复刻和领域可移植性。第二个手册 [`prompts/bb-babysit.md`](prompts/bb-babysit.md) 将相同的模式应用于漏洞赏金工作流。
### 第 1 层 — 操作员看护 (LLM 监督器)
一个独立的 Claude Code 会话,使用 `prompts/hydra-babysit.md` 初始化,与批次并行运行。手册赋予它:
- **预检门控** — 在启动 worker 之前验证目标的协议握手(而不仅仅是端口开放)。防止在平台重用主机时发生 IP 回收。
- **廉价检查循环** — 每 180–270 秒 `ScheduleWakeup`(提示缓存预热),然后对 worker 的 jsonl 文件执行 `jq`/`tail`/`stat` 来评估进展,而无需阅读完整会话。
- **决策矩阵** — 基于 *部分 flag*、*目标宕机*、*训练记忆捷径*、*成本超限*、*求解器刷屏* 等信号,进行首次匹配行分派,执行 CONTINUE / KILL / UPGRADE(sonnet → opus)/ PAUSE。
- **提交前擦除** — 如果已记录了部分 / 错误的 flag,监督器会擦除 `flags.json` 并降级 `results.jsonl` 中的状态,以便 `--retry-failed` 可以重新选择该题目。
使用方法:将手册粘贴到 Claude Code 会话中,告知其题目 JSON + 目标 IP,然后让它运行。工作者是 `hydra` 本身;监督器从不直接调用模型。
### 第 2 层 — 看门狗 (sidecar)
与每个 worker 容器并行运行,并跟踪 `runs//logs/claude.stdout.jsonl` 以检测异常行为信号。在容器耗尽预算前终止它。信号包括:
| 代码 | 触发条件 | CLI 标志 |
|---|---|---|
| `bash_repeat` | 相同的 Bash 命令前缀触发 N+ 次 | `--watchdog-max-bash-repeats` (默认 3) |
| `solver_spam` | 写入超过 N 个匹配 `work/{solve,probe,exploit}NNN.py` 的文件 | `--watchdog-max-solver-variants` (默认 5) |
| `cost_cap` | 估算的 token 成本超过上限 | `--watchdog-cost-cap` (默认 $10) |
| `oom_preempt` | 容器 RSS ≥ 内存限制的 X% | `--watchdog-mem-kill-pct` (默认 90%) |
| `idle_work` | 当智能体仍在使用工具时,`work/` 目录 N 秒内未更改 | `--watchdog-idle-work-timeout` (默认 180 秒) |
使用 `--no-watchdog` 禁用(用于调试智能体本身)。
被终止的运行在 `results.jsonl` 中以 `status: failed` 和 `reason: watchdog:
()` 记录——便于 grep,并且 `--retry-failed` 会重新选择它们。
### 第 3 层 — Flag 门控 (预提交)
每个 flag 候选在写入 `flags.json` 之前都要通过 `hydra/flag_gate.py`:
- REJECT:未闭合的花括号、错误的前缀、格式不匹配、长度越界、控制字符、空白字符。`flags.json` 保持干净;状态 = `failed`。
- WARN:缺少草稿工件,或存在 `prior-knowledge.log`。状态 = `solved_uncertain`;flag 被记录但标记需人工验证。
- ACCEPT:正常。
在你的 JSON 中针对每道题目收紧门控:
```
{"name": "splash", "flag_prefix": "EXAMPLE",
"expected_format": "EXAMPLE\\{[0-9a-f]{32}\\}"}
```
## Hydra 不是什么
关于其范围,需要明确说明:
- **不是 CTF 课程或学习工具。** 它解决问题,但不教学。如果你想学习 pwn,可以阅读 [`notes/lessons-learned.md`](notes/lessons-learned.md) 中的解题报告或 [`.claude/skills/`](.claude/skills/) 下的技能手册——但 Hydra 本身优化目标是 *输出 flag*,而非 *人类理解*。
- **在最难的题目上并非 SOTA。** pass@k 对不稳定的题目有帮助,但 worker LLM 仍然是其上限。高难度 pwn / 定制 crypto / 多阶段链仍然受益于熟练的人类。
- **不便宜。** 使用 `claude-opus-4-7` 时,每道题目的成本通常在 $0.50 – $4 之间,具体取决于类别和超时设置。看门狗的 `cost_cap` 默认为每道题目 $10 — 请自行调整。
- **不是零配置。** 你需要自己组装 `challenges.json`。Hydra 会宽松地嗅探字段名,但它不会为你抓取 CTF 平台。
- **与 Anthropic 无关。** Hydra 使用 Claude Code 作为 worker 运行时,但它是第三方项目。
- **不是漏洞赏金的舰队猎人。** [`prompts/bb-babysit.md`](prompts/bb-babysit.md) 手册故意设计为单 worker、受监督、范围受限的——因为无人监督的舰队会导致项目被封禁。
## 开发
```
.venv/bin/pytest
.venv/bin/python -m ruff check # lint (E + F + B + UP rulesets)
```
## 路线图
参见 [`ROADMAP.md`](ROADMAP.md)。v0.2 的主要项目:在 InterCode-CTF 上进行基准测试,`hydra supervise` 子命令,按类别的成本遥测,以及一个“Hydra on Haiku”更低成本监督器变体。 标签:C2, WSL, 请求拦截, 逆向工具