docs(readme): 新增系统技术架构章节 + Mermaid 架构图
- 双图架构(探索图+资产图)+ 锚点连接、总体分层图与组件表 - 引擎意图闭环时序图、worker 过程级信息交换图、planner 多轮共享 todolist 稳定攻击链路图(5 张 Mermaid,GitHub 原生渲染,无 emoji) Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
1 parent
6bffd491ee
commit
75ca97feb1
1 file changed
+171
-1
@@ -142,10 +142,180 @@ CGO_ENABLED=0 go build -tags embedui -o artex ./cmd/artex
|
||||
- 测试:`go test ./...`
|
||||
- Mock 预览(无后端):`cd web && NEXT_PUBLIC_MOCK=1 npm run dev`
|
||||
|
||||
---
|
||||
|
||||
## 系统技术架构
|
||||
|
||||
ARTEX 是一套 **LLM 多 agent 驱动的自主渗透系统**:Go 单体后端(内嵌 Next.js 前端)+ PostgreSQL,agent 能力由 [`norma`](https://github.com/Autumn-27/norma) SDK 提供(`agentcore` / `tool` / `permission` / `harness` / `memory` / `transcript`)。核心是**双图架构**,以及围绕它的两条自主性机制:**worker 间过程级信息交换**与 **planner 多轮共享 todolist 稳定攻击链路**。
|
||||
|
||||
### 总体分层
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
subgraph FE["前端 Next.js(go:embed 内嵌单二进制)"]
|
||||
UI["仪表盘 · 任务 · 资产 · 覆盖图 · 流量 · 工作空间 · 系统配置"]
|
||||
end
|
||||
subgraph SRV["server(Go net/http)"]
|
||||
API["REST /api/* JWT 鉴权 SSE"]
|
||||
ENG["engine 调度循环"]
|
||||
MGR["Manager 任务/引擎/store 生命周期"]
|
||||
end
|
||||
subgraph AG["agent(norma SDK)"]
|
||||
GO["goals 目标分解 + 提取范围"]
|
||||
PL["planner 规划者(唯一意图生成者)"]
|
||||
WK["worker 执行者 ×N"]
|
||||
MA["mainagent 人在环路"]
|
||||
end
|
||||
subgraph DB["PostgreSQL"]
|
||||
AGRAPH["资产图 assets / companies / task_scope"]
|
||||
EGRAPH["探索图 exploration_nodes / anchors / activity"]
|
||||
end
|
||||
subgraph SUB["支撑子系统"]
|
||||
PROXY["流量记录代理 MITM + CA 留痕"]
|
||||
GUARD["guard / intercept 工具审批门"]
|
||||
ENR["enrich DNS / HTTP 异步补全"]
|
||||
EXT["MCP · skills · memory · report"]
|
||||
end
|
||||
|
||||
UI -->|HTTP| API
|
||||
API --> MGR --> ENG
|
||||
ENG --> PL
|
||||
ENG --> WK
|
||||
API --> MA
|
||||
API --> GO
|
||||
PL --> DB
|
||||
WK --> DB
|
||||
MA --> DB
|
||||
GO --> DB
|
||||
WK -->|"Bash / HTTP 全程留痕"| PROXY
|
||||
WK --> GUARD
|
||||
WK --> ENR
|
||||
PL -.-> EXT
|
||||
WK -.-> EXT
|
||||
MA -.-> EXT
|
||||
```
|
||||
|
||||
| 层 | 职责 |
|
||||
| --- | --- |
|
||||
| **前端** | Next.js 静态导出,`go:embed` 内嵌进单二进制;可视化任务/资产/探索链路/覆盖图,人在环路对话 |
|
||||
| **server** | `net/http` 路由 + JWT 鉴权 + SSE;`Manager` 托管任务、引擎、DB store 的生命周期 |
|
||||
| **engine** | 每任务一个 `plannerLoop` + N 个 worker goroutine;意图领取、超时/暂停/drain |
|
||||
| **agent** | goals / planner / worker / mainagent,`ToolSet` 把双图暴露成 LLM 工具 |
|
||||
| **db** | 双图的 Postgres 落地(pgx);schema 随 `go:embed` 每次启动幂等建表 |
|
||||
| **支撑** | 记录型 MITM 代理、审批门、异步补全、MCP/技能/记忆/报告 |
|
||||
|
||||
### 双图架构:探索图 + 资产图
|
||||
|
||||
系统把「**目标是什么**」和「**测到了什么程度**」拆成两张相互独立、又通过锚点相连的图:
|
||||
|
||||
- **资产图(Asset Graph,全局共享)**:跨任务同一份的资产真值库。节点为 `root_domain / subdomain / ip / service / app / endpoint`,归属公司;域名→子域→服务→端点的父子关系与去重 key 全部由程序计算,agent 只提交原始信息。
|
||||
- **探索图(Exploration Graph,每任务独立)**:一次任务的“思考与推进”过程。节点为 `goal(目标)/ intent(意图)/ fact(事实)/ finding(漏洞)/ hint(提示)`,靠 `spawns / derived_from / yields / proves` 等边连成**血缘链**,回答“哪个方向派生自哪些事实、产出了什么”。
|
||||
- **两图靠锚点相连**:`exploration_anchors(node_id, asset_id)` 把意图/事实/漏洞锚定到具体资产上——于是既能从“探索方向”看它打的是哪些资产,也能从“某个资产”反查它在本任务被哪些意图测过、得出过哪些事实。这也支撑了**资产测试覆盖度**与**资产覆盖图**(范围内资产 + 已测高亮)。
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph EG["探索图(每任务独立 · 推进链)"]
|
||||
direction TB
|
||||
G["goal 目标"]
|
||||
I1["intent 意图 A"]
|
||||
F1["fact 事实"]
|
||||
I2["intent 意图 B"]
|
||||
FD["finding 漏洞"]
|
||||
G -->|spawns| I1
|
||||
I1 -->|yields| F1
|
||||
F1 -->|derived_from| I2
|
||||
I2 -->|proves| FD
|
||||
end
|
||||
subgraph AG["资产图(全局共享 · 真值库)"]
|
||||
direction TB
|
||||
RD["root_domain"]
|
||||
SD["subdomain"]
|
||||
SV["service"]
|
||||
EP["endpoint"]
|
||||
RD --> SD --> SV --> EP
|
||||
end
|
||||
I1 -. anchor .-> SD
|
||||
F1 -. anchor .-> SV
|
||||
I2 -. anchor .-> EP
|
||||
FD -. anchor .-> EP
|
||||
```
|
||||
|
||||
> 分工:**planner** 读探索图态势、判目标、只在有未覆盖的新方向时派**意图**进 frontier;**worker** 领**一条意图**、用真实工具执行、把新资产/事实/漏洞写回两图后即停。资产图是共享事实,探索图是每任务的推进链。
|
||||
|
||||
### 引擎与意图生命周期(一次探索的闭环)
|
||||
|
||||
引擎是**事件驱动**的闭环:图一变就唤醒 planner,planner 派意图,worker 领意图执行并写回,写回又触发下一轮——直到目标被证明(`prove_goal`)。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
autonumber
|
||||
participant EV as 图变更 debounce
|
||||
participant P as planner
|
||||
participant FR as frontier 意图队列
|
||||
participant W as worker
|
||||
participant PX as 记录代理
|
||||
participant DB as 双图 + activity
|
||||
|
||||
EV-->>P: 唤醒
|
||||
P->>DB: 读态势(graph_overview 预取 + coverage/scope)
|
||||
P->>FR: 派 0..N 个意图(带 asset_ids)
|
||||
Note over P,FR: 大多数唤醒派 0 个——无新方向即结束
|
||||
W->>FR: claimNext 领一条意图
|
||||
W->>DB: 取意图 asset_ids 的原始资产作为初始信息
|
||||
W->>PX: 真实工具执行(Kali / Bash / HTTP)
|
||||
PX-->>W: 响应(全程留痕 + CA 验证)
|
||||
W->>DB: 写回 fact / asset / finding + 每步 activity
|
||||
DB-->>EV: 图变更
|
||||
EV-->>P: 再次唤醒(闭环)
|
||||
```
|
||||
|
||||
### worker 间的过程级信息交换
|
||||
|
||||
一次深入的探索里,很多有价值的观察(某个报错、某段响应、某个隐藏参数)出现在一个 worker 的**执行过程**中,却未必被写成正式 fact。为避免重复劳动、让链路上的 worker 能站在彼此的肩膀上,worker 具备**跨 work 检索过程**的能力:
|
||||
|
||||
- `search_all_worker_traces(q)`:在**本任务其他 work 的执行过程**里按关键字检索(自动排除自己这条意图的步骤),命中项带 `intent_id`;
|
||||
- `list_worker_traces` / `get_worker_trace(intent_id, step_ids=[…])`:先看有哪些 work 跑过,再取某个 work 具体几步的完整内容做细节交换。
|
||||
|
||||
这样即便探索图上还没有对应的 fact,后续 worker 也能复用他人过程中的观察——**信息在 worker 之间以“执行过程”为粒度流动**,而边界不变(每个 worker 仍只做自己领到的那条意图)。
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
WA["worker A(意图 #12)"] -->|"每步 activity"| ACT[("探索图 · activity 过程库")]
|
||||
WB["worker B(意图 #34)"] -->|"每步 activity"| ACT
|
||||
WC["worker C(意图 #56)"] ==>|"1) search_all_worker_traces(q)"| ACT
|
||||
ACT ==>|"2) 命中 A/B 的步骤(排除自己)"| WC
|
||||
WC ==>|"3) get_worker_trace(id, step_ids)"| ACT
|
||||
ACT ==>|"4) 返回完整过程内容"| WC
|
||||
```
|
||||
|
||||
### planner 多轮共享 todolist → 稳定的攻击链路
|
||||
|
||||
真实攻击链往往是**有前后依赖的多步序列**(如:发现注入点 → 拿到凭据 → 横向 → 提权),一次性把这些并行派下去只会乱套。planner 因此持有一份**按任务保留、跨唤醒共享的规划待办(todolist)**:
|
||||
|
||||
- planner 是事件驱动的——图一变就被唤醒,但**每次唤醒是全新会话**;共享的 todolist 让它把一条串行利用链**记录一次**、然后在后续多轮里**按依赖逐步派意图**,而不是把整条链在一轮里全部前置展开;
|
||||
- 每轮只对「前置步骤已完成、其依赖的 fact 已存在」的下一步派意图,并随进展更新清单(把已被 fact 满足的步骤标完成)。
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
subgraph TODO["共享 todolist(按任务保留 · 跨唤醒常驻)"]
|
||||
direction LR
|
||||
T1["1 注入点 [已完成]"]
|
||||
T2["2 取凭据 [进行中]"]
|
||||
T3["3 横向 [待前置]"]
|
||||
T4["4 提权 [待前置]"]
|
||||
T1 -.前置满足.-> T2 -.-> T3 -.-> T4
|
||||
end
|
||||
R1["第 1 轮唤醒 派意图①"] --> T1
|
||||
R2["第 2 轮(①产出 fact) 派意图②"] --> T2
|
||||
R3["第 3 轮(②产出 fact) 派意图③"] --> T3
|
||||
```
|
||||
|
||||
于是攻击链在“事件驱动 + 无状态会话”的环境下依然**稳定推进、不重复、不错序**——这是 ARTEX 能自主走完多步利用链的关键。
|
||||
|
||||
---
|
||||
## 参考
|
||||
|
||||
任务的核心理念来源于:https://github.com/oritera/Cairn
|
||||
https://github.com/oritera/Cairn
|
||||
|
||||
|
||||
## 许可
|
||||
|
||||
Reference in new issue
Block a user