preemware/OPFORA

GitHub: preemware/OPFORA

OPFORA 是一个基于 LangGraph 和 Deep Agents 构建的自主攻击型安全智能体,能够无人值守地解决 HTB 级别 CTF 靶机并测试 Web 应用安全漏洞。

Stars: 8 | Forks: 0

# OPFORA 自主攻击型安全 agent。能够无人值守地解决 HTB 级别的 CTF 靶机,测试 Web 应用的 OWASP 级别问题,通过阅读互联网信息来为其推理提供基础。基于 LangGraph + Deep Agents 构建。 **它不是红队替代品。** 不对抵抗现代 EDR 的 OPSEC 做出任何承诺,不对社会工程学做出任何承诺,也不对自主闭合防御闭环做出任何承诺。 ## 一段话简介 由一个读取结构化发现结果并决定下一步操作的主 agent 协调的一小部分 subagent(Surface、Exploit、PostEx 和 Analyst)。所有攻击工具都部署在 MCP server 之后 —— `surface`(侦察 + Web)、`exploit`(payload + 传递)、`postex`(枚举 + 提权)、`browser`(Playwright)、`shell`(tmux 会话)、`episodes`(基于 Postgres 的日志)。三种任务模式(`ctf`、`lab`、`engagement`)具有不同的 prompt 和 HITL 策略。由 middleware 强制执行的确定性交战规则 门控 —— 模型绝不自行决定目标是否在范围内。 ## 已攻破的靶机 OPFORA 已无人值守拿下 root 权限的 [HackTheBox](https://www.hackthebox.com/) 机器: Bounty · Connected · DevArea · Devhub · Helix · Monteverde · Nibbles · Optimum · Querier · Resolute · SmartHIRE · Silentium · Support · WingData · Reactor · Kobold 使用 **`opfora engage`** 无人值守运行其中任何一台 —— 当配置规范包含 `htb:` 块时,它会通过 HTB API 启动靶机,解决问题,提交 flag,并销毁靶机([详情](#htb--hackthebox-auto-provisioning))。 **不要盲目相信这个列表 —— 请自行复现。** 这些声明记录在 [`benchmark/claims.yaml`](benchmark/claims.yaml) 中,并与本地生成的 构件进行核对,而不是仅凭文字说明: ``` opfora benchmark list # available suites opfora benchmark run htb-retired-small # spawns/solves/tears down, writes a metrics artifact opfora benchmark run xbow-full --sample 30 # XBEN pass@1 estimate + 95% CI, ~1/3 the cost of all 104 opfora benchmark verify # re-derive claims.yaml from benchmark/results/ (exit 1 if any unbacked) opfora benchmark report # aggregate metrics across all runs ``` 只有当 `benchmark/results/` 中提交/生成的结果证明其有效时(获取了 root 权限,且 flag 被 HTB 本身接受), `verify` 才会将每项声明报告为 VERIFIED —— 否则为 UNVERIFIED。全新克隆 -> 在你运行之前一切均为 UNVERIFIED,这正是其目的所在。`report` 会汇总每次运行的关键指标:初始立足点 获取率、root/admin 获取率、平均成本、平均时间、工具调用、人工干预、 RoE 拦截、卡死检测器激活次数以及阻止的重复失败操作(每一个 数字都可追溯到 episode 日志、Redis 或运行记录 —— 参见 [`benchmark/bench.py`](benchmark/bench.py))。 **客观的能力画像:** 获取初始立足点(靶机上的一个 shell)在这里是一个几乎被解决的问题 —— 侦察 -> 漏洞 -> exploit 在广泛的目标范围内能可靠生效。**提权则时好时坏。** 有些靶机可以直接提权到 root;另一些则在提权链上停滞不前(钻牛角尖走错了路、不明显的横向跳跃、特定环境下的技巧),这也是目前大部分正在进行的工作所聚焦的领域。 ## 快速开始 **实战快速路径** —— 针对单个目标,无需了解整个平台。在执行 `pip install -e .`(下文的步骤 1)并将 provider 密钥添加到 `.env` 之后: ``` opfora doctor # check Docker, keys, datastores, MCP health opfora setup # write .env + build images (one time) opfora quickstart 10.129.245.50 # minimal stack up + engage that target ``` `quickstart` 仅启动必要的组件(postgres、redis、gateway 以及 surface/shell/episodes MCP server —— 不包含 Neo4j、LiteLLM proxy 或 Web UI),编写 规范并开始执行任务。使用 `opfora up --minimal` 可以在不执行任务的情况下启动该精简技术栈, 或者使用 `opfora up` 启动完整技术栈。随时运行 `opfora doctor` 来诊断出现故障的环境配置。 **完整手动设置:** ``` # 0. 复制 env 并进行编辑 cp .env.example .env # 1. 将 Python 后端安装到 venv 中 # 需要 Python 3.11+。如果 `python3` 版本较旧,请先安装 3.11 或 3.12 # (例如 `brew install python@3.12`)并在下文中进行替换。 python3 -m venv .venv source .venv/bin/activate pip install -e . # 2. 启动 management plane docker compose -f infra/docker-compose.yml up -d # 3a. (本地开发) 在 ops network 上启动 DVWA / Juice Shop docker compose -f infra/docker-compose.yml -f infra/docker-compose.ops.yml \ --profile dev-targets up -d # 3b. (HTB / 外部) 直接跳过 — `opfora engage` 会根据你 spec 中的 `vpn_config:` 字段自动启动 # VPN sidecar。 # (只能选择 3a 或 VPN overlay 中的一项 — 它们是互斥的, # 因为 `network_mode: service:vpn` 与 ops-net 互斥。) # 4. 运行它 opfora init # one-time onboarding # HackTheBox:一个 `htb:` 块会让 `engage` 为你 SPAWN 靶机,解决它, # 提交 flags,并将其销毁。不需要目标 IP。 # (需要在 .env 中配置 HTB_TOKEN — 参见 Engagement spec 中的 “htb”。) opfora engage docs/examples/htb-challenge.yaml # 已存在的目标(本地 VM、你 SPAWN 的靶机、客户端 IP): opfora engage docs/examples/metasploitable.yaml --profile eco ``` 规范驱动目标:带有 `htb:` 块时,`engage` 会通过 HTB API 配置机器,因此你无需手动提供每次启动的 IP;如果没有该块,它将针对你提供并管理的目标运行。 CLI 会将每个 subagent 的输出(带有颜色区分)流式传输到你的终端。Web 仪表板(可选)位于 http://localhost:3000。 ### 完整记录(`--debug-log`) `engage`、`attach` 和 `resume` 都接受 `--debug-log ` 参数,该参数以 JSON Lines(每行一个事件)格式记录 agent 的**完整过程** —— 每一次工具调用、工具结果和模型消息: ``` opfora engage docs/examples/metasploitable.yaml --debug-log logs/run.jsonl # 或者捕获一个正在运行的 engagement: opfora attach --debug-log logs/run.jsonl ``` 这是一次运行的完整机器可读记录 —— 非常适合用于事后分析、回放发生的过程,或者交给 LLM 来询问“它为什么在这里失败了?”。该文件是**追加模式**的(每次 attach 都会添加一个 `_debug_meta` 分隔符,因此重新挂载永远不会覆盖之前的捕获内容)。事件**仅在挂载时被捕获**:如果你分离了,请使用 `--debug-log` 重新挂载以恢复记录。 ### VPN 流程 VPN 挎载模式:单个 `vpn` 容器持有 OpenVPN 隧道,攻击型 MCP server 通过 `network_mode: "service:vpn"` 加入其网络 namespace。从 `nmap`、`curl`、Playwright 或已落地的 shell 发出的每一个出站数据包都会通过该隧道路由。 - **`.ovpn` 在任务 YAML 中声明。** 将 `vpn_config:` 设置为一个路径(绝对路径,或相对于规范文件的路径)—— `opfora engage` 会解析它并在启动前带起 VPN 挎载容器。解析优先级:`--vpn` CLI 标志 > `VPN_FILE` 环境变量 > 规范中的 `vpn_config:`。 - 每个 compose 栈只有一个 VPN —— 要切换目标,请更改规范中的 `vpn_config:` 并重新运行 `opfora engage`。当挂载源发生变化时,Compose 会重新创建挎载容器。 - 当 VPN 覆盖层处于活动状态时,`ops-net` 上的本地开发目标(DVWA、Juice Shop)将无法从 MCP 容器访问。请在本地开发或 VPN 之间二选一,不能同时使用。 - 传入 `--skip-vpn` 可以保持 compose 原样不动(当挎载容器已经使用正确的 .ovpn 启动,或者在非 VPN 运行时使用)。 **HTB 自动 VPN(无需 `.ovpn` 文件)。** 对于 `htb:` 运行,你可以完全跳过 `vpn_config:`:将其留空,`opfora engage` 会在运行时从 HTB API 获取实验环境隧道。CLI 会启动攻击型 MCP 并让它们共享 VPN namespace,并且一旦靶机启动,gateway 就会下载机器的 `.ovpn` 并将其推送到沙箱中 —— 无需你自己下载或管理文件。 - 自动 VPN **仅在规范包含 `htb:` 且没有 `vpn_config`** 时被选用。如果设置了 `vpn_config:`(或者 `--vpn` / `VPN_FILE` 指向一个文件),CLI 会采用该静态路径,如果缺少该 `.ovpn` 则会报错 —— 因此要使用自动 VPN,请确保这三个都没有设置(如果 shell 中还残留着 `VPN_FILE`,请执行 `unset VPN_FILE`)。 - 需要在 `.env` 中设置 `HTB_TOKEN`(用于 API 下载)。`HTB_AUTO_VPN` 默认开启;将其设置为 `0` 可禁用。 ## 任务规范 任务由传递给 `opfora engage .yaml` 的单个 YAML 文件描述。模板位于 [`docs/examples/`](docs/examples/) 中。一个全功能示例: ``` name: htb-checkpoint # label for the engagement (required) mode: ctf # ctf | lab | engagement (required) targets: # hostnames or CIDRs in scope - 10.129.245.50 objective: "root flag" # what "done" means (free text) expected_flags: 2 # user + root — see below budget_usd: 5.0 # hard cost cap for the run profile: eco # eco | max | test (model tiers) autonomy: standard # observe | assist | standard | aggressive-lab | engagement-safe vpn_config: ../../client.ovpn # .ovpn path (absolute, or relative to this file) # Operator briefing — 原样折叠到 agent 的开场消息中。 # 自由文本形式的 pre-engagement 上下文:scope 提示、内部 hostname、 # 已知的良好 foothold 路径、“不要触碰 X”。对于初始 creds,请使用 `credentials`。 notes: | Assumed-breach start. The DC re-randomizes per spawn — re-derive any recovered secret each run rather than reusing an old value. # Assumed-breach / 提供的 credentials。持久注入到 orchestrator # 和 offensive-subagent 的 system prompts 中,以便 agent 从一开始就使用它们, # 而不是试图发现或破解它已经拥有的内容。 credentials: - username: alex.turner secret: "Checkpoint2024!" kind: password # password | hash | ssh-key | token | api-key service: smb # ssh | smb | winrm | http | mysql | domain | ... (optional) host: dc01 # scope to one host (optional) notes: domain account for authenticated enum + lateral movement (optional) # Rules of engagement。在 ctf/lab 模式下,scope 会从 `targets` 自动推导, # 因此你通常可以省略此项。在 `engagement` 模式下为必填项(已签署的 RoE)。 roe: allowed_hosts: ["*.corp.local"] # exact or wildcard hostnames allowed_networks: ["10.10.0.0/16"]# CIDRs blocked_hosts: ["10.10.0.5"] # never touch, even if in an allowed range self_hosts: ["10.10.14.0/23"] # your LHOST/VPN/staging — exempt from scope checks blocked_ports: [3389] allowed_techniques: ["*"] # "*" or categories: recon, exploit, postex, ... blocked_techniques: [] destructive_requires_approval: true signed_document_path: ./roe.pdf # REQUIRED for `engagement` mode signed_by: "Jane Client" signed_at: 2026-06-01T00:00:00Z ``` ### 字段 | 字段 | 必需 | 默认值 | 说明 | |---|---|---|---| | `name` | 是 | — | 任务标签(用于报告 + `opfora ls`)。 | | `mode` | 是 | — | `ctf` \| `lab` \| `engagement` —— 参见[三种模式](#three-modes)。 | | `targets` | 是* | `[]` | 主机名或 CIDR;在 ctf/lab 模式下,它们还会作为 RoE 白名单的种子。*当设置了 `htb` 时为可选 —— 启动的靶机 IP 会自动为你填充。 | | `objective` | 否 | `"root"` | 编排器努力达成的自由文本目标。 | | `expected_flags` | 否 | 未设置 | 设置后(例如 HTB 的 user+root 对应 `2`),确定性门控会强制在该数量的 flag 被记录后进行分析师交接。对于多主机实验环境请保持未设置。 | | `budget_usd` | 否 | `10.0` | `budget_guard` 在 80% 时警告,在 95% 时硬性停止。 | | `profile` | 否 | `eco` | 模型层级 —— 参见 [Profiles](#profiles)。CLI 上的 `--profile` 会覆盖此项。 | | `autonomy` | 否 | 模式默认值 | 显式信任姿态 —— 参见 [Autonomy](#autonomy)。CLI 上的 `--autonomy` 会在此次运行中覆盖此项。 | | `vpn_config` | 否 | 无 | 指向 `.ovpn` 的路径;`opfora engage` 会带起 VPN 挎载容器。优先级:`--vpn` > `VPN_FILE` 环境变量 > 此项。 | | `notes` | 否 | `""` | 操作员简报 —— 见下文。 | | `credentials` | 否 | `[]` | 假定突破凭证 —— 见下文。 | | `htb` | 否 | 无 | HackTheBox 自动配置(启动/销毁)。设置后,`opfora engage` 会自动配置靶机 —— 见下文。 | | `roe` | 否¹ | 自动 | 交战规则。¹在 `engagement` 模式下必需(需提供 `signed_document_path`)。 | ### Autonomy 在规范中设置 `autonomy:` 或在某次运行中覆盖它: ``` opfora engage spec.yaml --autonomy observe ``` | 等级 | 行为 | |---|---| | `observe` | 仅进行组织、总结和建议。面向目标的操作会被阻止。 | | `assist` | 被动侦察只能在 HITL 批准后运行;exploit/后渗透类别被阻止。 | | `standard` | 侦察和其他安全的工作流步骤自动运行;exploit、凭证、横向移动、数据访问、持久化和规避类别需要 HITL 批准。 | | `aggressive-lab` | 针对实验/靶机(CTF/lab)使用的完全自主。 | | `engagement-safe` | 针对安全测试的严格 HITL,适用于 exploit、凭证、横向移动、数据访问、持久化和规避类别。 | ### `notes` — 操作员简报 作为 **OPERATOR BRIEFING** 块逐字传递给 agent 初始消息的自由文本。用于 agent 在开始前应该知道的、非凭证类的任何信息:范围提示、内部主机名、一个已知良好的初始立足点路径以跳过重新推导、“靶机每次启动都会重新随机化”等。它会传达给编排器,编排器会将相关部分中继到 subagent 的任务简报中。 ### `credentials` — 假定突破访问 任务开始时拥有的一系列凭证(就像真实的“假定突破”渗透测试一样)。与 `notes` 不同,这些信息会**持久地**展示在编排器和攻击型 subagent 的系统 prompt 中(系统 prompt 不会在长时间的运行中被摘要掉),告诉 agent 在发现或破解新凭证之前先*使用*它已持有的凭证。 | 子字段 | 必需 | 说明 | |---|---|---| | `username` | 是 | 账户名。 | | `secret` | 否 | 密码、NTLM hash、密钥材料、token。对于仅提示用户名的情况请省略。 | | `kind` | 否(`password`) | `password` \| `hash` \| `ssh-key` \| `token` \| `api-key`。 | | `service` | 否 | `ssh` \| `smb` \| `winrm` \| `http` \| `mysql` \| `domain` \| …… —— 使用位置。 | | `host` | 否 | 将凭证范围限定在某一台主机。 | | `notes` | 否 | 自由文本(例如“属于 docker 组”)。 | ### `htb` — HackTheBox 自动配置 添加一个 `htb:` 块,让目标通过 HTB API **自动启动、解决并销毁**,而不是提供一个需要你手动启动/重置的静态 `targets:` IP。这完全由规范驱动 —— `opfora engage` 检测到 `htb:` 块就会自动配置靶机;无需单独的命令: ``` opfora engage docs/examples/htb-challenge.yaml ``` ``` name: htb-support mode: ctf expected_flags: 2 htb: machine: Support # HTB machine name or numeric id (required) teardown: on_complete # on_complete | on_success | never submit_flags: true # POST captured flags to HTB to confirm the solve difficulty: 5 # 1..10 rating sent with each flag # reset_before: false # reset the box to a clean state before the run # kind: retired # active | retired | release | starting_point (auto-detected if unset) # spawn_timeout_s: 180 # how long to wait for the box to get an IP vpn_config: ../machines_us-3.ovpn # 没有 `targets:` — SPAWN 的靶机的 IP 会自动填入 ``` 配置在 **gateway 端运行** —— `/eng` 端点会检测到 `htb:` 块并包围这次运行,因此 CLI *和* Web 仪表板都能仅凭规范获取配置信息。每次运行的生命周期:**解析 -> 启动 -> 等待 IP -> 针对其运行一次任务 -> 提交捕获的 flag -> 销毁。** | `htb:` 子字段 | 必需 | 默认值 | 说明 | |---|---|---|---| | `machine` | 是 | — | HTB 机器名称或数字 id。 | | `kind` | 否 | 自动 | `active` \| `retired` \| `release` \| `starting_point`;如果未设置则会自动检测。 | | `teardown` | 否 | `on_complete` | `on_complete`(总是),`on_success`(仅在解决时),或 `never`。 | | `submit_flags` | 否 | `true` | 将每个捕获的 flag 提交给 HTB(`own`)以确认解题成功。 | | `difficulty` | 否 | `5` | HTB 提交 flag 时要求的 1-10 评分。 | | `reset_before` | 否 | `false` | 在开始前将机器重置为干净状态。 | | `spawn_timeout_s` | 否 | `180` | 等待靶机获取 IP 的最长时间。 | 说明: - **需要 `HTB_TOKEN`**(HTB 账户 -> *App Tokens*)位于 `.env` 中 —— **gateway** 会读取它(compose 中的 `env_file: ../.env`),因为配置是在 gateway 端进行的。如果账户上已经启动了另一台不同的机器,会先终止该机器(HTB 只允许一个活跃靶机)。 - VPN 由 CLI 在运行前带起(`vpn_config` / `--vpn` / `VPN_FILE`)—— gateway 无法控制挎载容器 —— 且 HTB 靶机只能通过实验环境的 VPN 访问。**请使用 TCP `.ovpn`**(见 [VPN 流程](#vpn-flow))。 - 销毁通过 `htb.teardown` 进行**规范驱动**(`on_complete` / `on_success` / `never`);通常的 `--profile` / `--skip-vpn` / `--debug-log` 依然适用。 - **HTB 运行是原子的:** Ctrl-C 会取消运行,且 gateway 依然会销毁机器 —— 而针对静态目标的 `engage` 会暂停以等待 `opfora resume`。规范中的 `htb:` 块会选择此行为:包含该块时,gateway 会在 HTB 启动 -> flag 提交 -> 销毁的流程中包裹运行;如果没有,它将针对你提供并管理的目标运行。 ## 三种模式 | 模式 | 用途 | RoE | HITL | |---|---|---|---| | `ctf` | HTB 单机 | 根据目标自动生成 | 无 —— 放手施为 | | `lab` | 多主机实验环境(Pro Labs、PG) | 根据目标自动生成 | 仅限横向移动 | | `engagement` | 授权的真实测试 | 需要签名文档 | 所有破坏性操作 | 模板请参见 [`docs/examples/`](docs/examples/)。 ## Profiles 模式决定*姿态*;profiles 决定*模型*。Profiles 独立于 模式 —— 在 CLI 上使用 `--profile` 可覆盖规范中的值。Autonomy 级别可以在不更改模式的情况下,进一步收紧或放宽 HITL 行为。 ### 各角色、各 profile 的层级 | Profile | Orchestrator | Surface | Exploit | PostEx | Analyst | Researcher | AD¹ | |---|---|---|---|---|---|---|---| | `eco` (默认) | HIGH | MID | HIGH | MID | MID | MID | HIGH | | `max` | HIGH | HIGH | HIGH | HIGH | HIGH | HIGH | HIGH | | `test` | LOW | LOW | LOW | LOW | LOW | LOW | LOW | | `qwen` | 所有角色开启 `qwen/qwen3.7-max`(通过 OpenRouter) | | | | | | | | `gpt` | 所有角色开启 `gpt-5.5` | | | | | | | ¹ AD 专家(通过 `MCP_AD_URL` 启用)沿用 Exploit 层级。 ² `qwen` 和 `gpt` 是单模型 profiles —— 每一个角色都使用同一个模型,用于 脱离基于 Anthropic 优先的分层默认设置的成本/评估运行。 层级映射位于 [`src/agent/models.py`](src/agent/models.py);LiteLLM 路由链位于 [`infra/litellm-config.yaml`](infra/litellm-config.yaml)。 ### 层级 -> 模型映射 | 层级 | Anthropic (首选) | OpenAI (备选) | Google (备选) | 本地备选 | |---|---|---|---|---| | **HIGH** | `claude-opus-4-8` | `gpt-5.5` | `gemini-3-pro` | — | | **MID** | `claude-sonnet-5` | `gpt-5.4-mini` | `gemini-flash` | — | | **LOW** | `claude-haiku-4-5` | `gpt-5.4-nano` | — | `qwen3-32b` (Ollama) | 默认情况下,agent 会通过 LiteLLM proxy 路由所有的模型调用(需要 `LITELLM_MASTER_KEY`)。这会激活 [`infra/litellm-config.yaml`](infra/litellm-config.yaml) 中的备选链,外加 Redis 响应 缓存、支出/预算追踪以及 Langfuse 可观测性,并且会路由每一个 模型,包括 `qwen`/OpenRouter profile。 设置 `OPFORA_USE_LITELLM=false` 可以直接调用每个 provider 的 SDK —— 这 保留了 Anthropic 原生的 prompt 缓存(在重度依赖 Opus 的运行中更便宜),但是 上面的备选链将失效(首选方案的宕机会通过 每次调用的重试来处理,而不是 provider 故障转移),并且 `qwen` 将直接与 OpenRouter 通信。 ### 为什么这样选择 - **Orchestrator 和 Exploit 在 `eco` 中保持 HIGH**(且 AD 专家沿用 Exploit 层级,因此它也是 HIGH)。这些承载着核心的负载推理。特别是降低 Exploit 层级会导致在困难靶机上的静默失败 —— 错误的 payload、无法链式执行的阶段、放弃了一条原本可行的路径。 - **`eco` 的下限是 MID,绝不为 LOW。** `eco` 相对于 `max` 节省成本的方式是在非关键角色上运行 MID(Sonnet),而不是降级到 LOW(Haiku)—— Haiku 会搞砸 PostEx 提权分类,因此 LOW 专门保留给 `test` profile。 - **Surface、PostEx、Analyst 和 Researcher 在 `eco` 中运行 MID。** Surface 主要是工具编排;PostEx 是一旦 shell 落地后的 shell 循环(提权*分类*仍然会经过 HIGH 的 Orchestrator);Analyst 是一次性的报告生成;Researcher 的深度阅读非常昂贵 —— 当某台机器需要进行艰难的 CVE 挖掘时,请使用 `--profile max` 升级它。 - **`max` 用于你输不起的任务。** 真实的客户测试、新颖的目标,以及任何推理质量比单步成本更重要的场合。 - **`test` 的存在是为了让 CI 不会让任何人破产。** 不要将其指向真实目标;LOW 层级的模型会漏掉更高层级能捕捉到的东西。 ### 订阅认证(Claude Code / Codex) 不想给 OPFORA 提供原始 API 密钥?使用与 Claude Code / Codex 相同的 OAuth 流程通过 provider 的**订阅**登录 —— 随后 `opfora` 将使用该 token 进行认证(Anthropic 可以直接使用 Claude Code 的公共客户端)。仅限 Direct-SDK 路径(`OPFORA_USE_LITELLM=false`)。完整步骤见 [docs/subscription-auth.md](docs/subscription-auth.md)。 ### 自适应思考(exploit/postex) 在 `.env` 中设置 `OPFORA_THINKING_EFFORT`(`low | medium | high | xhigh | max`) 以便为两个重度推理的 subagent(Exploit、PostEx)在每一步提供自适应思考;未设置时(默认)则不带此功能运行。设置了级别后, [`model_arg_for(...)`](src/agent/models.py) 会赋予这些 subagent 一个 启用了思考功能的 Anthropic 模型,其努力程度将被限制在层级支持的范围内 (Sonnet 最高为 `high`;Haiku / 非 Anthropic 层级保持普通模式)。思考机制使得 模型能够在行动之间进行审慎思考(重试前先诊断),而不是 条件反射式地触发下一个工具调用 —— 这种条件反射式的循环正是导致 昂贵重试绕路的原因。请从 `high` 开始并进行相应调整。 ### 预算控制 `budget_guard` middleware 会追踪每次任务的支出,在 80% 时警告,在 95% 时硬性停止。请实事求是地在规范中设置 `budget_usd`: - 在 `eco` 下解决单个 HTB 简单靶机:通常为 $0.50 – $2 - 在 `eco` 下解决 HTB 困难靶机:$3 – $10 - 在 `eco` 下解决 10 台主机的实验环境:$20 – $60 - 在 `max` 下进行外部任务:按范围而非按靶机做预算(对于相同的攻击面,通常是 `eco` 费率的 5-10 倍) 基准测试聚合器([`benchmark/aggregate.py`](benchmark/aggregate.py))会追踪多次运行中每台机器的中位数成本,因此任何偏移都会在趋势线中显现出来。 ## 架构 ``` ┌────────── management-net ──────────┐ │ Next.js ─── FastAPI gateway │ │ │ │ │ ├── Postgres (episodes + checkpoints) │ ├── Neo4j (derived graph) │ ├── Redis (UI pubsub) │ ├── ETL worker (log → graph) │ ├── LiteLLM (model router) │ └── MCP servers └──────────────────┬─────────────────┘ │ docker socket ▼ ┌──────────── ops-net (isolated) ────┐ │ kali-sandbox ── targets/VPN ── │ └────────────────────────────────────┘ ``` 沙箱仅通过 `episodes` MCP server 向管理平面回写数据。沙箱内部没有直接的数据库连接。 ## Web 仪表板 CLI 是主要界面;仪表板用于观察已经在运行的任务。它是可选的 —— docker-compose 中的 `web` 服务位于一个 profile 之后,这样无头模式的运行就不需要支付构建成本。 ### 启动它 ``` # 启动 web dashboard(也会启动它所需的 gateway) opfora web # add --build on first run # 原始 compose 等效操作 — management stack 加上 web service docker compose -f infra/docker-compose.yml --profile web up -d # 或者,与 dev 目标一起 docker compose \ -f infra/docker-compose.yml \ -f infra/docker-compose.ops.yml \ --profile web --profile dev-targets up -d ``` 然后打开 。 ### 页面 | 路径 | 显示内容 | |---|---| | `/` | 索引 + 快捷链接 | | `/engagements` | gateway 知道的每一个任务的列表(基于文件系统支持) | | `/engagements/` | 详细视图 —— 实验进度、活跃 shell、发现结果(按严重程度着色)、完整的 episode 时间线 | | `/engagements//shell` | 任务中任何 tmux 会话的只读流。轮询时间约为 1.5 秒 | | `/engagements//graph` | Neo4j 衍生的投影图:主机、带版本号的服务、凭证、CVE | | `/hitl` | 所有任务中待处理的 HITL 批准。可以接受/拒绝,并提供可选的指导意见 | | `/stuck` | 待处理的 `StuckReport` 升级请求。输入提示,点击“Resume with this guidance” | | `/skills` | 来自 `skill_proposer` middleware 提议的技能。每个草稿都有 Markdown 预览 | 仪表板刻意保持极简 —— 等宽字体、暗色主题,除了 Next.js 内置的之外没有客户端路由器。一切都通过 `NEXT_PUBLIC_GATEWAY_URL`(默认为 `http://localhost:8000`)与 FastAPI gateway 通信。 ### 本地开发(迭代仪表板) ``` cd web npm install NEXT_PUBLIC_GATEWAY_URL=http://localhost:8000 npm run dev ``` `/engagements//shell` 和 `/hitl` 是轮询 gateway 的客户端组件;`/engagements/` 和 `/engagements//graph` 是在请求时获取数据的服务器端组件。如果页面是空白的,请检查 gateway 是否可达(`curl http://localhost:8000/healthz`)—— 仪表板页面会捕获获取失败并渲染为空状态,而不是抛出错误。 ## 仓库布局 ``` src/ ├── agent/ # orchestrator, modes, subagents, middleware, prompts ├── mcp_servers/ # surface, exploit, postex, browser, shell, episodes, research, ad ├── etl/ # episode → Neo4j projection ├── gateway/ # FastAPI gateway (CLI + dashboard talk to this) ├── cli/ # Typer CLI (the `opfora` command) └── schemas/ # pydantic models skills/ # progressive-disclosure SKILL.md files infra/ # docker compose, Dockerfiles, postgres init, litellm config benchmark/ # ci_easy.py + nightly_full.py tests/unit/ # RoE gate, schemas, middleware state docs/examples/ # spec templates ``` ## RoE 门控 这是设计中拒绝妥协的唯一一点。确定性的 middleware 会从每个工具调用的参数中提取主机/IP/URL,与 `ipaddress.ip_network` 匹配,阻止任何不在列表内的事物。模型绝不决定范围。 测试位于 [`tests/unit/test_roe_gate.py`](tests/unit/test_roe_gate.py)。 ## 网络安全防护 / 验证计划 Anthropic 模型携带**实时的网络安全防护** —— 这是一个服务器端的分类器, 可以在遇到攻击安全内容(exploit 传递、反向 shell、RCE)时返回 `stop_reason: "refusal"` 以及 `stop_details.category: "cyber"`。在未经验证的组织上,这些拒绝是**间歇性的**: 一次运行可能成功落地 shell,随后却有约 10-15%后续 exploit 回合被拒绝,这表现为 空的“截断”回合,以及一个从不输出其结构化结果的 subagent。现在 CLI 会显式提示每一次拒绝(`⚠ model refused …`),而不是让它看起来像静默停滞。 这**不是** agent 可以通过 prompt 绕过的东西,我们也不尝试去绕过 —— 这是一种安全机制。对于授权的攻击性安全用途(渗透测试任务、CTF 实验环境、安全研究),合法的解锁方式是 Anthropic 的**网络验证计划**:申请将你的组织/密钥列入白名单。拒绝消息本身的 `explanation` 字段附带了申请表的链接,并且该计划记录在 。 在验证通过之前,预计 exploit/postex subagent 上会出现间歇性的拒绝。 ## 开发 ``` # 设置 venv (Python 3.11+) python3 -m venv .venv .venv/bin/pip install -e ".[dev]" # 单元测试(无需 Docker) .venv/bin/pytest tests/unit/ # Lint .venv/bin/ruff check src/ .venv/bin/mypy src/ ``` 对于完整的集成循环,你需要 Docker + VPN 配置。 ## 技能编写 团队可以将本地的实战技术编码为位于 `skills///SKILL.md` 下的技能。 单数的 `skill` 命令用于本地开发;复数的 `skills` 命令用于审查 agent 提议的草稿。 ``` opfora skill new surface/my-skill opfora skill test surface/my-skill opfora skill lint opfora skill pack ``` `skill test` 和 `skill lint` 会验证必需的 frontmatter/部分、命令 安全标签、预期的输入/输出、工具引用、陈旧的 `skills/...` 路径,以及以未知二进制文件或工具开头的命令片段。`skill pack` 会写入一个包含活跃技能的 `.tar.gz` 包,以便跨团队共享。 ## 这不是什么 营销层面上的客观范围声明: - **不是红队替代品。** 没有针对 EDR 的 OPSEC。没有社会工程学。没有闭合防御闭环。 - **卡死检测是一项 UX 特性,而不是一个 bug。** 约 20-30% 的靶机需要提示;agent 会升级发送一个结构化的 `StuckReport`,以便操作员可以用一个问题来解答,而不是看着它苦干两个小时。 - **技能循环是双向的** —— agent 提议新的实战技术,操作员审查并合并。没有任何东西会自动合并到活跃的技能树中。 ## 许可证 [AGPL-3.0](LICENSE)。
标签:AI智能体, CISA项目, DLL 劫持, Web报告查看器, 大语言模型, 密码管理, 搜索引擎查询, 测试用例, 特征检测, 红队评估, 网络调试, 自动化, 请求拦截, 逆向工具