Imtnk/ctf-toolkit

GitHub: Imtnk/ctf-toolkit

一个面向 CTF 比赛的 AI Agent 工具链,结合本地/远程大语言模型与安全分析工具,通过 ReAct 循环自动化完成题目分类、文件分析和漏洞识别等任务。

Stars: 0 | Forks: 0

# CTF 工具链 — Mac 模型服务器 这台 Mac (M3 Pro, 18 GB) 运行 **Ollama** 并通过局域网向运行实际 CTF 工具的 Kali WSL2 环境提供模型服务。 ## 模型 | 模型 | 角色 | 大小 | |---|---|---| | `deepseek-r1:14b` | **主力** — 链式推理,CTF 甄别 | ~9 GB | | `qwen2.5-coder:14b` | 专注代码的备选方案 | ~9 GB | | `dolphin-llama3:8b` | 无审查备选(在遇到拒绝时自动触发) | ~5 GB | | `nomic-embed-text` | Embeddings(原有) | 274 MB | 考虑到操作系统的内存预留空间,RAM 中只能容纳一个 14B 模型。使用 `switch-model.sh` 进行切换。 ## 快速开始 ``` brew services list | grep ollama # Ollama runs as a launchd service (auto-starts at login) curl -s http://localhost:11434 # → "Ollama is running" ipconfig getifaddr en0 # LAN IP for Kali (currently 192.168.1.11; DHCP — may drift) ``` ## `ai.py` — 单次执行与 agent 模式 ### `ai` — 菜单与快捷方式 `ai-ui.py` 是一个轻量级启动器,别名为 **`ai`**(位于 `~/.bashrc` 和 `~/.zshrc` 中)。直接执行 `ai` 会打开一个交互菜单(询问 / 运行 agent / 恢复,并带有本地与远程大脑切换、自动批准以及 dry-run 开关);任何参数都将直接传递给 `ai.py`: ``` ai # interactive menu (shows the current brain) ai "find the vulnerability" # one-shot passthrough ai agent "triage ./chal" # agent passthrough (all ai.py flags work) ``` ### 单次执行(向后兼容) ``` echo "solve this RSA: n=... e=... c=..." | python3 ai.py cat challenge.py | python3 ai.py "find the vulnerability" python3 ai.py "what does XOR with a repeating key look like in ciphertext?" ``` 向 Ollama 发送单个 prompt 并打印回复。不使用工具,不进行循环。 ### Agent 模式 — 包含工具的 ReAct 循环 ``` python3 ai.py agent "what type is ./chal and what are its strings?" python3 ai.py agent --approve auto "triage ./chal — architecture, protections, interesting strings" python3 ai.py agent --dry-run "what would you do with ./chal?" python3 ai.py agent -m dolphin "exploit the vuln in ./vuln.py" cat chal.py | python3 ai.py agent "find and explain the vulnerability" # 恢复崩溃或中断的运行 python3 ai.py agent --resume python3 ai.py agent --resume .agent/run-20260721-143022.jsonl ``` | 标志 | 默认值 | 含义 | |---|---|---| | `-m / --model` | 大脑默认值 | 使用指定的 **本地** Ollama 模型 id 覆盖 | | `--local` | 关 | 强制使用本地 Ollama 大脑,而不是远程 gateway | | `--approve auto` | 手动 | 跳过非白名单命令的提示 | | `--dry-run` | 关 | 显示计划执行的命令;不实际执行任何内容 | | `--max-steps` | 15 | 触发软预算提示前的步数 | | `--resume [FILE]` | — | 恢复最新(或指定)的 `.agent/*.jsonl` 记录 | ## 大脑:远程 gateway 对比本地 Ollama Agent 的**大脑**(推理)与其**双手**(`agent/tools.py`,用于运行实际子进程)是解耦的。默认情况下,大脑是运行在**兼容 OpenAI 的 gateway** 上的大型托管模型;本地计算机仍然负责执行每一个工具。本地的 `dolphin-llama3:8b` 依然作为拒绝时的备选方案。 | 环境变量 | 默认值 | 含义 | |---|---|---| | `CTF_REMOTE_API_KEY` | *(未设置)* | **密钥。** gateway 的 Bearer 密钥。从 `~/.config/ctf-toolchain/secrets.env`(chmod 600,位于此仓库之外)读取。切勿提交。 | | `CTF_REMOTE_MODEL` | `qwen3.6-35b-a3b` | 远程模型 id | | `CTF_REMOTE_BASE_URL` | `https://gateway.9arm.co/v1` | 兼容 OpenAI 的 base URL (`POST {base}/chat/completions`) | | `CTF_BRAIN` | `remote` | 设置为 `local` 可全局强制使用 Ollama 大脑 | | `CTF_AI_HOST` | `localhost` | 用于本地大脑 / 备选方案的 Ollama 主机 | **选择规则:** 当存在密钥,且未使用 `CTF_BRAIN=local`、`--local` 或 `-m ` 时,将使用远程大脑。如果没有密钥,则会降级为本地 `deepseek-r1:14b`(会打印一次警告);如果 Ollama 也无法访问,`ctf-eval` 将进一步降级为其离线启发式算法。 一次性密钥设置(请自行粘贴真实密钥——它永远不需要经过其他任何人的手): ``` printf 'export CTF_REMOTE_API_KEY=%q\n' 'sk-REAL' >> ~/.config/ctf-toolchain/secrets.env # secrets.env 被 chmod 600 并通过 ~/.bashrc 和 ~/.zshrc 引入 ``` ## Agent 循环 每一轮:**模型 → JSON `{thought, tool, args}` → 批准 → 执行 → 观察 → 重复** ### 工具 | 工具 | 批准级别 | 用途 | |---|---|---| | `run_shell(cmd)` | 白名单 / 询问 / 拒绝 | Shell 命令;逐行流式传输输出 | | `python_exec(code)` | 询问(扫描黑名单) | Python 代码片段;pwntools/pycryptodome/z3 | | `read_file(path)` | 自动(只读) | 文本文件,8 KB 上限 | | `write_file(path, text)` | 总是 diff+确认 | 在任何写入之前显示 Diff | | `list_dir(path)` | 自动 | 包含大小的目录列表 | | `file_info(path)` | 自动 | `file` 命令 + 大小 + SHA-256 | | `hexdump(path, n)` | 自动 | 前 n 字节,hex+ASCII | | `strings(path, min_len)` | 自动 | 可打印字符串(系统 `strings` + Python 备选) | | `http_request(method, url, …)` | 询问 | 通过 urllib 发起的 Web 挑战请求 | | `finish(answer)` | — | 结束循环;首先触发验证步骤 | ### 批准级别 1. **自动**(白名单) — `file`, `strings`, `ls`, `cat`, `grep`, `hexdump`, `nmap`, `objdump`, `readelf`, `binwalk`(不带 `-e`), `base64`, `openssl` 检查操作, … — 静默运行 2. **询问** — 其他所有命令;提示显示 `[y] once / [a] always / [N] deny`;"a" 会将前缀规则附加到会话白名单中 3. **拒绝**(黑名单) — `rm -rf`, `sudo`, `curl|sh`, `dd of=/dev/`, fork 炸弹, `shred` — 即使在 `--approve auto` 下也会被强制阻止 ### 循环防护 - **重复检测** — 重复的工具+参数哈希 → 注入“你刚才已经运行过此命令”并跳过 - **无进展启发式** — 3 次连续的空/重复观察 → 暂停提示 - **软预算** — 到达 `--max-steps` 时:继续 10 步 / 停止 / 注入提示 / 输入答案 - **运行中干预** — 随时输入并按回车键;将作为 `[user hint]` 注入,无需重启 - **完成前验证** — 提出的答案将经过单独的分类调用 - **拒绝备选** — 通过干净上下文的分类器调用检测拒绝(不是对工具输出进行子字符串匹配);自动切换到 `dolphin-llama3:8b` ### 上下文管理 - 固定的事实(任务、flag 格式、确认的发现)在截断后依然保留 - 消息超过 40 条时会被修剪;最后 12 条将与固定块一起保留 - 类似 flag 的字符串 (`WORD{...}`) 会自动从观察结果中提取并存入固定发现中 ### 记录与恢复 每一步都会追加到 `.agent/run-YYYYMMDD-HHMMSS.jsonl`。`--resume` 会重新加载消息历史并继续。恢复时会全新构建系统 prompt(目录更改将生效)。 ## 辅助脚本 ``` ./switch-model.sh deepseek # load deepseek-r1:14b (primary) ./switch-model.sh coder # load qwen2.5-coder:14b ./switch-model.sh dolphin # load dolphin-llama3:8b (uncensored / RAM-saver) ./switch-model.sh status # ollama ps + ollama list ./start-ollama.sh # start service, confirm localhost + LAN reachable ./stop-ollama.sh # stop service to free RAM (e.g. before Ghidra) ./test-server.sh # health check: reachable, models present, generation works ./test-server.sh 192.168.1.11 # same check from Kali over LAN ``` ## 从 Kali 环境 将 Kali 端的辅助工具指向局域网内的 Mac。`ai.py` 和 agent 会读取 **`CTF_AI_HOST`** 环境变量(默认为 `localhost`),因此无需修改代码: ``` export CTF_AI_HOST=192.168.1.11 # Mac's LAN IP (DHCP — may drift; see below) python3 ai.py agent "triage ./chal" ``` 有关连接设置和测试,请参阅 `[[local-ai-ctf-setup]]` 第 07–08 节。 ## 架构 ``` ctf-toolchain/ ai.py # CLI: one-shot (unchanged) + agent subcommand agent/ config.py # host / model / limits llm.py # Ollama /api/chat wrapper protocol.py # JSON extractor (handles tags, ```json fences, nested braces) tools.py # tool registry (10 tools, streaming run_shell + python_exec) approval.py # three-tier gate + session-learned allowlist + check_write diff loop.py # ReAct loop (all guards, steering, truncation, transcript writes) transcript.py # .agent/*.jsonl write + load_resume refusal.py # clean-context refusal classifier + dolphin fallback context.py # pinned-facts + maybe_truncate switch-model.sh start-ollama.sh / stop-ollama.sh test-server.sh AGENT-PLAN.md # original implementation plan ``` 依赖项:**仅标准库**(`urllib`, `json`, `subprocess`, `threading`, `select`, `difflib`)。 CTF 的强大能力源于通过 shell 调用已安装的工具集(pwntools, pycryptodome, z3, binwalk, …)。
标签:AI智能体, AI风险缓解, DLL 劫持, LLM评估, Ollama, 大语言模型, 应用安全, 本地部署, 逆向工具