完整交互见在线 Demo。
| 仪表盘(总览 / Token 消耗 / 活动流) | 任务列表 |
|---|---|
![]() |
![]() |
| 任务 · 执行过程(会话 / 工具调用) | 探索链路 |
|---|---|
![]() |
![]() |
| 发现 | 资产 |
|---|---|
![]() |
![]() |
| 资产覆盖图(力导向布局 · 已测高亮 · 节点折叠展开) |
|---|
![]() |
| 流量录制 | 人在环路对话 |
|---|---|
![]() |
![]() |
| Agent 管理 | LLM 配置 |
|---|---|
![]() |
![]() |
| 拦截审批 | 后端日志 |
|---|---|
![]() |
![]() |
支持从 ScopeSentry 直接同步资产数据,免去重复收集:
- 在「资产同步」页填 ScopeSentry 的地址与 API Key,接入数据源;
- 按项目或任务维度选择要同步的目标与资产类型(域名 / 子域 / IP / 端口 / 站点 / 端点…);
- 一键导入并按公司资产范围归并,直接进入 ARTEX 的资产图供 agent 探索使用。
依赖数据库 PostgreSQL;探索需配置 LLM(
ANTHROPIC_API_KEY或OPENAI_API_KEY,也可在 UI 里配)。
git clone https://github.com/Autumn-27/ARTEX.git
cd ARTEX
./install.sh脚本会:检测 / 自动安装 Docker → 让你选 ① 全部 Docker 或 ② 本地编译运行:
- ① 全部 Docker:填一个 Postgres 密码(可回车随机)→ 自动写
.env→docker compose up -d。 - ② 本地运行:选数据库(连已有 / 用 Docker 起一个)→ 生成
config.json→go编译内嵌单二进制 → 启动。
装好后打开 **http://localhost:8787**(首次进入 /setup 设置管理员密码)。
git clone https://github.com/Autumn-27/ARTEX.git
cd ARTEX
cp .env.example .env # 填 POSTGRES_PASSWORD、可选 ANTHROPIC_API_KEY
docker compose up -d # 拉取 autumn27/artex 镜像 + postgres
# → http://localhost:8787镜像已含常用工具(ripgrep/curl/vim/npm/nmap…);./skills 与 ./data 以绑定挂载持久化。
到 Releases 下载对应平台的 zip,解压后得到 artex + skills/ + config.example.json:
cp config.example.json config.json # 填好 database 连接
./artex # → http://localhost:8787# 1) 前端静态导出
cd web && npm ci && npm run build:static && cd ..
# 2) 拷进内嵌目录
cp -r web/out server/webui/dist
# 3) 编译(-tags embedui 才内嵌前端)
CGO_ENABLED=0 go build -tags embedui -o artex ./cmd/artex
./artex数据库(config.json,或用环境变量 ARTEX_PG_DSN 覆盖):
{
"database": {
"host": "127.0.0.1", "port": 5432,
"user": "artex", "password": "yourpass",
"dbname": "artex", "sslmode": "disable"
}
}LLM:export ANTHROPIC_API_KEY=sk-...(或 OPENAI_API_KEY),也可在 UI 的「LLM 配置」页填写。
可选:ARTEX_LLM_PROVIDER / ARTEX_LLM_MODEL / ARTEX_LLM_BASE_URL / ARTEX_LLM_PROXY。
并发:每个任务的 work agent 数在「系统设置」里配置(默认 3)。
常用参数:./artex -addr :8787 -proxy :8788(-addr 前端+API,-proxy 流量录制代理)。
./dev.sh # 后端(:8787) + 流量代理(:8788) + 前端 next dev(:5173) → http://localhost:5173- 后端:
go run ./cmd/artex(不带-tags embedui则不内嵌前端) - 前端:
cd web && npm run dev(/api反代到后端,带热更新) - 测试:
go test ./... - Mock 预览(无后端):
cd web && NEXT_PUBLIC_MOCK=1 npm run dev
ARTEX 是一套 LLM 多 agent 驱动的自主渗透系统:Go 单体后端(内嵌 Next.js 前端)+ PostgreSQL,agent 能力由 norma SDK 提供(agentcore / tool / permission / harness / memory / transcript)。核心是双图架构,以及围绕它的两条自主性机制:worker 间过程级信息交换与 planner 多轮共享 todolist 稳定攻击链路。
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)把意图/事实/漏洞锚定到具体资产上——于是既能从“探索方向”看它打的是哪些资产,也能从“某个资产”反查它在本任务被哪些意图测过、得出过哪些事实。这也支撑了资产测试覆盖度与资产覆盖图(范围内资产 + 已测高亮)。
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)。
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 的执行过程中,却未必被写成正式 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 仍只做自己领到的那条意图)。
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 让它把一条串行利用链记录一次、然后在后续多轮里按依赖逐步派意图,而不是把整条链在一轮里全部前置展开;
- 每轮只对「前置步骤已完成、其依赖的 fact 已存在」的下一步派意图,并随进展更新清单(把已被 fact 满足的步骤标完成)。
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
仅供授权测试与研究使用。












