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 over cleartext, si discosta dalla norma delle connessioni HTTP transitorie aggiornando una connessione HTTP standard a una persistente. Questa connessione aggiornata utilizza il protocollo binario http2 per la comunicazione continua, a differenza della natura a singola richiesta dell'HTTP in chiaro.
Il nocciolo del problema di smuggling sorge con l'uso di un reverse proxy. Di norma, il reverse proxy elabora e inoltra le richieste HTTP al backend, restituendo la risposta del backend dopo. Tuttavia, quando l'intestazione Connection: Upgrade
è presente in una richiesta HTTP (comunemente vista con le connessioni websocket), il proxy reverse mantiene una connessione persistente tra client e server, facilitando lo scambio continuo richiesto da alcuni protocolli. Per le connessioni H2C, l'aderenza all'RFC richiede la presenza di tre intestazioni specifiche:
La vulnerabilità sorge quando, dopo aver aggiornato una connessione, il reverse proxy smette di gestire le singole richieste, assumendo che il suo compito di instradamento sia completato dopo l'instaurazione della connessione. Sfruttare H2C Smuggling consente di eludere le regole del reverse proxy applicate durante l'elaborazione delle richieste, come l'instradamento basato su percorso, l'autenticazione e l'elaborazione WAF, assumendo che una connessione H2C venga avviata con successo.
La vulnerabilità dipende dalla gestione da parte del reverse proxy degli header Upgrade
e talvolta Connection
. I seguenti proxy inoltrano intrinsecamente questi header durante il proxy-pass, abilitando quindi intrinsecamente H2C smuggling:
HAProxy
Traefik
Nuster
Al contrario, questi servizi non inoltrano intrinsecamente entrambi gli header durante il proxy-pass. Tuttavia, possono essere configurati in modo insicuro, consentendo l'inoltro non filtrato degli header Upgrade
e Connection
:
AWS ALB/CLB
NGINX
Apache
Squid
Varnish
Kong
Envoy
Apache Traffic Server
È fondamentale notare che non tutti i server inoltrano intrinsecamente gli header richiesti per un aggiornamento della connessione H2C conforme. Pertanto, server come AWS ALB/CLB, NGINX e Apache Traffic Server, tra gli altri, bloccano naturalmente le connessioni H2C. Tuttavia, vale la pena testare la variante non conforme Connection: Upgrade
, che esclude il valore HTTP2-Settings
dall'header Connection
, poiché alcuni backend potrebbero non conformarsi agli standard.
Indipendentemente dal percorso specifico designato nell'URL proxy_pass
(ad es., http://backend:9999/socket.io
), la connessione stabilita predefinisce http://backend:9999
. Questo consente di interagire con qualsiasi percorso all'interno di quel punto finale interno, sfruttando questa tecnica. Di conseguenza, la specifica di un percorso nell'URL proxy_pass
non limita l'accesso.
Gli strumenti h2csmuggler by BishopFox e h2csmuggler by assetnote facilitano i tentativi di eludere le protezioni imposte dal proxy stabilendo una connessione H2C, consentendo così l'accesso a risorse protette dal proxy.
Per ulteriori informazioni su questa vulnerabilità, in particolare riguardo a NGINX, fare riferimento a questa risorsa dettagliata.
Lo smuggling di Websocket, a differenza della creazione di un tunnel HTTP2 verso un endpoint accessibile tramite un proxy, stabilisce un tunnel Websocket per bypassare le potenziali limitazioni del proxy e facilitare la comunicazione diretta con l'endpoint.
In questo scenario, un backend che offre un'API WebSocket pubblica insieme a un'API REST interna non accessibile è preso di mira da un client malevolo che cerca di accedere all'API REST interna. L'attacco si svolge in diversi passaggi:
Il client inizia inviando una richiesta di Upgrade al reverse proxy con una versione del protocollo Sec-WebSocket-Version
errata nell'header. Il proxy, non riuscendo a convalidare l'header Sec-WebSocket-Version
, crede che la richiesta di Upgrade sia valida e la inoltra al backend.
Il backend risponde con un codice di stato 426
, indicando la versione del protocollo errata nell'header Sec-WebSocket-Version
. Il reverse proxy, trascurando lo stato di risposta del backend, assume di essere pronto per la comunicazione WebSocket e inoltra la risposta al client.
Di conseguenza, il reverse proxy è fuorviato nel credere che sia stata stabilita una connessione WebSocket tra il client e il backend, mentre in realtà il backend aveva rifiutato la richiesta di Upgrade. Nonostante ciò, il proxy mantiene una connessione TCP o TLS aperta tra il client e il backend, consentendo al client di accedere senza restrizioni all'API REST privata tramite questa connessione.
I reverse proxy interessati includono Varnish, che ha rifiutato di affrontare il problema, e la versione 1.8.0 o precedente del proxy Envoy, con versioni successive che hanno modificato il meccanismo di aggiornamento. Altri proxy potrebbero essere suscettibili.
Questo scenario coinvolge un backend con sia un'API WebSocket pubblica che un'API REST pubblica per il controllo della salute, insieme a un'API REST interna non accessibile. L'attacco, più complesso, coinvolge i seguenti passaggi:
Il client invia una richiesta POST per attivare l'API di controllo della salute, includendo un ulteriore header HTTP Upgrade: websocket
. NGINX, che funge da reverse proxy, interpreta questo come una richiesta di Upgrade standard basata esclusivamente sull'header Upgrade
, trascurando gli altri aspetti della richiesta, e la inoltra al backend.
Il backend esegue l'API di controllo della salute, contattando una risorsa esterna controllata dall'attaccante che restituisce una risposta HTTP con codice di stato 101
. Questa risposta, una volta ricevuta dal backend e inoltrata a NGINX, inganna il proxy facendogli credere che sia stata stabilita una connessione WebSocket a causa della sua convalida solo del codice di stato.
Attenzione: La complessità di questa tecnica aumenta poiché richiede la capacità di interagire con un endpoint in grado di restituire un codice di stato 101.
In definitiva, NGINX è ingannato nel credere che esista una connessione WebSocket tra il client e il backend. In realtà, non esiste alcuna connessione; l'API REST di controllo della salute era l'obiettivo. Tuttavia, il reverse proxy mantiene la connessione aperta, consentendo al client di accedere all'API REST privata tramite essa.
La maggior parte dei reverse proxy è vulnerabile a questo scenario, ma lo sfruttamento dipende dalla presenza di una vulnerabilità SSRF esterna, generalmente considerata un problema di bassa gravità.
Controlla i laboratori per testare entrambi gli scenari in https://github.com/0ang3el/websocket-smuggle.git
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)