WAF_EVASION_LOGS: Bypassing Enterprise Filters on High-Value Targets
WAF_EVASION_LOGS: Bypassing Enterprise Filters on High-Value Targets
[ 0x00 ] A ILUSÃO DO FILTRO PERFEITO
É comum no meio corporativo assumir que a presença de um WAF (Web Application Firewall) de classe empresarial (como Cloudflare Enterprise, Akamai Kona ou Imperva) é suficiente para imunizar aplicações web. Telas de 403 Forbidden dão a falsa sensação de barreiras intransponíveis.
No entanto, WAFs operam essencialmente como parsers de tráfego que comparam assinaturas de rede (expressões regulares) com o payload das requisições HTTP. O calcanhar de Aquiles dessa arquitetura reside na discrepância de interpretação de dados: onde há parsers encadeados e normalização de dados distinta, há brechas para desvios.
[ 0x01 ] DESSINCRONIZAÇÃO DE DECODIFICAÇÃO (DOUBLE URL ENCODING)
A técnica de Double URL Encoding explora falhas onde o WAF e o servidor backend realizam etapas assimétricas de decodificação de caracteres.
Ao enviar um payload simples como U%6eION S%45LECT (codificação URL simples), o WAF realiza a decodificação inicial, interceptando a string UNION SELECT e bloqueando a requisição. Contudo, na codificação dupla, codificamos o caractere especial de percentagem % (cujo código hexadecimal é %25), transformando o caractere n (%6e) em %256e.
- Fase 1 (WAF): O firewall recebe
U%256eION S%2545LECT. Ao aplicar uma única passagem de decodificação URL, a string é convertida paraU%6eION S%45LECT. Como o filtro do WAF procura pela assinatura exataUNION SELECT, a requisição é classificada como inofensiva e liberada. - Fase 2 (Backend): O servidor web backend recebe a requisição liberada. Antes de passá-la para as rotinas de banco de dados, o interpretador (como PHP ou ASP) realiza a decodificação secundária dos valores, transformando
U%6eION S%45LECTde volta paraUNION SELECT. A consulta maliciosa é executada.
[ 0x02 ] POLUIÇÃO DE PARÂMETROS HTTP (HPP)
A Poluição de Parâmetros HTTP ocorre ao injetar múltiplos parâmetros com a mesma chave em uma única query string HTTP (ex: ?id=1&id=UNION+SELECT...). A vulnerabilidade ocorre porque diferentes servidores e frameworks web lidam com chaves duplicadas de maneiras distintas:
| Servidor / Framework | Comportamento com Chaves Duplicadas | Resultado do Exemplo |
|---|---|---|
| ASP.NET / IIS | Concatenado com vírgula | 1,UNION SELECT... |
| PHP / Apache | Retorna apenas o último valor | UNION SELECT... |
| JSP / Tomcat | Retorna apenas o primeiro valor | 1 |
| Express.js (Node.js) | Cria um array de strings | ['1', 'UNION SELECT...'] |
Se o WAF for configurado para inspecionar apenas a primeira ocorrência do parâmetro id (visando economia de recursos), ele validará o valor seguro 1 e ignorará a ocorrência subsequente. No entanto, se o backend for estruturado sob PHP/Apache, ele processará o último valor (o payload SQLi), contornando a proteção.
[ 0x03 ] EXTRAÇÃO DE METADADOS DO LOG (ESTUDO DE CASO OPENRESTY)
Durante uma avaliação autorizada em um ativo empresarial protegido, identifiquei um WAF configurado para bloquear requisições com strings suspeitas em parâmetros comuns de requisição. A estratégia adotada consistiu em mover o payload para cabeçalhos HTTP exóticos (X-Forwarded-Host, X-Rewrite-URL, Client-IP).
Muitos gateways e proxies reversos (como Nginx e OpenResty) utilizam esses cabeçalhos para controle de rotas internas e logs. Ao enviar payloads com codificação Unicode específica e delimitadores nulos (%00) nestes cabeçalhos, causei um erro de tratamento no parser do proxy reverso.
Em vez de bloquear a conexão, o gateway mal configurado encaminhou a requisição para uma rota de erro interna que expôs o stack trace de debug do OpenResty. Isso revelou regras de roteamento internas e versões exatas de bibliotecas compartilhadas, permitindo mapear o ambiente interno sem acionar os alertas principais de intrusão do WAF.
[ 0x04 ] EVASÃO VIA TRANSFER-ENCODING: CHUNKED
Muitos filtros de WAF inspecionam apenas o cabeçalho Content-Length e o corpo da requisição POST até um limite de tamanho. Sob a especificação HTTP/1.1, podemos fragmentar a transmissão de dados utilizando o cabeçalho Transfer-Encoding: chunked.
Nesta modalidade, o corpo da requisição é enviado em blocos isolados. Cada bloco inicia com seu tamanho em formato hexadecimal, seguido de CRLF (\r\n), os dados e outro CRLF. A transmissão é finalizada obrigatoriamente com o chunk terminal de tamanho zero (0\r\n\r\n).
POST /api/upload HTTP/1.1
Host: target.local
Transfer-Encoding: chunked
Content-Type: application/x-www-form-urlencoded
Connection: close
1\r\n
<\r\n
1\r\n
s\r\n
1\r\n
c\r\n
1\r\n
r\r\n
1\r\n
i\r\n
1\r\n
p\r\n
1\r\n
t\r\n
0\r\n
\r\n
WAFs antigos que não remontam streams HTTP chunked analisam apenas os blocos de bytes isolados de 1 byte (que não possuem assinaturas maliciosas), liberando a requisição para o backend. O backend, por sua vez, realiza a remontagem em memória e executa o XSS completo.
[ 0x05 ] NORMALIZAÇÃO UNICODE E COMPATIBILIDADE DE TIPOS
O consórcio Unicode define regras de equivalência de caracteres para unificar variações gráficas. Existem formas de normalização canônica (NFC/NFD) e formas de normalização por compatibilidade (NFKC/NFKD). A normalização por compatibilidade (NFK) é amplamente empregada por bancos de dados e motores de busca para colapsar variantes gráficas de letras em seus equivalentes ASCII.
Por exemplo, o caractere do símbolo Kelvin K (U+212A) é canonicamente distincto da letra ASCII K (U+004B). No entanto, sob a normalização NFKC, U+212A é colapsado para U+004B.
Se um operador enviar um payload contendo SELECKT (usando o símbolo Kelvin):
1. Fase de Inspeção: O WAF realiza a análise estática em formato bruto ou utilizando normalização canônica (NFC). Ele determina que SELECKT não corresponde à palavra-chave restrita SELECT e libera o tráfego.
2. Fase de Execução: A normalização NFKC não ocorre de forma mágica no parser SQL bruto do banco de dados, mas sim nas rotinas de pré-processamento da aplicação, ORMs, adaptadores de conexão (que unificam charsets) ou na normalização interna de strings efetuada por mecanismos de indexação da aplicação antes da geração final da consulta.
Golden Tip: Testar filtros não se resume a automatizar cargas de ataque. Requer mapear e compreender o fluxo de dados em toda a cadeia tecnológica (Load Balancer -> WAF -> Proxy Reverso -> Backend Application -> Database) para identificar inconsistências de decodificação.