# Bypass de Proteções de Proxy / WAF {{#include ../banners/hacktricks-training.md}} ## Bypass Nginx ACL Rules with Pathname Manipulation Técnicas [desta pesquisa](https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies). Exemplo de regra do Nginx: ```plaintext location = /admin { deny all; } location = /admin/ { deny all; } ``` Para prevenir bypasses, o Nginx executa a normalização do caminho antes de verificá-lo. No entanto, se o servidor backend realizar uma normalização diferente (removendo caracteres que o Nginx não remove), pode ser possível realizar um bypass dessa defesa. ### **NodeJS - Express** | Versão do Nginx | **Caracteres de Bypass do Node.js** | | --------------- | ----------------------------------- | | 1.22.0 | `\xA0` | | 1.21.6 | `\xA0` | | 1.20.2 | `\xA0`, `\x09`, `\x0C` | | 1.18.0 | `\xA0`, `\x09`, `\x0C` | | 1.16.1 | `\xA0`, `\x09`, `\x0C` | ### **Flask** | Versão do Nginx | **Caracteres de Bypass do Flask** | | --------------- | ------------------------------------------------------------- | | 1.22.0 | `\x85`, `\xA0` | | 1.21.6 | `\x85`, `\xA0` | | 1.20.2 | `\x85`, `\xA0`, `\x1F`, `\x1E`, `\x1D`, `\x1C`, `\x0C`, `\x0B` | | 1.18.0 | `\x85`, `\xA0`, `\x1F`, `\x1E`, `\x1D`, `\x1C`, `\x0C`, `\x0B` | | 1.16.1 | `\x85`, `\xA0`, `\x1F`, `\x1E`, `\x1D`, `\x1C`, `\x0C`, `\x0B` | ### **Spring Boot** | Versão do Nginx | **Caracteres de Bypass do Spring Boot** | | --------------- | --------------------------------------- | | 1.22.0 | `;` | | 1.21.6 | `;` | | 1.20.2 | `\x09`, `;` | | 1.18.0 | `\x09`, `;` | | 1.16.1 | `\x09`, `;` | ### **PHP-FPM** Configuração do Nginx FPM: ```plaintext location = /admin.php { deny all; } location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/run/php/php8.1-fpm.sock; } ``` Nginx está configurado para bloquear o acesso a `/admin.php`, mas é possível contornar isso acessando `/admin.php/index.php`. ### Como prevenir ```plaintext location ~* ^/admin { deny all; } ``` ## Bypass Mod Security Rules ### Path Confusion [**In this post**](https://blog.sicuranext.com/modsecurity-path-confusion-bugs-bypass/) é explicado que o ModSecurity v3 (até 3.0.12), **implementou incorretamente a variável `REQUEST_FILENAME`** que deveria conter o path acessado (até o início dos parâmetros). Isso ocorreu porque ele realizou um URL decode para obter o path.\ Portanto, uma request como `http://example.com/foo%3f';alert(1);foo=` no mod security vai supor que o path é apenas `/foo` porque `%3f` é transformado em `?`, encerrando o path da URL, mas na verdade o path que o servidor receberá será `/foo%3f';alert(1);foo=`. As variáveis `REQUEST_BASENAME` e `PATH_INFO` também foram afetadas por esse bug. Algo semelhante ocorreu na versão 2 do Mod Security que permitia burlar uma proteção que impedia o acesso de usuários a arquivos com extensões específicas relacionadas a backups (como `.bak`) simplesmente enviando o ponto codificado em URL `%2e`, por exemplo: `https://example.com/backup%2ebak`. ## Bypass AWS WAF ACL ### Malformed Header [This research](https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies) menciona que era possível burlar regras do AWS WAF aplicadas sobre cabeçalhos HTTP enviando um cabeçalho "malformed" que não era corretamente parseado pelo AWS, mas era pelo servidor backend. Por exemplo, enviando a seguinte request com uma SQL injection no cabeçalho X-Query: ```http GET / HTTP/1.1\r\n Host: target.com\r\n X-Query: Value\r\n \t' or '1'='1' -- \r\n Connection: close\r\n \r\n ``` Era possível contornar o AWS WAF porque ele não entendia que a linha seguinte fazia parte do valor do cabeçalho enquanto o servidor NODEJS entendia (isso foi corrigido). ## Bypasses genéricos de WAF ### Limites de tamanho de requisição Normalmente WAFs têm um certo limite de comprimento das requisições a serem verificadas e se uma requisição POST/PUT/PATCH ultrapassar esse limite, o WAF não verificará a requisição. - For AWS WAF, you can [**check the documentation**](https://docs.aws.amazon.com/waf/latest/developerguide/limits.html)**:**
Tamanho máximo do corpo de uma requisição web que pode ser inspecionado para as proteções do Application Load Balancer e AWS AppSync8 KB
Tamanho máximo do corpo de uma requisição web que pode ser inspecionado para as proteções do CloudFront, API Gateway, Amazon Cognito, App Runner, e Verified Access**64 KB
- From [**Azure docs**](https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/application-gateway-waf-request-size-limits)**:** Web Application Firewalls mais antigos com Core Rule Set 3.1 (ou inferior) permitem mensagens maiores que **128 KB** ao desligar a inspeção do corpo da requisição, mas essas mensagens não serão verificadas por vulnerabilidades. Para versões mais novas (Core Rule Set 3.2 ou superior), o mesmo pode ser feito desabilitando o limite máximo do corpo da requisição. Quando uma requisição excede o limite de tamanho: Se **modo de prevenção**: Registra e bloqueia a requisição.\ Se **modo de detecção**: Inspeciona até o limite, ignora o resto e registra se o `Content-Length` exceder o limite. - From [**Akamai**](https://community.akamai.com/customers/s/article/Can-WAF-inspect-all-arguments-and-values-in-request-body?language=en_US)**:** Por padrão, o WAF inspeciona apenas os primeiros 8KB de uma requisição. Pode aumentar o limite até 128KB adicionando Advanced Metadata. - From [**Cloudflare**](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/#http-request-body-fields)**:** Até 128KB. ### Brechas na inspeção de assets estáticos (.js GETs) Algumas pilhas CDN/WAF aplicam inspeção de conteúdo fraca ou nenhuma em requisições GET para assets estáticos (por exemplo caminhos terminando com `.js`), enquanto ainda aplicam regras globais como rate limiting e reputação de IP. Combinado com auto-caching de extensões estáticas, isso pode ser abusado para entregar ou semear variantes maliciosas que afetam respostas HTML subsequentes. Casos de uso práticos: - Enviar payloads em headers não confiáveis (por exemplo, `User-Agent`) em um GET para um path `.js` para evitar inspeção de conteúdo, e então solicitar imediatamente o HTML principal para influenciar a variante em cache. - Usar um IP novo/limpo; uma vez que um IP é sinalizado, mudanças de roteamento podem tornar a técnica pouco confiável. - No Burp Repeater, usar "Send group in parallel" (estilo single-packet) para correr as duas requisições (`.js` então HTML) pela mesma rota de front-end. Isso combina bem com header-reflection cache poisoning. Veja: {{#ref}} cache-deception/README.md {{#endref}} - [How I found a 0-Click Account takeover in a public BBP and leveraged it to access Admin-Level functionalities](https://hesar101.github.io/posts/How-I-found-a-0-Click-Account-takeover-in-a-public-BBP-and-leveraged-It-to-access-Admin-Level-functionalities/) ### Ofuscação ```bash # IIS, ASP Clasic <%s%cr%u0131pt> == #changing the case of the tag < #prepending an additional "<" #using backticks instead of parenetheses java%0ascript:alert(1) #using encoded newline characters