fix: use Hinln/ARTEX for authenticated release updates
AI 自主渗透测试系统(Go 后端 + Next.js 前端)
🌐 在线 Demo: https://artex-demo.vercel.app/
完整交互见在线 Demo。
全局「审批记录」、任务内「拦截审批」及对话中的审批卡片均支持展开查看详情。展示结构参考 AegisHook 的审批详情组件,沿用 ARTEX 的组件和主题:
支持从 ScopeSentry 直接同步资产数据,免去重复收集:
依赖数据库 PostgreSQL;探索需配置 LLM(ANTHROPIC_API_KEY 或 OPENAI_API_KEY,也可在 UI 里配)。
ANTHROPIC_API_KEY
OPENAI_API_KEY
git clone https://github.com/Hinln/ARTEX.git cd ARTEX ./install.sh
脚本会:检测 / 自动安装 Docker → 让你选 ① 全部 Docker 或 ② 本地编译运行:
.env
docker compose up -d
config.json
go
装好后打开 http://localhost:8787(首次进入 /setup 设置管理员密码)。
/setup
git clone https://github.com/Hinln/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 以绑定挂载持久化。
./skills
./data
远程 MCP 可在系统设置中选择 http(Streamable HTTP)或 sse(旧版 SSE)。 旧版 SSE 服务通常使用 GET /sse 建立事件流,再通过服务返回的 /message?sessionId=... 接收 JSON-RPC 请求;配置时将 URL 填为 /sse,请求头按 Authorization=Bearer <token> 填写。
http
sse
GET /sse
/message?sessionId=...
/sse
Authorization=Bearer <token>
到 Releases 下载对应平台的 zip,解压后得到 artex + start.sh(Windows 为 start.bat)+ skills/ + config.example.json:
artex
start.sh
start.bat
skills/
config.example.json
cp config.example.json config.json # 填好 database 连接 ./start.sh # → http://localhost:8787
请用 start.sh / start.bat 启动,而不是直接跑 ./artex。它是个守护脚本:程序退出后按退出码决定是否重新拉起,页面上的一键更新靠它完成换装。直接运行 ./artex 时更新完就不会被拉起了。 后台常驻:nohup ./start.sh >artex.log 2>&1 &。
./artex
nohup ./start.sh >artex.log 2>&1 &
# 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 ./start.sh
build.sh 会先构建并嵌入前端,再使用 Go linker 去除调试信息,并将发布文件压缩为 zip。Release 模式默认生成 Linux amd64/arm64、macOS amd64/arm64 和 Windows amd64 的 zip 包:
build.sh
./build.sh --release # 产物:dist/artex-0.3.3-*.zip
UPX 自解压二进制可能与部分 Linux 内核、虚拟化环境或安全策略不兼容,因此默认不启用。可用 ARTEX_TARGETS 自定义目标;确认目标运行环境兼容时,可显式传入 --upx 进一步缩小二进制:
ARTEX_TARGETS
--upx
ARTEX_TARGETS=linux/amd64,windows/amd64 ./build.sh --release ./build.sh --target linux/amd64 --upx
升级只换程序、不动数据:Postgres 数据卷 pgdata、./data(jwt.key / SQLite 等)、./skills 都会保留。数据库迁移无需手动执行——artex 每次启动会幂等重跑 schema.sql(含 ADD COLUMN / CREATE INDEX IF NOT EXISTS),即“重启即迁移”。升级前仍建议先备份 ./data 与数据库。
pgdata
schema.sql
ADD COLUMN
CREATE INDEX IF NOT EXISTS
页面一键更新固定从 Hinln/ARTEX Releases 检查和下载版本。克隆或通过 Git 更新源码也使用 Hinln/ARTEX;原项目的 Go module 路径保持不变。
Hinln/ARTEX
这是私有仓库。请为运行 ARTEX 的后端进程设置 ARTEX_UPDATE_GITHUB_TOKEN,令牌只需本仓库的 Contents: read 权限。令牌由后端用于查询 Release 和下载附件,不发送给浏览器,也不要提交到 Git。
ARTEX_UPDATE_GITHUB_TOKEN
# 先在当前 shell 或服务环境中安全设置 ARTEX_UPDATE_GITHUB_TOKEN ./start.sh
本地直接启动时,start.sh 不会自动读取 .env;必须将变量导出到进程环境。Docker Compose 部署则可在未纳入 Git 的 .env 中填写该变量,并重建 artex 容器;镜像需要包含本分支的更新代码,旧版镜像不会因此切换升级源。
需要先在本仓库发布非 draft、非 prerelease 的正式 Release,并附上 artex-<版本>-<os>-<arch>.zip 和 SHA256SUMS,页面才能提供可安装更新。仓库里只有源码时还不能在线升级。现有 Release 工作流会在推送 v* tag 时为当前仓库生成这些附件。
artex-<版本>-<os>-<arch>.zip
SHA256SUMS
v*
在 系统配置 页(侧边栏「系统配置」→ /system/settings)的版本与更新卡片里,可以直接检查并安装新版本,无需登录服务器。
/system/settings
点「更新」后:下载当前平台的发布包 → 比对 Release 的 SHA256SUMS → 用 -h 冒烟测试新二进制 → 暂存为 artex.new → 程序退出,由 start.sh / start.bat 重新拉起并完成换装。页面会自动等到新版本上线后刷新。
-h
artex.new
artex.old
artex.failed
dev
git describe
docker compose pull artex && docker compose up -d artex
cd ARTEX ./update.sh
脚本先可选 git pull 拉取最新代码,再让你选 ① Docker 更新 或 ② 本地编译更新(与 install.sh 对应):
git pull
install.sh
ARTEX_TAG
latest
docker compose pull
cd ARTEX git pull # 更新 compose / 脚本(可选) # 指定版本:在 .env 设 ARTEX_TAG=v0.2.0;不设则用 latest docker compose pull artex docker compose up -d artex # 换新镜像重启 → 自动迁移 schema docker image prune -f # 清理旧镜像(可选)
到 Releases 下载新版本 zip,停掉旧进程后覆盖 artex 与 skills/(保留你的 config.json 与 data/),重启即可:
data/
cp -r <解压目录>/skills ./ && cp <解压目录>/artex ./ ./start.sh
git pull cd web && npm ci && npm run build:static && cd .. cp -r web/out server/webui/dist CGO_ENABLED=0 go build -tags embedui -o artex ./cmd/artex # 重启 ./start.sh
数据库(config.json,或用环境变量 ARTEX_PG_DSN 覆盖):
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。
export ANTHROPIC_API_KEY=sk-...
ARTEX_LLM_PROVIDER
ARTEX_LLM_MODEL
ARTEX_LLM_BASE_URL
ARTEX_LLM_PROXY
并发:每个任务的 work agent 数在「系统设置」里配置(默认 3)。
常用参数:./start.sh -addr :8787 -proxy :8788(-addr 前端+API,-proxy 流量录制代理)。启动脚本会把参数原样透传给 artex。
./start.sh -addr :8787 -proxy :8788
-addr
-proxy
前端和 API/SSE 都由同一个后端端口(默认 :8787)提供,实时活动流默认走同源地址,因此**无需配置 NEXT_PUBLIC_SSE_BASE**,公网只开放 443、把 8787 留在内网即可。
:8787
NEXT_PUBLIC_SSE_BASE
SSE 是长连接 + 持续推送,反代必须关闭缓冲,否则浏览器能连上却收不到事件(表现为活动流一直转圈)。Nginx 示例:
server { listen 443 ssl; server_name your.domain.com; # ssl_certificate / ssl_certificate_key ... location / { proxy_pass http://127.0.0.1:8787; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $scheme; # SSE 关键项:关缓冲、长超时、HTTP/1.1 proxy_buffering off; proxy_cache off; proxy_read_timeout 3600s; proxy_http_version 1.1; proxy_set_header Connection ""; } }
仅当 SSE 需要走与页面不同的来源(如独立子域)时,才在构建期设置 NEXT_PUBLIC_SSE_BASE(该变量在 next build 时固化进静态包,容器运行时再设无效)。
next build
任务详情的「复测」页签可分页选择本任务的漏洞、查看历次结论和证据,并手动发起复测。启动后保留当前页签,显示转圈图标和「复测中」;确认修复后同步更新漏洞状态。
在漏洞列表每行操作区点击「复测」,或在漏洞详情的「漏洞复测」区域点击「发起复测」,填写可选的修复版本、测试条件或限制,系统会创建独立的复测 Agent 会话,启动后保留当前页面。列表的平铺、按任务分组和资产视图均支持该入口;复测运行时显示转圈图标和「复测中」,需要查看时点击进入对应会话,结束后恢复「复测」。复测无需重新启动原扫描任务,结论分为「仍可复现」「已修复」「无法确认」,每次的结论、证据和会话链接保存在漏洞详情中。
新版后端首次启动会预置可编辑的「漏洞复测」(retester)Agent,可在 Agent 管理中配置提示词、LLM、运行预算和工具。默认使用其绑定的 LLM,未绑定则使用全局激活配置。复测会话成功完成且结论为「已修复」时,系统自动将漏洞处置状态改为「已修复」;执行中、失败、停止或其他结论保留原状态。原始证据和报告始终保留。也可在状态下拉菜单中手动选择「已修复」。同一漏洞正在复测时复用已有会话,停止、失败或服务重启后可重新发起。
retester
本版历史记录通过漏洞详情和会话查看,暂未纳入漏洞报告导出或任务归档包,也未自动关联流量包。演示模式只生成明确标注的模拟记录,不请求真实目标。
./dev.sh # 后端(:8787) + 流量代理(:8788) + 前端 next dev(:5173) → http://localhost:5173
go run ./cmd/artex
-tags embedui
cd web && npm run dev
/api
go test ./...
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 稳定攻击链路。
norma
agentcore
tool
permission
harness
memory
transcript
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
go:embed
net/http
Manager
plannerLoop
ToolSet
系统把「目标是什么」和「测到了什么程度」拆成两张相互独立、又通过锚点相连的图:
root_domain / subdomain / ip / service / app / endpoint
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)。
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)
intent_id
list_worker_traces
get_worker_trace(intent_id, step_ids=[…])
这样即便探索图上还没有对应的 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):
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 能自主走完多步利用链的关键。
扫码关注微信公众号 SecSentry,在公众号后台私信即可入群交流。
https://github.com/oritera/Cairn
本项目采用 GNU Affero General Public License v3.0(AGPL-3.0) 授权,完整条款见仓库根目录的 LICENSE 文件。
这意味着任何人都可以自由使用、修改和分发本项目,但衍生作品必须同样以 AGPL-3.0 开源;特别地,若你修改本项目并通过网络(如部署为在线服务)向用户提供,也必须向这些用户公开对应的完整源码。
⚠️ 重要提示:开源协议本身不限制软件的使用用途。以下的「使用限制」与「免责声明」是作者对使用者的额外约定与郑重声明,请务必遵守。
ARTEX 仅供个人学习、代码研究与本地技术验证使用,不得用于对任何线上系统或网站发起实际测试。
使用者须自行遵守所在国家/地区关于网络安全、数据保护与计算机犯罪的全部法律法规(在中国大陆包括但不限于《网络安全法》《数据安全法》《个人信息保护法》及相关司法解释)。因使用本工具产生的一切法律责任与后果,均由使用者自行承担。
本项目按“现状(AS IS)”提供,不附带任何明示或默示的担保。作者及贡献者不对使用本工具(无论使用方式是否得当)所导致的任何直接或间接损失、数据丢失、系统损坏或法律纠纷承担责任。下载、安装或使用本项目,即表示你已阅读、理解并同意上述全部条款。
版权所有:中国计算机学会技术支持:开源发展技术委员会 京ICP备13000930号-9 京公网安备 11010802047560号
ARTEX
AI 自主渗透测试系统(Go 后端 + Next.js 前端)
🌐 在线 Demo: https://artex-demo.vercel.app/
截图预览
审批记录详情
全局「审批记录」、任务内「拦截审批」及对话中的审批卡片均支持展开查看详情。展示结构参考 AegisHook 的审批详情组件,沿用 ARTEX 的组件和主题:
资产同步(ScopeSentry)
支持从 ScopeSentry 直接同步资产数据,免去重复收集:
安装
方式一:一键安装脚本(推荐)
脚本会:检测 / 自动安装 Docker → 让你选 ① 全部 Docker 或 ② 本地编译运行:
.env→docker compose up -d。config.json→go编译内嵌单二进制 → 启动。装好后打开 http://localhost:8787(首次进入
/setup设置管理员密码)。方式二:Docker Compose(手动)
镜像已含常用工具(ripgrep/curl/vim/npm/nmap…);
./skills与./data以绑定挂载持久化。远程 MCP 可在系统设置中选择
http(Streamable HTTP)或sse(旧版 SSE)。 旧版 SSE 服务通常使用GET /sse建立事件流,再通过服务返回的/message?sessionId=...接收 JSON-RPC 请求;配置时将 URL 填为/sse,请求头按Authorization=Bearer <token>填写。方式三:下载预编译二进制(Releases)
到 Releases 下载对应平台的 zip,解压后得到
artex+start.sh(Windows 为start.bat)+skills/+config.example.json:方式四:从源码编译单二进制
方式五:构建跨平台 Release 压缩包
build.sh会先构建并嵌入前端,再使用 Go linker 去除调试信息,并将发布文件压缩为 zip。Release 模式默认生成 Linux amd64/arm64、macOS amd64/arm64 和 Windows amd64 的 zip 包:UPX 自解压二进制可能与部分 Linux 内核、虚拟化环境或安全策略不兼容,因此默认不启用。可用
ARTEX_TARGETS自定义目标;确认目标运行环境兼容时,可显式传入--upx进一步缩小二进制:更新升级
本仓库的私有 Release 更新源
页面一键更新固定从 Hinln/ARTEX Releases 检查和下载版本。克隆或通过 Git 更新源码也使用
Hinln/ARTEX;原项目的 Go module 路径保持不变。这是私有仓库。请为运行 ARTEX 的后端进程设置
ARTEX_UPDATE_GITHUB_TOKEN,令牌只需本仓库的 Contents: read 权限。令牌由后端用于查询 Release 和下载附件,不发送给浏览器,也不要提交到 Git。本地直接启动时,
start.sh不会自动读取.env;必须将变量导出到进程环境。Docker Compose 部署则可在未纳入 Git 的.env中填写该变量,并重建 artex 容器;镜像需要包含本分支的更新代码,旧版镜像不会因此切换升级源。需要先在本仓库发布非 draft、非 prerelease 的正式 Release,并附上
artex-<版本>-<os>-<arch>.zip和SHA256SUMS,页面才能提供可安装更新。仓库里只有源码时还不能在线升级。现有 Release 工作流会在推送v*tag 时为当前仓库生成这些附件。方式一:页面一键更新(推荐)
在 系统配置 页(侧边栏「系统配置」→
/system/settings)的版本与更新卡片里,可以直接检查并安装新版本,无需登录服务器。点「更新」后:下载当前平台的发布包 → 比对 Release 的
SHA256SUMS→ 用-h冒烟测试新二进制 → 暂存为artex.new→ 程序退出,由start.sh/start.bat重新拉起并完成换装。页面会自动等到新版本上线后刷新。artex.old(失败的那个留作artex.failed供排查)。artex.old,卡片上有「回滚到上一版本」。注意数据库结构不会回退。dev或git describe带后缀时禁用,避免正式版覆盖掉本地调试的二进制。docker compose up -d重建容器后会退回镜像自带的版本。要连镜像一起升级仍请用docker compose pull artex && docker compose up -d artex。方式二:一键更新脚本
脚本先可选
git pull拉取最新代码,再让你选 ① Docker 更新 或 ② 本地编译更新(与install.sh对应):.env的ARTEX_TAG,缺省latest)→docker compose pull→docker compose up -d(换新镜像重启即自动迁移)。./artex(完成后重启进程生效)。方式三:Docker Compose(手动)
方式四:预编译二进制(Releases)
到 Releases 下载新版本 zip,停掉旧进程后覆盖
artex与skills/(保留你的config.json与data/),重启即可:方式五:从源码编译
配置
数据库(
config.json,或用环境变量ARTEX_PG_DSN覆盖):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)。
常用参数:
./start.sh -addr :8787 -proxy :8788(-addr前端+API,-proxy流量录制代理)。启动脚本会把参数原样透传给artex。反向代理部署(HTTPS / 只开放 443)
前端和 API/SSE 都由同一个后端端口(默认
:8787)提供,实时活动流默认走同源地址,因此**无需配置NEXT_PUBLIC_SSE_BASE**,公网只开放 443、把 8787 留在内网即可。SSE 是长连接 + 持续推送,反代必须关闭缓冲,否则浏览器能连上却收不到事件(表现为活动流一直转圈)。Nginx 示例:
开发
手动漏洞复测
任务详情的「复测」页签可分页选择本任务的漏洞、查看历次结论和证据,并手动发起复测。启动后保留当前页签,显示转圈图标和「复测中」;确认修复后同步更新漏洞状态。
在漏洞列表每行操作区点击「复测」,或在漏洞详情的「漏洞复测」区域点击「发起复测」,填写可选的修复版本、测试条件或限制,系统会创建独立的复测 Agent 会话,启动后保留当前页面。列表的平铺、按任务分组和资产视图均支持该入口;复测运行时显示转圈图标和「复测中」,需要查看时点击进入对应会话,结束后恢复「复测」。复测无需重新启动原扫描任务,结论分为「仍可复现」「已修复」「无法确认」,每次的结论、证据和会话链接保存在漏洞详情中。
新版后端首次启动会预置可编辑的「漏洞复测」(
retester)Agent,可在 Agent 管理中配置提示词、LLM、运行预算和工具。默认使用其绑定的 LLM,未绑定则使用全局激活配置。复测会话成功完成且结论为「已修复」时,系统自动将漏洞处置状态改为「已修复」;执行中、失败、停止或其他结论保留原状态。原始证据和报告始终保留。也可在状态下拉菜单中手动选择「已修复」。同一漏洞正在复测时复用已有会话,停止、失败或服务重启后可重新发起。本版历史记录通过漏洞详情和会话查看,暂未纳入漏洞报告导出或任务归档包,也未自动关联流量包。演示模式只生成明确标注的模拟记录,不请求真实目标。
本地运行与测试
go run ./cmd/artex(不带-tags embedui则不内嵌前端)cd web && npm run dev(/api反代到后端,带热更新)go test ./...cd web && NEXT_PUBLIC_MOCK=1 npm run dev系统技术架构
ARTEX 是一套 LLM 多 agent 驱动的自主渗透系统:Go 单体后端(内嵌 Next.js 前端)+ PostgreSQL,agent 能力由
normaSDK 提供(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 -.-> EXTgo:embed内嵌进单二进制;可视化任务/资产/探索链路/覆盖图,人在环路对话net/http路由 + JWT 鉴权 + SSE;Manager托管任务、引擎、DB store 的生命周期plannerLoop+ N 个 worker goroutine;意图领取、超时/暂停/drainToolSet把双图暴露成 LLM 工具go:embed每次启动幂等建表双图架构:探索图 + 资产图
系统把「目标是什么」和「测到了什么程度」拆成两张相互独立、又通过锚点相连的图:
root_domain / subdomain / ip / service / app / endpoint,归属公司;域名→子域→服务→端点的父子关系与去重 key 全部由程序计算,agent 只提交原始信息。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,planner 派意图,worker 领意图执行并写回,写回又触发下一轮——直到目标被证明(
prove_goal)。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 仍只做自己领到的那条意图)。
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) 返回完整过程内容"| WCplanner 多轮共享 todolist → 稳定的攻击链路
真实攻击链往往是有前后依赖的多步序列(如:发现注入点 → 拿到凭据 → 横向 → 提权),一次性把这些并行派下去只会乱套。planner 因此持有一份按任务保留、跨唤醒共享的规划待办(todolist):
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 能自主走完多步利用链的关键。
交流群
扫码关注微信公众号 SecSentry,在公众号后台私信即可入群交流。
参考
https://github.com/oritera/Cairn
许可与免责声明
开源协议
本项目采用 GNU Affero General Public License v3.0(AGPL-3.0) 授权,完整条款见仓库根目录的 LICENSE 文件。
这意味着任何人都可以自由使用、修改和分发本项目,但衍生作品必须同样以 AGPL-3.0 开源;特别地,若你修改本项目并通过网络(如部署为在线服务)向用户提供,也必须向这些用户公开对应的完整源码。
ARTEX 仅供个人学习、代码研究与本地技术验证使用,不得用于对任何线上系统或网站发起实际测试。
允许使用范围
禁止事项
合规责任
使用者须自行遵守所在国家/地区关于网络安全、数据保护与计算机犯罪的全部法律法规(在中国大陆包括但不限于《网络安全法》《数据安全法》《个人信息保护法》及相关司法解释)。因使用本工具产生的一切法律责任与后果,均由使用者自行承担。
免责声明
本项目按“现状(AS IS)”提供,不附带任何明示或默示的担保。作者及贡献者不对使用本工具(无论使用方式是否得当)所导致的任何直接或间接损失、数据丢失、系统损坏或法律纠纷承担责任。下载、安装或使用本项目,即表示你已阅读、理解并同意上述全部条款。