abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · ats-ipallow-method-case
类别: 权限残留 可达性: 远程
Apache Traffic Server 10.2.0 (b1df7334) - Apache Software Foundation
HTTP/1 混合大小写方法会绕过默认 ip_allow.yaml 对 PURGE/PUSH/DELETE/TRACE 的拒绝,并以 ATS uid 身份 TUNNEL 到重映射的源站。YAML 与 remap @method 的解析均不区分大小写。H1 先分词,再对请求字节执行 strncmp,大小写不匹配时返回 -1。拒绝逻辑反转后,该未知 token 被视为允许。HTTP/2 的 :method 不区分大小写,仍被拒绝。缓存 PURGE/PUSH 仍需已知的 wksidx,因此混合大小写不会清除或推送缓存。
这是默认入站方法 ACL 的残留问题,不是 CVE-2026-33267(逐跳),也不是反转的空非标准 remap ACL(在此固定版本上已关闭)。
| ID | 暂无 CVE |
| 类别 | 权限残留 |
| 可达性 | 远程(来自非回环客户端的未认证 HTTP/1) |
| CWE | CWE-178, CWE-863 |
| CVSS | 高危:7.5 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N |
| 产品 | Apache Traffic Server |
| 受影响 | 10.2.0 (b1df7334b39a878971c376da849e8da4984918b6) 默认反向代理 |
| 认证 | 无。默认 ip_allow.yaml。remap_required: 1 加一条 map。 |
| 许可证 | GNU Affero GPL v3.0 |
| 实验环境 | 仅 127.0.0.1:18710。镜像 ats-10.2.0-lab:local。 |
我固定了标签 10.2.0,提交 b1df7334b39a878971c376da849e8da4984918b6。最新稳定版 2026 年 8 月 17 日。源码构建镜像,非 gadget。
从非回环地址通过 HTTP/1 访问典型反向代理(remap_required: 1 加一条 map)。127.0.0.1 为全部允许。plugin.config 为空。默认 ip_allow.yaml。
| 方法 | 汇聚点 | 权限 |
|---|---|---|
来自 172.x sidecar 的 HTTP/1 delete / DeLeTe,经重映射后 | hdrtoken_method_tokenize 然后 process_quick_http_filter 然后 METHOD_NOT_SUPPORTED TUNNEL(HdrToken.cc:512-528,HttpTransact.cc:6855-6858) | 完整性(实验证明): 源站返回 200 DELETED ATS-IPALLOW-METHOD-CASE-WITNESS。大写 DELETE 返回 403。源站方法以 ATS uid 身份执行。 |
HTTP/1 trace | 同一 TUNNEL | 侦察(实验证明): 源站返回 200 TRACE-OK。ATS 不构建 TRACE 回显(wksidx 不是 TRACE)。大写 TRACE 返回 403。 |
HTTP/1 purge / push | 未知方法 TUNNEL,非缓存操作 | 完整性(ATS 缓存):已关闭(实验证明)。 源站看到 PURGE-ORIGIN / PUSH-ORIGIN。缓存操作需要已知 wksidx。push_method_enabled 默认为 0。 |
| 同一混合大小写请求 | 额外一次源站跳转 | 可用性(实验证明): 并非进程死亡。 |
实验证明 vs 推断: 大写拒绝、混合大小写 DELETE/TRACE 隧道、缓存 PURGE/PUSH 关闭:均为实验证明。源站 DELETE/TRACE 仅在该源站折叠方法大小写时成立(IIS / 部分 Java)。RFC 9110 大小写敏感的源站(nginx、httpd、Go)返回 501。实验源站折叠大小写。
要求: 来自非回环客户端的 HTTP/1。remap_required: 1 加一个 map。默认入站拒绝 PURGE/PUSH/DELETE/TRACE。HTTP/2 :method 不区分大小写仍被拒绝。
| 攻击面 | 实验环境 |
|---|---|
来自 172.x 的精确大小写 DELETE / TRACE | 403,源站未被命中 |
HTTP/2 :method 混合大小写 | 不区分大小写分词,仍被拒绝 |
混合大小写 purge / push 作为 ATS 缓存操作 | 源站看到了该动词;缓存路径保持关闭 |
CONNECT 目标拒绝(0.0.0.0/8、RFC1918、链路本地、::ffff:0:0/96) | 默认 ip_allow.yaml 出站 |
remap_required: 1 未命中 | 404,而非开放中继 |
| 反转的空非标准 remap ACL | CHANGELOG 修复仍然有效 |
CVE-2026-33267 逐跳 / @ 剥离 | 在此固定版本上已关闭 |
默认 ip_allow.yaml 是原版远程方法 ACL。YAML 加载使用 hdrtoken_tokenize(不区分大小写)。DENY 反转随后设置 _method_mask = ALL & ~listed 和 _deny_nonstandard_methods = true,且非标准列表为空(IPAllow.cc:545-548)。
HTTP/1 解析使用 hdrtoken_method_tokenize 进行分词。DFA 不区分大小写;随后该辅助函数将请求字节与已知字符串进行 strncmp 比较,并在大小写不匹配时返回 -1:
retval = hdrtoken_tokenize(string, string_len, &string_out);
if (retval >= 0) {
if (strncmp(string, string_out, string_len) != 0) {
// Not a case match
retval = -1;
}
}
EndRemapRequest 会针对 method == -1 调用 isNonstandardMethodAllowed(IPAllow.h:365-376)。非标准方法集合为空且启用了拒绝非标准方法时,结果为 !method_in_set,因此大小写混合的方法会被允许。is_this_http_method_supported(-1) 返回 false。METHOD_NOT_SUPPORTED 会设置 ProxyMode_t::TUNNELLING 并返回 true。文档说明 ATS 会将未知方法转发到源站。在 TUNNELLING 模式下会跳过缓存查找。
HTTP/2 的 :method 会经过 HTTPHdr::method_set -> hdrtoken_tokenize,且没有大小写检查。H2 的 delete 会变成 DELETE 并被拒绝。这个遗留问题属于 HTTP/1。
错误方向:把 RFC 9110 大小写敏感的源站视为使拒绝列表失效(ATS 缓存的 PURGE/PUSH 仍然关闭;源站的 DELETE/TRACE 才是遗留问题);从 127.0.0.1 发起 curl 请求(允许 ALL);声称存在缓存清除;重新提交逐跳问题。
演示效果:一个反向 shell。判定依据是源站在收到大写方法返回 403 后出现的见证字符串。
python3 ats-ipallow-method-case-Abraxas-Labs.py
或
cd lab
./run.sh
Loopback 127.0.0.1:18710。Compose 项目 ats-ipallow-method-case。镜像 ats-10.2.0-lab:local(10.2.0 的源码构建)。攻击者 sidecar 位于 172.x,因此 localhost ALL 不会掩盖拒绝结果。Origin 折叠方法大小写。见证 ATS-IPALLOW-METHOD-CASE-WITNESS。最后一行:
SUCCESS ats-ipallow-method-case how=live control=DELETE/TRACE-403 poc=delete/DeLeTe/trace-tunneled cache-purge-push=closed ATS-IPALLOW-METHOD-CASE-WITNESS
像 YAML 和 HTTP/2 已经做的那样,对 HTTP/1 方法进行不区分大小写的分词(nocase),或者在未知方法 TUNNEL 之前,以不区分大小写的方式匹配 ip_allow.yaml 中的拒绝名称。将缓存的 PURGE/PUSH 保留在众所周知的 wksidx 上。不要将已被拒绝的众所周知方法的大小写变体视为新方法。
b1df7334b39a878971c376da849e8da4984918b6)HdrToken.cc hdrtoken_method_tokenizeIPAllow.cc DENY 反转IPAllow.h isNonstandardMethodAllowedHttpTransact.cc METHOD_NOT_SUPPORTED TUNNELip_allow.yaml.default