gobelinor/benchCTF

GitHub: gobelinor/benchCTF

benchCTF 是一个在 CTF 挑战中自动化基准测试 AI 智能体的框架,支持多模型与多编排器的公平对比,并输出包含成功率、耗时和成本的综合报告。

Stars: 0 | Forks: 0

# benchCTF 在 CTF 挑战中对 AI 智能体进行基准测试。 ![Claude Code Opus 4.7 与 Codex GPT-5.5 在 CryptoHack `lets-decrypt` 挑战中的对比,各运行 5 次](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/e851c8f74d003948.png) 你只需为 benchCTF 提供一个挑战目录(包含一个 `challenge.md` 以及任何二进制文件、密文、源文件)和一个模型列表。每个模型将在相同的提示词和方法论下,在各自独立且干净的工作目录中自主运行——它会读取文件、编写脚本、运行命令、与远程服务交互,并报告它找到的 flag。 输出是一份 Markdown 报告,从以下方面对比每个模型:挂钟时间、Token 消耗量、成功率,以及合成的美元成本(Token 数量 × 公开的 API 费率),这样基于订阅的栈(如 Claude Code 或 Codex)就可以与按 Token 计费的 API 在同一维度上进行比较。 ## 模块化设计 支持三种编排器(“运行器”),可以在 `models.yaml` 中为每个模型单独配置: | 运行器 (runner) | 运行方式 | 身份验证 | |---|---|---| | `opencode` | `opencode run --format json` | 通过 `opencode auth login` 配置的任何验证方式 (Anthropic / OpenAI / Google / Copilot / OpenRouter / API keys) | | `claude_code` | `claude -p --output-format stream-json` | 继承 Claude Code 的 OAuth (Claude Pro / Max / Team / API key) | | `codex` | `codex exec --json` | 继承 Codex 的 ChatGPT OAuth (Plus / Pro / API key) | 你可以自由组合: - **纯模型比较** — 使用相同的编排器(例如 `opencode`),搭配多个模型,唯一的变量只有模型。 - **跨栈比较** — 使用不同的编排器,例如 Claude Code 对比 Codex 对比 opencode-with-Gemini,将端到端的完整技术栈作为黑盒进行比较。 ## 在虚拟机中运行此程序 ## 安装 依赖条件: - Python ≥ 3.10 - 以及你打算使用的 CLI 工具,并确保其在 `PATH` 中: - `opencode` ≥ 1.3 + 至少完成一个提供商的身份验证 (`opencode auth login`) - `claude` (Claude Code),已登录 - `codex`,已登录 ``` python3 -m venv .venv && source .venv/bin/activate pip install -r requirements.txt cp models.yaml.example models.yaml # then trim to the models you want ``` ## 运行 ``` python bench.py --challenge challenges/example-easy ``` | 标志 | 默认值 | 用途 | |---|---|---| | `--challenge PATH` | (必填) | 挑战目录(必须包含 `challenge.md`) | | `--models PATH` | `models.yaml` | 模型配置 | | `--runs N` | 取自 `defaults.runs` | 每个模型的运行次数(用于计算平均值/中位数/标准差) | | `--timeout SECS` | 取自 `defaults.timeout_seconds` | 每次运行的挂钟时间上限 | | `--no-agents` | 关闭 | 跳过方法学前缀(基线模式) | | `--agents PATH` | `templates/AGENTS.md` | 使用自定义方法论 | | `--only NAMES` | (全部) | 逗号分隔的要包含的模型名称 | | `--out DIR` | `runs` | 输出根目录 | 模型**按顺序**运行,每个模型在从挑战目录复制而来的独立全新工作目录中执行。 ## 示例 ### 相同编排器,不同模型 — 纯模型比较 `models.yaml`: ``` defaults: timeout_seconds: 1800 runs: 3 models: - name: opencode-claude-opus-4-7-max runner: opencode opencode_model: anthropic/claude-opus-4-7 variant: max pricing: input: 5.00 output: 25.00 cache_read: 0.50 cache_write: 6.25 - name: opencode-gpt-5-5-pro-xhigh runner: opencode opencode_model: openai/gpt-5.5-pro variant: xhigh pricing: input: 15.00 output: 120.00 cache_read: 1.50 - name: opencode-gemini-2-5-pro runner: opencode opencode_model: google/gemini-2.5-pro pricing: input: 1.25 output: 10.00 cache_read: 0.125 ``` 相同的运行环境、相同的提示词、相同的工作目录布局——唯一的变量只有模型。 ### 不同编排器,不同模型 — 全栈比较 `models.yaml`: ``` defaults: timeout_seconds: 2700 runs: 1 models: - name: claude-opus-4-7-max runner: claude_code claude_model: claude-opus-4-7 claude_args: ["--effort", "max"] pricing: { input: 5.00, output: 25.00, cache_read: 0.50, cache_write: 6.25 } - name: codex-gpt-5.5-xhigh runner: codex codex_model: gpt-5.5 codex_args: ["-c", "model_reasoning_effort=xhigh"] pricing: { input: 5.00, output: 30.00, cache_read: 0.50 } ``` 这会对比两个真实的技术栈(CLI + 模型 + 宿主机环境配置)。这三种运行器都会加载一些宿主机的环境上下文——有关具体细节,请参阅局限性部分。这也是你在比较完整技术栈时所测试基准的一部分。 ## 输出 每次调用都会创建 `runs//` 目录: ``` runs/20260428-194641/ ├── report.md ← summary + per-run details ├── results.json ← all results in one array └── /run-/ ├── workdir/ ← isolated copy of challenge files ├── stdout.jsonl ← raw runner event stream ├── stderr.log └── result.json ← per-run record ``` 结束时,还会在控制台打印一份 `rich` 表格。 ## 挑战格式 ``` challenges// ├── challenge.md # description (free-form), optional YAML frontmatter └── # binaries, ciphertext, pcaps, etc. ``` 智能体会被指示在最终消息的末尾输出 `FLAG: `(或 `FLAG: NOT_FOUND`)。测试框架会在**最后一条助手消息**中扫描该行内容。Flag 值将按原样记录——如果需要,可以将其与 `result.json` 中的标准 flag 进行验证。 ## 方法论 (`AGENTS.md`) `templates/AGENTS.md` 提供了一套通用的 CTF 方法论(侦察 → 分类 → 利用 → 获取 flag → 约束)。它会**作为前缀附加到提示词中**,因此无论各个 CLI 如何处理自身的约定,每个运行器都会收到相同的指令。使用 `--no-agents` 可将其禁用;使用 `--agents PATH` 可替换为自定义的方法论。 ## 成本:合成成本与原生成本 每次运行都会记录两项成本: - `cost_usd_synthetic` — 基于 `models.yaml` 中的 `tokens × pricing` 计算,始终会被填充。使用此项可跨模型进行比较,包括那些运行在固定费率 OAuth 订阅上的模型。 - `cost_usd_native` — 运行器自身报告的成本。`claude_code` 暴露 `total_cost_usd` 字段;`opencode` 暴露 `info.cost` 字段;`codex` 不报告成本(始终为 `$0`)。 ## 模型配置结构 ``` - name: runner: opencode | claude_code | codex pricing: input: # required output: # required cache_read: # optional, default 0 cache_write: # optional, default 0 reasoning: # optional, defaults to output # runner=opencode: opencode_model: provider/model # e.g. anthropic/claude-sonnet-4-5 variant: high # optional, opencode --variant # runner=claude_code: claude_model: opus # alias or full id claude_args: [--max-turns, "100"] # optional, extra args passed to claude # runner=codex: codex_model: gpt-5.5 codex_args: ["-c", "model_reasoning_effort=high"] # optional ``` 各运行器的 Token 会被统一归化为互不重叠的类别(例如 `input` 仅指未缓存的新输入,`cache_read` 指缓存的输入等),这样无论数据来自哪里,合成成本的计算公式都能保持一致。 ## 局限性 - 没有 Docker 支持。每次运行使用的是隔离的工作目录,但依然信任宿主机。如果没有自己的沙箱环境,请不要运行不受信任的 CTF 挑战(尤其是 pwn 类)。 - 顺序执行,而非并行。这可以避免触发 OAuth 频率限制冲突,并保持报告结果的确定性。 - Flag 是**自我报告**的。除非你主动提供,否则测试框架并不知道标准的 flag。 - **所有的运行器都不是纯净的上下文环境。** 每个运行器都会自动加载宿主机的环境配置: - `claude_code` → `~/.claude/CLAUDE.md`、`~/.claude/skills/*`、hooks、plugins、settings。 - `codex` → `~/.codex/AGENTS.md`、`~/.codex/skills/*`、`~/.codex/config.toml`。 - `opencode` → 会向上遍历工作目录的父级链寻找 `AGENTS.md` / `CLAUDE.md`,**并且**会自动加载 `~/.claude/CLAUDE.md` 以及来自 `~/.claude/skills/` 和 `~/.agents/skills/` 的技能。 当你在不同的运行器之间进行比较时,你实际上是在比较完整的软件栈,而不是单纯的裸模型。为了获得更纯净的比较结果,请使用精简后的宿主机配置运行(在基准测试之前,将你的全局规则和技能目录移出或重命名),或者保持使用单一运行器并仅改变模型。
标签:AI安全, AI智能体, AI编程, API, Benchmark, Chat Copilot, Claude, Codex, CVE检测, GPT, LLM Agent, LLM基准测试, Python, 人工智能, 反取证, 大模型评测, 安全评估, 密码学, 手动系统调用, 无后门, 模型对比, 漏洞管理, 用户模式Hook绕过, 网络安全, 逆向工具, 隐私保护, 黑盒测试