Skip to content
RC-CHNPublic

About

No description, website, or topics provided.

Resources

Stars

6 stars

Watchers

1 watching

Forks

Latest commit

 

History

508 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ARTEX

AI 自主渗透测试系统(Go 后端 + Next.js 前端)

📦 由 RC-CHN/ARTEX 独立维护。安装包、自动升级和容器均由本仓库的 GitHub Actions 验证与发布:GitHub Releases + ghcr.io/rc-chn/artex。完整源码与本地维护的 Norma SDK 均在仓库内。


截图预览

截图展示本项目的任务、资产和探索界面。

仪表盘(总览 / Token 消耗 / 活动流) 任务列表
仪表盘 任务
任务 · 执行过程(会话 / 工具调用) 探索链路
执行过程 探索链路
发现 资产
发现 资产
资产覆盖图(力导向布局 · 已测高亮 · 节点折叠展开)
资产覆盖图
流量录制 人在环路对话
流量 对话
Agent 管理 LLM 配置
Agent LLM
拦截审批 后端日志
拦截 日志

审批记录详情

全局「审批记录」、任务内「拦截审批」及对话中的审批卡片均支持展开查看详情。展示结构参考 AegisHook 的审批详情组件,沿用 ARTEX 的组件和主题:

资产同步(ScopeSentry)

可选接入用户自行部署的 ScopeSentry 兼容 API,同步资产数据:

  • 在「资产同步」页填 ScopeSentry 的地址与 API Key,接入数据源;
  • 按项目或任务维度选择要同步的目标与资产类型(域名 / 子域 / IP / 端口 / 站点 / 端点…);
  • 一键导入并按公司资产范围归并,直接进入 ARTEX 的资产图供 agent 探索使用。

安装

依赖数据库 PostgreSQL;探索需配置 LLM(ANTHROPIC_API_KEY 或 OPENAI_API_KEY,也可在 UI 里配)。

方式一:一键安装脚本(推荐)

git clone https://github.com/RC-CHN/ARTEX.git
cd ARTEX
./install.sh

脚本会:检测 / 自动安装 Docker → 让你选 ① 全部 Docker 或 ② 本地编译运行:

  • ① 全部 Docker:填一个 Postgres 密码(可回车随机)→ 自动写 .env → docker compose up -d。
  • ② 本地运行:选数据库(连已有 / 用 Docker 起一个)→ 生成 config.json → go 编译内嵌单二进制 → 启动。

装好后打开 **http://localhost:8787**(首次进入 /setup 设置管理员密码)。

方式二:Docker Compose(手动)

git clone https://github.com/RC-CHN/ARTEX.git
cd ARTEX
cp .env.example .env          # 填 POSTGRES_PASSWORD、可选 ANTHROPIC_API_KEY
docker compose up -d          # 拉取 ghcr.io/rc-chn/artex 镜像 + postgres
# → http://localhost:8787

镜像由本仓库发布到 ghcr.io/rc-chn/artex;生产部署建议指定版本或摘要。 镜像源不可用(或想自行改代码)时,本地从纯源码构建即可:docker compose build && docker compose up -d。 Dockerfile 为多阶段构建(前端静态导出 → Go 静态编译 → 运行镜像),默认走国内友好依赖源,可加 --build-arg GOPROXY=... / --build-arg NPM_REGISTRY=... 覆盖。

镜像已含常用工具(ripgrep/curl/vim/npm/nmap…);./skills 与 ./data 以绑定挂载持久化。

使用自建镜像仓库时,在 .env 中设置镜像路径和版本,例如:

ARTEX_IMAGE=registry.example.com/project/artex
ARTEX_TAG=latest

将 registry.example.com/project/artex 替换为自己的镜像路径。私有仓库先执行 docker login registry.example.com,再执行 docker compose pull && docker compose up -d。实际配置只写入已被 Git 忽略的 .env。 本地构建可通过 --build-arg ARTEX_BUILD_VERSION=<版本> 写入程序版本号。

远程 MCP 可在系统设置中选择 http(Streamable HTTP)或 sse(旧版 SSE)。 旧版 SSE 服务通常使用 GET /sse 建立事件流,再通过服务返回的 /message?sessionId=... 接收 JSON-RPC 请求;配置时将 URL 填为 /sse,请求头按 Authorization=Bearer <token> 填写。

支持默认关闭的实验性远程 Runner:独立 Linux 主机主动注册,一个节点承载多个隔离线程,并按 CPU、内存、GPU 和环境能力调度。统一下发 MCP 配置和任务文件,仍可选择原有本机执行。

完整镜像预装常用 Python/SSH 工具和固定版本安全工具;工具仓库与验证工作流提供多架构包、按需 SFTP 分发、真实身份验证、共享请求预算和持久化 HTTP 回调。嵌入式交叉编译包单独生成,按需取用,不复制进每个任务目录。

方式三:下载预编译二进制(Releases)

到本仓库 Releases 下载对应平台的 zip 和 SHA256SUMS 并核对校验和:解压后得到 artex + start.sh(Windows 为 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 &。

方式四:从源码编译单二进制

# 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

方式五:构建跨平台 Release 压缩包

build.sh 会先构建并嵌入前端,再使用 Go linker 去除调试信息,并将发布文件压缩为 zip。Release 模式默认生成 Linux amd64/arm64、macOS amd64/arm64 和 Windows amd64 的 zip 包:

./build.sh --release
# 产物:dist/artex-0.3.3-*.zip

UPX 自解压二进制可能与部分 Linux 内核、虚拟化环境或安全策略不兼容,因此默认不启用。可用 ARTEX_TARGETS 自定义目标;确认目标运行环境兼容时,可显式传入 --upx 进一步缩小二进制:

ARTEX_TARGETS=linux/amd64,windows/amd64 ./build.sh --release
./build.sh --target linux/amd64 --upx

方式六:k3s / Kubernetes

deploy/k8s 提供 ARTEX 单实例、PostgreSQL 16 和 LoadBalancer 的通用部署清单。应用数据与数据库各申请 10Gi 的集群共享存储;应用卷要求 RWX。自定义技能保存在应用卷,JWT 签名密钥保存在 Secret,Pod 重建后会继续使用。

基础清单使用本仓库的 ghcr.io/rc-chn/artex 镜像;存储类 shared-storage 是占位符,部署前必须配置。复制 deploy/overlay.example 到 deploy/private,在覆盖文件中填写自己的镜像路径、版本或摘要,以及支持 RWX 的集群共享存储类。数据库也使用共享存储,不要选用 local-path 等节点本地存储。deploy/private 已被 Git 和 Docker 构建上下文忽略,不应强制提交。

先创建 artex 命名空间,并在该命名空间准备以下 Secret:

Secret 必需字段 用途
registry-pull .dockerconfigjson 私有镜像仓库拉取凭据,类型为 kubernetes.io/dockerconfigjson
artex-postgres password 数据库密码,使用随机十六进制字符串
artex-auth jwt.key 至少 32 字符的随机 JWT 签名密钥
cp -r deploy/overlay.example deploy/private
# 编辑 deploy/private/kustomization.yaml,填写镜像与共享存储类
kubectl apply -f deploy/k8s/namespace.yaml
# 准备上述 Secret 后部署
kubectl apply -k deploy/private
kubectl -n artex get pods,pvc,service

访问 artex Service 分配的 LoadBalancer 地址,首次进入 /setup/ 设置管理员密码,然后在「系统 → LLM 配置」添加并激活模型。升级时修改私有覆盖文件中的 ARTEX 镜像版本或摘要后重新应用;Deployment 使用 Recreate,保持单个调度进程。Secret 通过集群单独创建,不要把凭据写进部署清单。

流量索引与旧版本迁移

运行时流量索引复用 ARTEX_PG_DSN 指定的 PostgreSQL,在独立的 artex_traffic schema 中保存元数据、报文头、小正文和 blob 引用。大正文保留在共享卷的 data/traffic/_blobs;使用 pg_trgm 的 GIN 索引支持中文和任意子串搜索。派生搜索文档由数据库写入触发器统一转小写,查询使用 LIKE lower(...),避免逐次对候选大正文做大小写转换;原始报文保持字节不变。数据库用户需有创建 schema 与 pg_trgm 扩展的权限;受限环境可由管理员预先安装 CREATE EXTENSION pg_trgm WITH SCHEMA public;。

旧 PostgreSQL 搜索文档会在启动时一次性规范化,与 folded-search-v2 标记在同一事务提交;触发器也兼容旧镜像写入。PG 搜索索引回填默认限时 30 分钟,可通过 ARTEX_TRAFFIC_MIGRATION_TIMEOUT=60m 调整,并相应延长部署的 startup probe;正常查询仍限时 2 分钟。

从 SQLite 版本升级时,先停止旧实例并备份 PostgreSQL 与应用数据卷,再启动新版本。Kubernetes 保持单副本和 Recreate。检测到 data/traffic/_index/index.sqlite 后,程序会复制数据库及 WAL 到临时目录,保留原文件,验证完整性与 blob 校验和,然后在一个 PostgreSQL 事务中导入历史 ID、正文和引用、重建搜索索引并写入完成标记。迁移失败会终止启动,事务回滚后可修复问题并重试;成功后重启不会重复导入或恢复已删除的流量。

/api/health 中的 traffic_backend 应为 postgres。迁移后的新录制只写 PostgreSQL,SQLite 文件作为迁移前备份保留;回退旧版本需要同时恢复升级前的数据库与文件快照,不能仅回退镜像。普通删除交给 PostgreSQL autovacuum 回收可复用空间,「清空流量」额外执行限时 VACUUM (ANALYZE)。

流量存储回归测试与 benchmark 使用独立的测试数据库,通过 ARTEX_TRAFFIC_TEST_DSN 显式指定;每次使用独立 schema 并自动清理。不要将其指向生产数据库。

export ARTEX_TRAFFIC_TEST_DSN='postgres://test_user:test_password@127.0.0.1:5432/artex_test?sslmode=disable'
go test ./traffic -count=1
go test ./traffic -run '^$' -bench '^BenchmarkTrafficIndex$' -benchmem -benchtime=2s -count=3 -cpu=4

默认构造 10,000 条、每条 4 KiB 正文的数据,分布于 100 个主机;可用 ARTEX_TRAFFIC_BENCH_ROWS 调整规模。测试比较 SQLite WAL 本地文件与 PostgreSQL 的读取、主机分页、正文搜索、筛选分页、并发读取和录制,报告平均耗时、P50/P95、内存分配与初始索引占用。建库、生成数据和清理不计入耗时;SQLite 仅用作性能基线与兼容测试,不作为共享文件系统上的生产后端。

搜索优化后三轮实测:同一 10,000 条语料下,PG 正文搜索从 5.714 ms 降至 1.832 ms(−67.9%),组合筛选从 15.623 ms 降至 6.929 ms(−55.6%);录制从 1.745 ms 增至 1.917 ms(+9.9%)。正文搜索快于本轮 SQLite,组合筛选仍略慢;详见报告中的完整延迟、P95 和测试边界。首次迁移基线继续保留。

开发回归与镜像构建

全项目集成测试使用显式的 ARTEX_TEST_PG_DSN(兼容 ARTEX_PG_DSN)。测试用户需要 CREATEDB 权限;每个包创建独立数据库,结束后自动删除,不在指定的管理数据库中清理业务表。未设置时跳过 PG 集成测试,不读取应用的 config.json。流量包继续使用独立 schema 的 ARTEX_TRAFFIC_TEST_DSN。

export ARTEX_TEST_PG_DSN='postgres://test_user:test_password@127.0.0.1:5432/artex_test?sslmode=disable'
export ARTEX_TRAFFIC_TEST_DSN="$ARTEX_TEST_PG_DSN"
go test ./... -count=2
go test -race ./server ./llmpool ./traffic ./enrich
(cd norma && go test ./...)
(cd web && npm run test:unit && npm run typecheck)

关闭服务时会停止接收后台工作、取消并等待任务及日志写入,再关闭数据库。关联公司的任务范围会进入 Planner / 主 Agent 概览,即使覆盖率统计关闭或尚未发现资产也保留范围规则。

容器基础镜像固定摘要,浏览器工具通过公开 npm lockfile 固定直接及传递依赖。发布版本参数只影响编译和镜像标签,工具安装层可复用。构建阶段验证各工具实际使用的 Chromium 与 MCP 调用;详见 构建与缓存验证。

GitHub CI/CD

本仓库的 CI 在 main 推送和 Pull Request 时运行:模块来源与固定版本检查、工作流校验、PostgreSQL 两轮全量回归、调度/取消/故障转移与关闭的 race 检查、Norma SDK 全套测试、前端缓存单测和静态构建,以及临时数据库上的容器 API 与真实浏览器验证。

正式发布使用主分支上的版本标签,例如:

git tag v0.4.0
git push origin v0.4.0

Release 工作流 会重新验证标签对应的提交,生成五个平台的 zip 和 SHA256SUMS,原生测试 Linux amd64 / arm64 镜像后发布到本仓库的 Releases 和 ghcr.io/rc-chn/artex。镜像提供 v0.4.0、0.4.0 这样的版本标签;只有最高的完整正式版本可更新 latest,预发布不更新。已公开的版本不可覆盖,请用新版本标签发布修改。

Actions 使用仓库自带的 GITHUB_TOKEN,无需保存个人访问令牌。首次发布 GHCR 包后,仓库维护者须在该包的 GitHub 设置中将可见性设为 Public,匿名用户才能拉取。工作流不保存集群、私有镜像站或数据库凭据。

若制品已发布但 latest 提升失败,可在 Actions 手动运行 Promote latest,填入该正式版本标签;它会检查完整制品和版本顺序,不重建或覆盖版本镜像。集群升级独立进行:验证版本和摘要、备份数据库与共享卷,再修改私有覆盖文件部署,检查健康和数据后完成升级。


更新升级

升级只换程序、不动数据:Postgres 数据卷 pgdata、./data(流量 blob / 会话记录等)、./skills 都会保留。数据库迁移无需手动执行——artex 每次启动会幂等重跑 schema.sql(含 ADD COLUMN / CREATE INDEX IF NOT EXISTS),即“重启即迁移”。升级前仍建议先备份 ./data 与数据库。

方式一:页面一键更新(推荐)

在 系统配置 页(侧边栏「系统配置」→ /system/settings)的版本与更新卡片里,可以直接检查并安装新版本,无需登录服务器。

点「更新」后:下载当前平台的发布包 → 比对 Release 的 SHA256SUMS → 用 -h 冒烟测试新二进制 → 暂存为 artex.new → 程序退出,由 start.sh / start.bat 重新拉起并完成换装。页面会自动等到新版本上线后刷新。

  • 失败不会留下坏程序:校验或冒烟不通过就丢弃暂存件、继续跑当前版本;换装后的新版若连续 3 次启动失败,会自动回滚到 artex.old(失败的那个留作 artex.failed 供排查)。
  • 随时可回退:上一版本保留为 artex.old,卡片上有「回滚到上一版本」。注意数据库结构不会回退。
  • 更新会中断正在运行的任务——更新即重启,请在空闲时进行。
  • 开发构建不给更新:版本号是 dev 或 git describe 带后缀时禁用,避免正式版覆盖掉本地调试的二进制。
  • Docker 下只换程序、不换镜像:镜像里的 playwright / nmap 等工具链不会跟着升级,且 docker compose up -d 重建容器后会退回镜像自带的版本。要连镜像一起升级仍请用 docker compose pull artex && docker compose up -d artex。
  • 访问 GitHub 需要代理时,在同一页面配置全局代理即可,更新链路会走它。更新只从 GitHub 域名下载并强制 HTTPS。

方式二:一键更新脚本

cd ARTEX
./update.sh

脚本先可选 git pull 拉取最新代码,再让你选 ① Docker 更新 或 ② 本地编译更新(与 install.sh 对应):

  • ① Docker:可指定目标镜像 tag(回车沿用 .env 的 ARTEX_TAG,缺省 latest)→ docker compose pull → docker compose up -d(换新镜像重启即自动迁移)。
  • ② 本地:重建前端静态产物 → 重新编译 ./artex(完成后重启进程生效)。

方式三:Docker Compose(手动)

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)

到 Releases 下载新版本 zip,停掉旧进程后覆盖 artex 与 skills/(保留你的 config.json 与 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 覆盖):

{
  "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)。

常用参数:./start.sh -addr :8787 -proxy :8788(-addr 前端+API,-proxy 流量录制代理)。启动脚本会把参数原样透传给 artex。

反向代理部署(HTTPS / 只开放 443)

前端和 API/SSE 都由同一个后端端口(默认 :8787)提供,实时活动流默认走同源地址,因此无需配置 NEXT_PUBLIC_SSE_BASE,公网只开放 443、把 8787 留在内网即可。

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 时固化进静态包,容器运行时再设无效)。


开发

手动漏洞复测

任务详情的「复测」页签可分页选择本任务的漏洞、查看历次结论和证据,并手动发起复测。启动后保留当前页签,显示转圈图标和「复测中」;确认修复后同步更新漏洞状态。

在漏洞列表每行操作区点击「复测」,或在漏洞详情的「漏洞复测」区域点击「发起复测」,填写可选的修复版本、测试条件或限制,系统会创建独立的复测 Agent 会话,启动后保留当前页面。列表的平铺、按任务分组和资产视图均支持该入口;复测运行时显示转圈图标和「复测中」,需要查看时点击进入对应会话,结束后恢复「复测」。复测无需重新启动原扫描任务,结论分为「仍可复现」「已修复」「无法确认」,每次的结论、证据和会话链接保存在漏洞详情中。

新版后端首次启动会预置可编辑的「漏洞复测」(retester)Agent,可在 Agent 管理中配置提示词、LLM、运行预算和工具。默认使用其绑定的 LLM,未绑定则使用全局激活配置。复测会话成功完成且结论为「已修复」时,系统自动将漏洞处置状态改为「已修复」;执行中、失败、停止或其他结论保留原状态。原始证据和报告始终保留。也可在状态下拉菜单中手动选择「已修复」。同一漏洞正在复测时复用已有会话,停止、失败或服务重启后可重新发起。

本版历史记录通过漏洞详情和会话查看,暂未纳入漏洞报告导出或任务归档包,也未自动关联流量包。演示模式只生成明确标注的模拟记录,不请求真实目标。

本地运行与测试

./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
Loading
层 职责
前端 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
Loading

分工: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: 再次唤醒(闭环)
Loading

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) 返回完整过程内容"| WC
Loading

planner 多轮共享 todolist → 稳定的攻击链路

真实攻击链往往是有前后依赖的多步序列(如:发现注入点 → 拿到凭据 → 横向 → 提权),一次性把这些并行派下去只会乱套。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
Loading

于是攻击链在“事件驱动 + 无状态会话”的环境下依然稳定推进、不重复、不错序——这是 ARTEX 能自主走完多步利用链的关键。


交流群

扫码关注微信公众号 SecSentry,在公众号后台私信即可入群交流。

微信公众号 SecSentry

参考

https://github.com/oritera/Cairn

许可与免责声明

开源协议

本项目采用 GNU Affero General Public License v3.0(AGPL-3.0) 授权,完整条款见仓库根目录的 LICENSE 文件。

这意味着任何人都可以自由使用、修改和分发本项目,但衍生作品必须同样以 AGPL-3.0 开源;特别地,若你修改本项目并通过网络(如部署为在线服务)向用户提供,也必须向这些用户公开对应的完整源码。

⚠️ 重要提示:开源协议本身不限制软件的使用用途。以下的「使用限制」与「免责声明」是作者对使用者的额外约定与郑重声明,请务必遵守。

ARTEX 仅供个人学习、代码研究与本地技术验证使用,不得用于对任何线上系统或网站发起实际测试。

允许使用范围

  • 仅可用于阅读、学习与研究本项目源码,以及在本地隔离环境中进行技术原理验证;
  • 适用于个人学习、学术研究、代码审阅等非攻击性用途。

禁止事项

  • 严禁使用本工具对任何网站、线上服务或联网系统发起扫描、探测、利用或攻击(无论是否获得授权、是否为自有资产);
  • 严禁将本工具用于任何实际的渗透测试、攻防对抗或生产环境;
  • 严禁将本工具用于非法入侵、数据窃取、勒索、拒绝服务或任何破坏性、犯罪性活动;
  • 严禁利用本工具从事违反所在国家/地区法律法规的行为。

合规责任

使用者须自行遵守所在国家/地区关于网络安全、数据保护与计算机犯罪的全部法律法规(在中国大陆包括但不限于《网络安全法》《数据安全法》《个人信息保护法》及相关司法解释)。因使用本工具产生的一切法律责任与后果,均由使用者自行承担。

免责声明

本项目按“现状(AS IS)”提供,不附带任何明示或默示的担保。作者及贡献者不对使用本工具(无论使用方式是否得当)所导致的任何直接或间接损失、数据丢失、系统损坏或法律纠纷承担责任。下载、安装或使用本项目,即表示你已阅读、理解并同意上述全部条款。

About

No description, website, or topics provided.

Resources

Stars

6 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages