ARTEX 安全排查、项目搭建与本地镜像部署
整理日期:2026-11-05
适用环境:Windows 11、PowerShell、Docker Desktop、WSL2文档结构
- 危险项目信息与后门 IOC
- 本机安全排查命令
- ARTEX 项目搭建与本地构建
- 本地镜像拉取、保存、加载与启动
脱敏说明: 本文不包含真实数据库密码、API Key、Token、Windows 用户名或不必要的本机专属标识。公开告警中的仓库名、镜像名和威胁特征予以保留,以便安全排查。
重要边界: 告警内容中的后门行为应视为待核验威胁情报。文档会区分告警指称、源码审查结果和本机检查结果,不因单一 IOC 命中或未命中直接判定感染或安全。
第一部分:危险项目信息与后门 IOC
1. 风险摘要
告警描述了一起 ARTEX 二开仓库的 Docker 镜像供应链投毒事件:
- 二开仓库据称只修改
docker-compose.yml中的 ARTEX 镜像地址。 - 源码可能与正常项目相似,但运行时拉取的预编译镜像来自另一个 Docker
Hub 命名空间。 - 被报告的恶意逻辑位于登录接口处理路径,而不是必须能从公开源码中直接发现。
- 后门被指称可在认证前执行系统命令,并将执行结果返回给请求方。
安全原则:源码干净不等于镜像可信。 必须核对仓库 remote、Compose
实际镜像、镜像 digest、二进制哈希和构建来源。
2. 需要重点关注的项目和镜像
类型 名称 / 特征 处理建议
被告警指称的二开仓库 trhhubsd/ARTEX 暂停使用;核对仓库和提交历史
告警提及的可疑提交 a4f4d38 对比该提交的 Compose 镜像地址变更
被告警指称的镜像 tomicdd/artex 不要拉取或运行;排查本机镜像、容器和历史
告警中原始镜像写法 autumn27/artex:${ARTEX_TAG:-latest} 仅作为告警所述对照,不代表当前可直接信任或仍可用
告警中被替换的镜像写法 tomicdd/artex:${ARTEX_TAG:-latest} 高风险 IOC
告警提到该恶意镜像拉取量接近 7,954 次、相关仓库约 1.3k
Star。这些数字属于告警中的统计说法,具有时间性,本文不将其作为独立核实的当前数据。
3. 被报告的后门行为
被报告的入口:
POST /api/auth/login
被报告的逻辑特征:
- 登录 JSON 请求中额外读取
captcha/Captcha字段。 - 字段内容若以
!开头,则去掉!。 - 将剩余内容交给 Shell(告警描述为
sh -c)执行。 - 执行发生在正常用户名、密码认证之前。
- 命令输出通过 HTTP 响应返回。
- 命令在容器内以 root
身份执行(这是告警所述影响,不代表所有部署都必然具有相同容器权限)。
告警提供的特征字符串:
captcha
Captcha
verifyCaptcha
/api/auth/login
sh -c
不要对公网目标发送利用请求。
这些字符串用于源码审查、日志排查和本地隔离取证。
4. IOC:摘要和哈希
告警原文提供的镜像 digest 只有缩写形式:
sha256:ce85d836...392745e
这是不完整摘要,不能直接作为精确 digest
比对值。需要从原始威胁情报、镜像仓库取证记录或可信扫描报告获取完整 64
位十六进制摘要后再做精确匹配。
不要把未经原始来源确认的补全哈希当成 IOC。精确比对时必须使用完整
digest。
5. 如何识别危险配置
危险配置示例:
services:
artex:
image: tomicdd/artex:${ARTEX_TAG:-latest}
本地构建部署的预期配置(本机项目当前采用的方式):
services:
artex:
image: artex:local
检查 Compose 实际使用的镜像:
docker compose config --images
检查仓库 remote:
git remote -v
6. 当前项目来源说明
本机此前 git remote -v 记录为:
https://github.com/Hinln/ARTEX.git
这是本机当前克隆项目的来源记录,不应仅凭仓库名称推断它是原作者唯一官方维护仓库。使用前仍需核对仓库说明、提交历史、上游来源和许可证。
7. 参考来源与证据等级
- 用户提供的安全告警文本:提供
trhhubsd/ARTEX、提交
a4f4d38、tomicdd/artex、登录验证码字段和命令执行行为等线索。 - Hinln/ARTEX GitHub 仓库:本机当前
Git remote 对应仓库。 - The Hacker News
报道:公开报道的安全事件线索。 - The Hum
独立核查文章:对后门指控证据状态提出保留意见。
结论边界: 将 tomicdd/artex 等作为高优先级 IOC
排查;只有在获得镜像、二进制或行为证据后,才能对具体主机是否感染下结论。
第二部分:本机安全排查命令
0. 设置项目路径
$ProjectRoot = "D:\Path\To\ARTEX" # 改为本机 ARTEX 项目目录
Set-Location $ProjectRoot
排查期间优先使用只读命令。取证完成前不要删除容器、镜像、数据卷或日志。
1. 核对 Git 来源和工作区
git remote -v
git rev-parse HEAD
git status --short
git log -5 --oneline --decorate
检查: - remote 是否为自己预期的仓库。 -
是否存在不认识的提交、脚本或工作区修改。 - 是否有人修改过
docker-compose.yml 中的镜像命名空间。
2. 检查镜像和容器
docker images --digests --no-trunc |
Select-String -Pattern "artex|tomicdd|autumn27|trhhubsd"
docker ps -a --no-trunc |
Select-String -Pattern "artex|tomicdd|autumn27|trhhubsd"
docker ps -a --no-trunc --filter ancestor=tomicdd/artex
检查 Compose 实际镜像:
docker compose config --images
docker compose ps
检查镜像元数据:
docker image inspect artex:local --format `
'ID={{.Id}}
RepoTags={{json .RepoTags}}
RepoDigests={{json .RepoDigests}}
Created={{.Created}}'
注意:当前镜像清单没有命中,只能说明目前仍保留的镜像中未发现;不能证明历史上从未拉取或运行过恶意镜像。
3. 检查 Compose 是否引用危险镜像或开放端口
Select-String -Path .\docker-compose.yml `
-Pattern 'image:|build:|privileged:|docker.sock|network_mode:|8787|8788'
docker compose config --images
重点检查: - ARTEX 是否使用经过审计的本地镜像 artex:local。 - 是否出现
tomicdd/artex 等未知镜像命名空间。 - 是否启用 privileged: true。 -
是否挂载 Docker Socket。 - Web/API 端口是否只绑定 127.0.0.1。
4. 检查登录后门字符串
Select-String -Path .\server\auth.go `
-Pattern 'func .*authLogin|captcha|verifyCaptcha|exec.Command|CommandContext' `
-Context 8,18
git grep -n -i -E `
'verifyCaptcha|captcha|exec\.Command|os/exec|/bin/sh|sh -c' `
-- '*.go'
重点审查: - 登录请求结构体是否出现 captcha / Captcha。 - 是否出现
verifyCaptcha。 - 是否在密码校验前执行系统命令。 - 是否将 HTTP
请求参数拼接到 Shell 命令。 - 是否把命令输出返回给未认证请求者。
说明:exec.CommandContext
本身不等于后门;需要结合调用链、输入来源、授权检查和执行权限判断。
5. 审查自定义工具执行逻辑
Select-String -Path .\server\customtool.go `
-Pattern 'exec.CommandContext|CommandContext|interp|tmp' `
-Context 12,20
Get-Content .\server\customtool.go |
Select-Object -Skip 330 -First 110
重点检查命令白名单、人工审批、执行超时、工作目录限制、临时脚本权限和参数注入风险。
6. 审查自动更新逻辑
Get-Content .\selfupdate\bootstrap.go |
Select-Object -First 240
Get-ChildItem .\selfupdate -Recurse -File |
Select-String -Pattern 'http|https|Download|WriteFile|Rename|exec.Command|github'
检查下载来源、TLS、签名或哈希校验、文件替换和回滚逻辑。不要只审
start.sh:启动脚本负责启动和重启,更新逻辑在 Go 程序中。
7. 检查容器权限、挂载和运行身份
docker inspect artex-artex-1 --format `
'Privileged={{.HostConfig.Privileged}}
ReadonlyRootfs={{.HostConfig.ReadonlyRootfs}}
CapAdd={{json .HostConfig.CapAdd}}
CapDrop={{json .HostConfig.CapDrop}}
SecurityOpt={{json .HostConfig.SecurityOpt}}
NetworkMode={{.HostConfig.NetworkMode}}
PidMode={{.HostConfig.PidMode}}
Mounts={{json .Mounts}}'
docker exec artex-artex-1 id
docker inspect artex-artex-1 --format '{{json .Mounts}}'
检查容器是否以 root 运行、是否有额外
capabilities、是否挂载宿主机敏感目录或 Docker Socket。
8. 比较容器二进制与本地构建产物
docker exec artex-artex-1 sh -c 'sha256sum /app/artex'
docker cp artex-artex-1:/app/artex .\artex-container-copy
Get-FileHash .\artex-container-copy -Algorithm SHA256
Get-FileHash .\dist\amd64\artex -Algorithm SHA256
容器文件和本地构建产物 SHA-256
一致,才能证明二者字节一致。哈希不同需要调查构建产物、容器创建时间和镜像来源。
9. 检查运行日志
docker compose logs --tail 200 artex
docker compose logs --tail 200 postgres
检查异常登录、未知下载地址、意外进程启动、异常重启和不认识的更新记录。
10. 检查 PowerShell 历史中的可疑镜像命令
$history = "$env:APPDATA\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt"
if (Test-Path $history) {
Select-String -Path $history -Pattern `
'tomicdd/artex|trhhubsd/ARTEX|docker pull .*artex|docker compose'
}
历史记录可能不完整或已被清理;无命中不能证明从未执行。
11. 检查 Windows 持久化线索(只读初筛)
Get-ScheduledTask |
Select-Object TaskName, TaskPath, State
Get-CimInstance Win32_Process |
Select-Object ProcessId, ParentProcessId, Name, ExecutablePath
$sshKeys = "$env:USERPROFILE\.ssh\authorized_keys"
if (Test-Path $sshKeys) {
Get-Item $sshKeys | Select-Object FullName, Length, LastWriteTime
}
不要仅凭进程名或计划任务名称判定恶意;需要结合路径、签名、创建时间和行为分析。
12. 排查后处置原则
若发现可疑镜像或容器: 1. 先记录镜像 ID、RepoDigest、容器
inspect、创建时间、日志和挂载信息。 2.
保存必要证据后,停止可疑容器并隔离网络。 3.
不要直接删除数据卷;先评估是否含有证据、凭据或业务数据。 4.
从已核验源码重新构建镜像。 5. 轮换可能暴露的 API Key、GitHub
Token、数据库密码和其他凭据。 6. 检查宿主机持久化和外联行为。
本文件是排查清单,不是感染判定器。没有命中 IOC 不代表绝对安全。
第三部分:ARTEX 项目搭建与本地构建
1. 环境准备
需要: - Windows 11 - Docker Desktop(Linux containers / WSL2
backend) - Git - Node.js 与 npm - Go 工具链 - PowerShell
检查版本:
git --version
node -v
npm -v
go version
docker version
docker compose version
2. 获取源码
新机器克隆:
$ProjectRoot = "D:\Path\To\ARTEX" # 改成希望放置项目的路径
git clone https://github.com/Hinln/ARTEX.git $ProjectRoot
Set-Location $ProjectRoot
已有项目不要重复 clone;先核对:
git remote -v
git rev-parse HEAD
git status --short
保留本地修改。不要盲目执行 git reset --hard 或 git clean -fd。
3. 安装前端依赖
Set-Location "$ProjectRoot\web"
npm ci
npm ci 使用 package-lock.json 安装锁定版本依赖。
4. 构建静态前端
项目静态构建脚本使用 POSIX 环境变量写法。PowerShell 下使用:
$env:NEXT_EXPORT = "1"
npx next build
$buildCode = $LASTEXITCODE
Remove-Item Env:NEXT_EXPORT -ErrorAction SilentlyContinue
if ($buildCode -ne 0) {
throw "Next.js 静态构建失败,停止后续步骤"
}
Test-Path .\out
预期生成 web\out。
5. 复制前端文件到 Go embed 目录
Set-Location $ProjectRoot
if (Test-Path .\server\webui\dist) {
Remove-Item .\server\webui\dist -Recurse -Force
}
New-Item -ItemType Directory .\server\webui\dist -Force |
Out-Null
Copy-Item .\web\out\* .\server\webui\dist\ -Recurse -Force
Test-Path .\server\webui\dist\index.html
6. 下载并验证 Go 依赖
Set-Location $ProjectRoot
go mod download
go mod verify
只有 go mod verify 成功,才能说明本地模块缓存与 Go module
校验信息一致;它不是完整的源码安全审计。
7. 编译 Linux/amd64 二进制
Windows 默认编译结果不能直接运行在 Linux 容器中,需要交叉编译:
Set-Location $ProjectRoot
New-Item -ItemType Directory .\dist\amd64 -Force |
Out-Null
$env:GOOS = "linux"
$env:GOARCH = "amd64"
$env:CGO_ENABLED = "0"
go build -tags embedui -o .\dist\amd64\artex .\cmd\artex
$buildCode = $LASTEXITCODE
Remove-Item Env:GOOS -ErrorAction SilentlyContinue
Remove-Item Env:GOARCH -ErrorAction SilentlyContinue
Remove-Item Env:CGO_ENABLED -ErrorAction SilentlyContinue
if ($buildCode -ne 0) {
throw "Go Linux/amd64 编译失败"
}
检查 ELF 文件头:
$bytes = [System.IO.File]::ReadAllBytes(
(Resolve-Path .\dist\amd64\artex)
)
[BitConverter]::ToString($bytes, 0, 4)
预期:
7F-45-4C-46
记录构建信息和哈希:
go version -m .\dist\amd64\artex
Get-FileHash .\dist\amd64\artex -Algorithm SHA256
8. 检查 Dockerfile
Dockerfile 应将预编译的 Linux 二进制复制到运行镜像,例如:
ARG TARGETARCH
COPY dist/${TARGETARCH}/artex /app/artex
如需让构建阶段使用代理,Dockerfile 应在相应 RUN
指令前声明代理构建参数:
ARG HTTP_PROXY
ARG HTTPS_PROXY
ARG http_proxy
ARG https_proxy
APT 网络不稳定时,可把 Debian 源改为 HTTPS,并在 apt-get update 使用:
-o Acquire::http::Pipeline-Depth=0
-o Acquire::https::Pipeline-Depth=0
-o Acquire::ForceIPv4=true
Dockerfile 多行 RUN 命令的 \ 必须放在续行行尾,不要单独放一行。
9. 构建本地镜像
如果 HTTP 代理监听 Windows 的 127.0.0.1:8080,Docker
容器访问宿主机代理应使用 host.docker.internal:8080。
通过代理构建:
Set-Location $ProjectRoot
docker buildx build --load --platform linux/amd64 `
--build-arg TARGETARCH=amd64 `
--build-arg HTTP_PROXY=http://host.docker.internal:7890 `
--build-arg HTTPS_PROXY=http://host.docker.internal:7890 `
--build-arg http_proxy=http://host.docker.internal:7890 `
--build-arg https_proxy=http://host.docker.internal:7890 `
-t artex:local .
不使用代理:
docker buildx build --load --platform linux/amd64 `
--build-arg TARGETARCH=amd64 `
-t artex:local .
确认镜像:
docker image inspect artex:local --format 'ID={{.Id}} Created={{.Created}}'
docker image ls artex
10. 配置 Compose 和环境文件
Compose 的 ARTEX 服务应使用本地镜像:
artex:
image: artex:local
端口建议仅绑定本机:
ports:
- "127.0.0.1:8787:8787"
- "127.0.0.1:8788:8788"
如果没有 .env,可以从模板创建:
Set-Location $ProjectRoot
if (-not (Test-Path .\.env)) {
Copy-Item .\.env.example .\.env
}
编辑 .env,设置强随机 POSTGRES_PASSWORD,按需设置模型服务 API
Key。不要把 .env 内容贴到公开聊天、提交到 Git 或写进报告。
验证 Compose:
docker compose config --quiet
if ($LASTEXITCODE -ne 0) {
throw "Compose 配置无效"
}
11. 启动和验证
docker compose up -d --no-build
docker compose ps
docker compose logs --tail 100 artex
curl.exe --noproxy "*" -I http://127.0.0.1:8787
浏览器访问:
http://127.0.0.1:8787
12. 重要说明
- 当前 Compose 若只有
image: artex:local、没有build:,则
docker compose build不会替你构建该镜像;使用上面的
docker buildx build。 --build-arg主要影响 DockerfileRUN构建阶段;不保证解决 Docker
Hub 拉取基础镜像、Dockerfile frontend 或 Registry token 的问题。# syntax=docker/dockerfile:1可能触发 BuildKit 拉取 Dockerfile
frontend。若网络无法访问 Docker Hub,先备份
Dockerfile,再考虑移除该行并使用 BuildKit 内置 frontend;需确认
Dockerfile 语法兼容。- 构建成功不代表源码安全。构建前应完成危险字符串、更新机制、自定义命令执行和依赖审查。
第四部分:本地镜像拉取、保存、加载与启动
1. 先区分三种情况
场景 正确方式
本机已经构建 artex:local docker image ls 检查,不需要 pull
本机没有镜像,但有源码 按本地构建执行
docker buildx build --load
另一台电脑需要使用已构建镜像 在原机器 docker save,在新机器
docker load
需要 PostgreSQL 基础镜像 docker pull postgres:16-alpine
不要执行 docker pull artex:local 来获取本地构建镜像。
artex:local 不是公共 Registry 地址;Docker 会尝试从默认 Registry
查找它,通常会失败。
2. 检查本机是否已有 ARTEX 镜像
docker image ls artex
docker image inspect artex:local
如果镜像存在,可直接启动:
Set-Location "D:\Path\To\ARTEX" # 改成实际项目目录
docker compose up -d --no-build
docker compose ps
3. 拉取 PostgreSQL 基础镜像
当前 Compose 使用:
postgres:
image: postgres:16-alpine
拉取命令:
docker pull postgres:16-alpine
docker image inspect postgres:16-alpine
注意:标签可能随上游更新而变化。长期或生产环境应核对并固定经过验证的
digest。
4. 将本机 ARTEX 镜像导出成文件
在已经有 artex:local 的电脑上:
docker image inspect artex:local
docker save -o .\artex-local.tar artex:local
Get-FileHash .\artex-local.tar -Algorithm SHA256
将 artex-local.tar
通过可信介质传到另一台电脑。不要把镜像文件上传到公开网盘或公开仓库,因为镜像可能包含内部配置、工具和代码。
5. 在另一台电脑导入镜像
docker load -i .\artex-local.tar
docker image ls artex
docker image inspect artex:local
如果 Compose 项目也在新电脑上,进入项目目录并启动:
Set-Location "D:\Path\To\ARTEX"
docker compose config --quiet
docker compose up -d --no-build
docker compose ps
确保新电脑上已经准备好正确的 .env,不要复制或公开含真实密钥的文件。
6. 如果需要从私有 Registry 拉取
只有当团队已经把镜像推送到自己控制、经过审计的 Registry 时,才使用:
docker login <可信Registry域名>
docker pull <可信Registry域名>/<项目镜像>:<固定版本标签>
docker image inspect <可信Registry域名>/<项目镜像>:<固定版本标签>
更推荐固定 digest:
docker pull <可信Registry域名>/<项目镜像>@sha256:<完整且已核验的digest>
以上是模板命令,尖括号内容必须替换为实际可信 Registry 和完整
digest;不要把占位符原样执行。
7. 不要拉取的可疑镜像
根据收到的安全告警,排查时重点关注:
tomicdd/artex
不要为了"验证是否有毒"而在日常工作环境中拉取或运行可疑镜像。若必须取证,应在隔离实验环境中由安全人员按证据保全流程处理。
8. 常用启动与维护命令
启动:
docker compose up -d --no-build
状态:
docker compose ps
docker image ls artex
日志:
docker compose logs --tail 100 artex
停止:
docker compose stop
移除容器但保留默认命名数据卷:
docker compose down
不要随意使用 docker compose down -v,它会删除 Compose
管理的数据卷,可能造成 PostgreSQL 数据丢失。

浙公网安备 33010602011771号