
Apache Traffic Server 10.2.0 - Alta - Remoto - Resíduo de privilégios - ip_allow method case
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · ats-ipallow-method-case
Classe: Privilégio residual Alcance: Remoto
Apache Traffic Server 10.2.0 (b1df7334) - Apache Software Foundation
Métodos HTTP/1 com capitalização mista ignoram a negação padrão do ip_allow.yaml de PURGE/PUSH/DELETE/TRACE e o TUNNEL para a origem remapeada como o uid do ATS. O parse de YAML e do @method no remap é nocase. O H1 tokeniza e depois faz strncmp dos bytes da requisição e retorna -1 em caso de divergência de capitalização. A inversão da negação trata esse token desconhecido como permitido. O :method do HTTP/2 é nocase e permanece negado. PURGE/PUSH de cache ainda exigem um wksidx bem conhecido, então a capitalização mista não purga nem faz push do cache.
Este é um resíduo da ACL padrão de métodos de entrada, não é o CVE-2026-33267 (hop-by-hop) e não é a ACL de remap invertida de vazio-não-padrão (fechada neste pin).
| ID | ainda sem CVE |
| Classe | Privilégio residual |
| Alcance | Remoto (HTTP/1 não autenticado de um cliente não-loopback) |
| CWE | CWE-178, CWE-863 |
| CVSS | Alto: 7.5 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N |
| Produto | Apache Traffic Server |
| Afetado | 10.2.0 (b1df7334b39a878971c376da849e8da4984918b6) proxy reverso padrão |
| Autenticação | nenhuma. ip_allow.yaml padrão. remap_required: 1 mais um map. |
| Licença | GNU Affero GPL v3.0 |
| Lab | apenas 127.0.0.1:18710. Imagem ats-10.2.0-lab:local. |
Fixe a tag 10.2.0, commit b1df7334b39a878971c376da849e8da4984918b6. Última Stable em 17 de ago. de 2026. Imagem compilada a partir do código-fonte, não é um gadget.
Alcançar um proxy reverso típico (remap_required: 1 mais um map) via HTTP/1 a partir de um endereço não-loopback. 127.0.0.1 é allow ALL. plugin.config vazio. ip_allow.yaml padrão.
| Método | Destino | Privilégio |
|---|---|---|
HTTP/1 delete / DeLeTe após remap a partir de um sidecar 172.x | hdrtoken_method_tokenize e depois process_quick_http_filter e depois TUNNEL METHOD_NOT_SUPPORTED (HdrToken.cc:512-528, HttpTransact.cc:6855-6858) | Integridade (comprovada em lab): origem 200 DELETED ATS-IPALLOW-METHOD-CASE-WITNESS. DELETE em maiúsculas é 403. Método na origem como o uid do ATS. |
HTTP/1 trace | mesmo TUNNEL | Reconhecimento (comprovado em lab): origem 200 TRACE-OK. O ATS não constrói o eco TRACE (wksidx não é TRACE). TRACE em maiúsculas é 403. |
HTTP/1 purge / push | TUNNEL de método desconhecido, não operação de cache | Integridade (cache do ATS): fechado (comprovado em lab). A origem viu PURGE-ORIGIN / PUSH-ORIGIN. Operações de cache exigem wksidx bem conhecido. push_method_enabled padrão 0. |
| Mesma requisição com capitalização mista | um hop extra até a origem | Disponibilidade (comprovada em lab): não é morte do processo. |
Comprovado em lab vs inferido: negação em maiúsculas, TUNNEL de DELETE/TRACE com capitalização mista, PURGE/PUSH de cache fechados: lab. DELETE/TRACE na origem apenas se essa origem normaliza a capitalização do método (IIS / alguns Java). Origens sensíveis a capitalização conforme RFC 9110 (nginx, httpd, Go) respondem 501. A origem do lab normaliza a capitalização.
Requer: HTTP/1 de um cliente não-loopback. remap_required: 1 mais um map. Negação padrão de entrada para PURGE/PUSH/DELETE/TRACE. :method HTTP/2 sem distinção de maiúsculas/minúsculas ainda negado.
| Superfície | Laboratório |
|---|---|
DELETE / TRACE com caixa exata de 172.x | 403, origem não atingida |
:method HTTP/2 com caixa mista | tokenização sem distinção de maiúsculas/minúsculas, ainda negado |
purge / push com caixa mista como operações de cache ATS | origem viu o verbo; caminho de cache permaneceu fechado |
Negação de destino CONNECT (0.0.0.0/8, RFC1918, link-local, ::ffff:0:0/96) | ip_allow.yaml de saída padrão |
Falha de remap_required: 1 | 404, não um relay aberto |
| ACL de remap vazia-não-padrão invertida | correção do CHANGELOG mantida |
CVE-2026-33267 hop-by-hop / remoção de @ | fechado neste pin |
O ip_allow.yaml padrão é a ACL de métodos remotos de fábrica. O carregamento YAML usa hdrtoken_tokenize (sem distinção de maiúsculas/minúsculas). A inversão de DENY então define _method_mask = ALL & ~listed e _deny_nonstandard_methods = true com uma lista não-padrão vazia (IPAllow.cc:545-548).
A análise HTTP/1 tokeniza com hdrtoken_method_tokenize. O DFA não diferencia maiúsculas de minúsculas; o helper então faz strncmp dos bytes da requisição contra a string conhecida e retorna -1 em caso de divergência de caixa:
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 pergunta a isNonstandardMethodAllowed para method == -1 (IPAllow.h:365-376). Conjunto não padrão vazio mais negação de não padrão é !method_in_set, então maiúsculas e minúsculas misturadas são permitidas. is_this_http_method_supported(-1) é falso. METHOD_NOT_SUPPORTED define ProxyMode_t::TUNNELLING e retorna verdadeiro. A documentação diz que o ATS encaminha métodos desconhecidos para a origem. A consulta ao cache é ignorada em TUNNELLING.
O :method do HTTP/2 passa por HTTPHdr::method_set -> hdrtoken_tokenize sem verificação de maiúsculas e minúsculas. O delete do H2 torna-se DELETE e é negado. Esse resíduo é HTTP/1.
Caminhos errados: tratar origens sensíveis a maiúsculas e minúsculas da RFC 9110 como algo que torna a lista de negação inócua (PURGE/PUSH do cache do ATS permanecem fechados; DELETE/TRACE da origem é o resíduo); fazer curl a partir de 127.0.0.1 (permitir ALL); alegar purga de cache; registrar novamente como hop-by-hop.
Teatro: um reverse shell. O oráculo é uma string testemunha na origem após 403 em maiúsculas.
python3 ats-ipallow-method-case-Abraxas-Labs.py
ou
cd lab
./run.sh