# Upgrade Header Smuggling {{#include ../banners/hacktricks-training.md}} ### H2C Smuggling #### HTTP2 Over Cleartext (H2C) H2C, ou **http2 over cleartext**, desvia da norma das conexões HTTP transitórias ao atualizar uma **conexão HTTP padrão para uma persistente**. Esta conexão atualizada utiliza o protocolo binário http2 para comunicação contínua, ao contrário da natureza de solicitação única do HTTP em texto claro. O cerne do problema de contrabando surge com o uso de um **proxy reverso**. Normalmente, o proxy reverso processa e encaminha solicitações HTTP para o backend, retornando a resposta do backend após isso. No entanto, quando o cabeçalho `Connection: Upgrade` está presente em uma solicitação HTTP (comumente visto com conexões websocket), o **proxy reverso mantém uma conexão persistente** entre cliente e servidor, facilitando a troca contínua exigida por certos protocolos. Para conexões H2C, a adesão ao RFC exige a presença de três cabeçalhos específicos: ``` Upgrade: h2c HTTP2-Settings: AAMAAABkAARAAAAAAAIAAAAA Connection: Upgrade, HTTP2-Settings ``` A vulnerabilidade surge quando, após a atualização de uma conexão, o proxy reverso deixa de gerenciar solicitações individuais, assumindo que seu trabalho de roteamento está completo após o estabelecimento da conexão. Explorar H2C Smuggling permite contornar as regras do proxy reverso aplicadas durante o processamento de solicitações, como roteamento baseado em caminho, autenticação e processamento de WAF, assumindo que uma conexão H2C seja iniciada com sucesso. #### Proxies Vulneráveis A vulnerabilidade depende do manuseio dos cabeçalhos `Upgrade` e, às vezes, `Connection` pelo proxy reverso. Os seguintes proxies encaminham esses cabeçalhos durante o proxy-pass, permitindo assim o H2C smuggling: - HAProxy - Traefik - Nuster Por outro lado, esses serviços não encaminham inherentemente ambos os cabeçalhos durante o proxy-pass. No entanto, eles podem ser configurados de forma insegura, permitindo o encaminhamento não filtrado dos cabeçalhos `Upgrade` e `Connection`: - AWS ALB/CLB - NGINX - Apache - Squid - Varnish - Kong - Envoy - Apache Traffic Server #### Exploração É crucial notar que nem todos os servidores encaminham inherentemente os cabeçalhos necessários para uma atualização de conexão H2C compatível. Assim, servidores como AWS ALB/CLB, NGINX e Apache Traffic Server, entre outros, bloqueiam naturalmente conexões H2C. No entanto, vale a pena testar com a variante não compatível `Connection: Upgrade`, que exclui o valor `HTTP2-Settings` do cabeçalho `Connection`, pois alguns backends podem não se conformar aos padrões. > [!CAUTION] > Independentemente do **caminho** específico designado na URL `proxy_pass` (por exemplo, `http://backend:9999/socket.io`), a conexão estabelecida padrão é `http://backend:9999`. Isso permite a interação com qualquer caminho dentro desse endpoint interno, aproveitando essa técnica. Consequentemente, a especificação de um caminho na URL `proxy_pass` não restringe o acesso. As ferramentas [**h2csmuggler by BishopFox**](https://github.com/BishopFox/h2csmuggler) e [**h2csmuggler by assetnote**](https://github.com/assetnote/h2csmuggler) facilitam tentativas de **contornar as proteções impostas pelo proxy** ao estabelecer uma conexão H2C, permitindo assim o acesso a recursos protegidos pelo proxy. Para mais informações sobre essa vulnerabilidade, particularmente em relação ao NGINX, consulte [**este recurso detalhado**](../network-services-pentesting/pentesting-web/nginx.md#proxy_set_header-upgrade-and-connection). ## Websocket Smuggling O websocket smuggling, ao contrário da criação de um túnel HTTP2 para um endpoint acessível via proxy, estabelece um túnel Websocket para contornar possíveis limitações do proxy e facilitar a comunicação direta com o endpoint. ### Cenário 1 Neste cenário, um backend que oferece uma API WebSocket pública juntamente com uma API REST interna inacessível é alvo de um cliente malicioso que busca acesso à API REST interna. O ataque se desenrola em várias etapas: 1. O cliente inicia enviando uma solicitação de Upgrade para o proxy reverso com uma versão de protocolo `Sec-WebSocket-Version` incorreta no cabeçalho. O proxy, falhando em validar o cabeçalho `Sec-WebSocket-Version`, acredita que a solicitação de Upgrade é válida e a encaminha para o backend. 2. O backend responde com um código de status `426`, indicando a versão de protocolo incorreta no cabeçalho `Sec-WebSocket-Version`. O proxy reverso, ignorando o status de resposta do backend, assume que está pronto para comunicação WebSocket e retransmite a resposta para o cliente. 3. Consequentemente, o proxy reverso é induzido a acreditar que uma conexão WebSocket foi estabelecida entre o cliente e o backend, enquanto na realidade, o backend havia rejeitado a solicitação de Upgrade. Apesar disso, o proxy mantém uma conexão TCP ou TLS aberta entre o cliente e o backend, permitindo que o cliente acesse a API REST privada por meio dessa conexão. Os proxies reversos afetados incluem o Varnish, que se recusou a resolver o problema, e a versão 1.8.0 ou anterior do proxy Envoy, com versões posteriores tendo alterado o mecanismo de upgrade. Outros proxies também podem ser suscetíveis. ![https://github.com/0ang3el/websocket-smuggle/raw/master/img/2-4.png](https://github.com/0ang3el/websocket-smuggle/raw/master/img/2-4.png) ### Cenário 2 Este cenário envolve um backend com uma API WebSocket pública e uma API REST pública para verificação de saúde, juntamente com uma API REST interna inacessível. O ataque, mais complexo, envolve as seguintes etapas: 1. O cliente envia uma solicitação POST para acionar a API de verificação de saúde, incluindo um cabeçalho HTTP adicional `Upgrade: websocket`. O NGINX, atuando como o proxy reverso, interpreta isso como uma solicitação de Upgrade padrão com base apenas no cabeçalho `Upgrade`, negligenciando outros aspectos da solicitação, e a encaminha para o backend. 2. O backend executa a API de verificação de saúde, contatando um recurso externo controlado pelo atacante que retorna uma resposta HTTP com código de status `101`. Essa resposta, uma vez recebida pelo backend e encaminhada para o NGINX, engana o proxy, fazendo-o pensar que uma conexão WebSocket foi estabelecida devido à sua validação apenas do código de status. ![https://github.com/0ang3el/websocket-smuggle/raw/master/img/3-4.png](https://github.com/0ang3el/websocket-smuggle/raw/master/img/3-4.png) > **Warning:** A complexidade dessa técnica aumenta à medida que requer a capacidade de interagir com um endpoint capaz de retornar um código de status 101. No final, o NGINX é enganado a acreditar que existe uma conexão WebSocket entre o cliente e o backend. Na realidade, não existe tal conexão; a API REST de verificação de saúde foi o alvo. No entanto, o proxy reverso mantém a conexão aberta, permitindo que o cliente acesse a API REST privada por meio dela. ![https://github.com/0ang3el/websocket-smuggle/raw/master/img/3-5.png](https://github.com/0ang3el/websocket-smuggle/raw/master/img/3-5.png) A maioria dos proxies reversos é vulnerável a esse cenário, mas a exploração depende da presença de uma vulnerabilidade SSRF externa, geralmente considerada um problema de baixa severidade. #### Labs Verifique os labs para testar ambos os cenários em [https://github.com/0ang3el/websocket-smuggle.git](https://github.com/0ang3el/websocket-smuggle.git) ### Referências - [https://blog.assetnote.io/2021/03/18/h2c-smuggling/](https://blog.assetnote.io/2021/03/18/h2c-smuggling/) - [https://bishopfox.com/blog/h2c-smuggling-request](https://bishopfox.com/blog/h2c-smuggling-request) - [https://github.com/0ang3el/websocket-smuggle.git](https://github.com/0ang3el/websocket-smuggle.git) {{#include ../banners/hacktricks-training.md}}