Upgrade Header Smuggling
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
H2C, o http2 sobre texto claro, se desvía de la norma de conexiones HTTP transitorias al actualizar una conexión HTTP estándar a una persistente. Esta conexión actualizada utiliza el protocolo binario http2 para la comunicación continua, a diferencia de la naturaleza de solicitud única del HTTP en texto claro.
El núcleo del problema de smuggling surge con el uso de un proxy inverso. Normalmente, el proxy inverso procesa y reenvía las solicitudes HTTP al backend, devolviendo la respuesta del backend después de eso. Sin embargo, cuando el encabezado Connection: Upgrade
está presente en una solicitud HTTP (comúnmente visto con conexiones websocket), el proxy inverso mantiene una conexión persistente entre el cliente y el servidor, facilitando el intercambio continuo requerido por ciertos protocolos. Para las conexiones H2C, la adherencia al RFC requiere la presencia de tres encabezados específicos:
La vulnerabilidad surge cuando, después de actualizar una conexión, el proxy inverso deja de gestionar solicitudes individuales, asumiendo que su trabajo de enrutamiento está completo tras el establecimiento de la conexión. Explotar H2C Smuggling permite eludir las reglas del proxy inverso aplicadas durante el procesamiento de solicitudes, como el enrutamiento basado en rutas, la autenticación y el procesamiento de WAF, asumiendo que se inicia con éxito una conexión H2C.
La vulnerabilidad depende del manejo de los encabezados Upgrade
y a veces Connection
por parte del proxy inverso. Los siguientes proxies reenvían inherentemente estos encabezados durante el proxy-pass, habilitando así H2C smuggling:
HAProxy
Traefik
Nuster
Por el contrario, estos servicios no reenvían inherentemente ambos encabezados durante el proxy-pass. Sin embargo, pueden configurarse de manera insegura, permitiendo el reenvío sin filtrar de los encabezados Upgrade
y Connection
:
AWS ALB/CLB
NGINX
Apache
Squid
Varnish
Kong
Envoy
Apache Traffic Server
Es crucial notar que no todos los servidores reenvían inherentemente los encabezados requeridos para una actualización de conexión H2C conforme. Como tal, servidores como AWS ALB/CLB, NGINX y Apache Traffic Server, entre otros, bloquean naturalmente las conexiones H2C. No obstante, vale la pena probar con la variante no conforme Connection: Upgrade
, que excluye el valor HTTP2-Settings
del encabezado Connection
, ya que algunos backends pueden no ajustarse a los estándares.
Independientemente de la ruta específica designada en la URL proxy_pass
(por ejemplo, http://backend:9999/socket.io
), la conexión establecida se predetermina a http://backend:9999
. Esto permite la interacción con cualquier ruta dentro de ese punto final interno, aprovechando esta técnica. En consecuencia, la especificación de una ruta en la URL proxy_pass
no restringe el acceso.
Las herramientas h2csmuggler by BishopFox y h2csmuggler by assetnote facilitan los intentos de eludir las protecciones impuestas por el proxy al establecer una conexión H2C, permitiendo así el acceso a recursos protegidos por el proxy.
Para obtener información adicional sobre esta vulnerabilidad, particularmente en relación con NGINX, consulte este recurso detallado.
El websocket smuggling, a diferencia de crear un túnel HTTP2 a un punto final accesible a través de un proxy, establece un túnel Websocket para eludir posibles limitaciones del proxy y facilitar la comunicación directa con el punto final.
En este escenario, un backend que ofrece una API WebSocket pública junto con una API REST interna inaccesible es objetivo de un cliente malicioso que busca acceso a la API REST interna. El ataque se desarrolla en varios pasos:
El cliente inicia enviando una solicitud Upgrade al proxy inverso con una versión de protocolo Sec-WebSocket-Version
incorrecta en el encabezado. El proxy, al no validar el encabezado Sec-WebSocket-Version
, cree que la solicitud Upgrade es válida y la reenvía al backend.
El backend responde con un código de estado 426
, indicando la versión de protocolo incorrecta en el encabezado Sec-WebSocket-Version
. El proxy inverso, ignorando el estado de respuesta del backend, asume que está listo para la comunicación WebSocket y reenvía la respuesta al cliente.
En consecuencia, el proxy inverso es engañado para creer que se ha establecido una conexión WebSocket entre el cliente y el backend, mientras que en realidad, el backend había rechazado la solicitud Upgrade. A pesar de esto, el proxy mantiene una conexión TCP o TLS abierta entre el cliente y el backend, permitiendo al cliente acceder sin restricciones a la API REST privada a través de esta conexión.
Los proxies inversos afectados incluyen Varnish, que se negó a abordar el problema, y la versión 1.8.0 o anterior del proxy Envoy, con versiones posteriores que han alterado el mecanismo de actualización. Otros proxies también pueden ser susceptibles.
Este escenario involucra un backend con una API WebSocket pública y una API REST pública para verificación de estado, junto con una API REST interna inaccesible. El ataque, más complejo, implica los siguientes pasos:
El cliente envía una solicitud POST para activar la API de verificación de estado, incluyendo un encabezado HTTP adicional Upgrade: websocket
. NGINX, actuando como el proxy inverso, interpreta esto como una solicitud de actualización estándar basada únicamente en el encabezado Upgrade
, descuidando otros aspectos de la solicitud, y la reenvía al backend.
El backend ejecuta la API de verificación de estado, contactando un recurso externo controlado por el atacante que devuelve una respuesta HTTP con código de estado 101
. Esta respuesta, una vez recibida por el backend y reenviada a NGINX, engaña al proxy haciéndole creer que se ha establecido una conexión WebSocket debido a su validación solo del código de estado.
Advertencia: La complejidad de esta técnica aumenta ya que requiere la capacidad de interactuar con un punto final capaz de devolver un código de estado 101.
En última instancia, NGINX es engañado para creer que existe una conexión WebSocket entre el cliente y el backend. En realidad, no existe tal conexión; la API REST de verificación de estado fue el objetivo. Sin embargo, el proxy inverso mantiene la conexión abierta, permitiendo al cliente acceder a la API REST privada a través de ella.
La mayoría de los proxies inversos son vulnerables a este escenario, pero la explotación depende de la presencia de una vulnerabilidad SSRF externa, generalmente considerada como un problema de baja gravedad.
Verifique los laboratorios para probar ambos escenarios en https://github.com/0ang3el/websocket-smuggle.git
Aprende y practica Hacking en AWS:HackTricks Training AWS Red Team Expert (ARTE) Aprende y practica Hacking en GCP: HackTricks Training GCP Red Team Expert (GRTE)