abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · ats-esi-unix-recvport
类别: SSRF 可达性: 远程
Apache Traffic Server 10.2.0 (b1df7334) - Apache Software Foundation
ESI FetchSM PluginVC 报告目标端口为 0。Remap 将端口 0 视为 UDS,并将 include 的 scheme 重写为 http+unix,从而使其匹配本应仅用于 UDS 监听器的 map_with_recv_port http+unix:// 规则。于是,一个看似公开的 esi:include(指向 http://www.example.com/secret)会命中 unix-socket 源站。TCP 的 GET /secret 仍走 TCP 映射。不带 unix recv-port 映射的 CONTROL 会内联 TCP 源站内容(无见证)。在 2026 年 7 月的校验器中,include scheme http+unix 本身即为 BAD_SCHEME。
典型的 esi.so 加一条 map 不会触发此问题。需要 ESI 以及至少一行 map_with_recv_port http+unix://。默认 remap_required: 1 和 number_of_redirections: 0。
这不是 CVE-2026-58178(私有字面量、file://、嵌套注释、深度上限均已关闭)。
| ID | 暂无 CVE |
| 类别 | SSRF |
| 可达性 | 远程(未经认证的 HTTP 请求发往 ESI 虚拟主机) |
| 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) ESI 加 map_with_recv_port http+unix |
| 认证 | 无。ESI 插件。Recv-port unix 映射。 |
| 许可证 | GNU Affero GPL v3.0 |
| 实验环境 | 仅 127.0.0.1:18750 / 18751。镜像 ats-10.2.0-lab:local。 |
我固定了标签 10.2.0,提交 b1df7334b39a878971c376da849e8da4984918b6。源码构建镜像。
未经认证的 HTTP 请求发往一个 ESI 虚拟主机,其 remap 中包含 map_with_recv_port http+unix://。include 的 src 可被攻击者影响(被攻陷的源站、存储型 ESI,或 $(HTTP_HEADER{...}))。
| 方法 | 汇聚点 | 权限 |
|---|---|---|
未经认证的 GET /page ESI include http://www.example.com/secret | FetchSM 目标端口 0 匹配 map_with_recv_port http+unix://www.example.com/(RemapProcessor.cc:87-114,PluginVC.h:274-278) | 侦察 / SSRF(实验环境已证实): 客户端响应体内联了来自 UDS 源站的 ATS-ESI-UNIX-RECVPORT-WITNESS。 |
| 同上 | 一阶写入 / shell | 完整性:无。 无一阶写入。无 shell。 |
CONTROL GET /page 不带 unix recv-port 映射 | TCP 源站 include | 已关闭(实验环境已证实): 内联 TCP-ORIGIN-OK,无见证。 |
TCP 客户端在 poc 虚拟主机上 GET /secret | TCP 映射 | 已关闭(实验环境已证实): TCP-ORIGIN-OK,无见证。 |
实验环境已证实 vs 推断: 对照无见证、poc 页面有见证、poc TCP /secret 无见证:均为实验环境。通过存储型 ESI 或头部展开影响 src 属于已记录的 ESI 信任模型,此处未重新证实。实验环境中的 include 是 /page 上的静态 http://www.example.com/secret。
需要: ESI 插件加 map_with_recv_port http+unix。默认 remap_required: 1。number_of_redirections: 0。
| 表面 | 实验 |
|---|---|
| 无 unix recv-port 映射的 CONTROL | control-no-witness=yes,内联 TCP-ORIGIN-OK |
TCP 客户端 GET /secret | poc-tcp-secret-no-witness=yes |
包含 scheme http+unix | 校验器 BAD_SCHEME |
file://、私有字面量、嵌套注释、深度上限 | CVE-2026-58178 已关闭 |
| 无 DNS 的主机名拒绝列表 | 已记录;在 remap_required: 1 下失效 |
remap_required: 1 未命中 | 404 |
number_of_redirections: 0 | 关闭 Location 跟随 |
PluginVCCore 将 passive_addr_struct 清零。PluginHttpConnectInternal 仅设置 active_addr(原始客户端)。FetchSM 的 HttpSM 运行在被动 PluginVC 上。attach_client_session 将 netvc->get_local_addr() 复制到 client_info.dst_addr。被动本地地址是清零的结构体。host_order_port() 为 0。
重映射查找(RemapProcessor.cc:87-114):端口 0 表示 UDS。Scheme 被重写为 http -> http+unix,因此 map_with_recv_port http+unix:// 会匹配。单元测试 test_RemapRules.cc:237-240 记录了这一点。
七月的校验器拒绝包含 scheme http+unix。它不会拒绝一个 http:// 包含,其内部重映射跳转因目标端口为 0 而变为 unix。
错误方向:将典型的 esi.so + 单个 map 视为这一遗留问题(CONTROL 证明并非如此);提交无 DNS 的主机名拒绝列表(已记录,在 remap_required=1 下失效);声称 file:// 仍然有效;期望 TCP /secret 遵循 unix 映射。
表演:一个反向 shell。预言机是来自 UDS 源的内联见证,TCP /secret 仍然是 TCP。
python3 ats-esi-unix-recvport-Abraxas-Labs.py
或
cd lab
./run.sh
Loopback poc 127.0.0.1:18750,control 127.0.0.1:18751。Compose 项目 ats-esi-unix-recvport。镜像 ats-10.2.0-lab:local。Witness ATS-ESI-UNIX-RECVPORT-WITNESS。最后一行:
SUCCESS ats-esi-unix-recvport control-no-witness=yes poc-page-witness=yes poc-tcp-secret-no-witness=yes ATS-ESI-UNIX-RECVPORT-WITNESS
不要将 FetchSM PluginVC 的目标端口 0 视为 UDS 接收端口匹配。对于真正的 UDS 监听器,保留 map_with_recv_port http+unix://。即使该主机存在 http+unix 接收端口规则,对 http://host/ 的 ESI 包含也应保持在 TCP 映射上。
b1df7334b39a878971c376da849e8da4984918b6)PluginVC.h 被动地址被清零PluginHttpConnect.ccRemapProcessor.cc 端口 0 -> http+unixtest_RemapRules.cc