Upgrade Header Smuggling

Support HackTricks

H2C Smuggling

HTTP2 Over Cleartext (H2C)

H2C, ou http2 sobre texto claro, 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 smuggling 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 é 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, já que alguns backends podem não estar em conformidade com os padrões.

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 e h2csmuggler by assetnote 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.

Websocket Smuggling

Websocket smuggling, ao contrário da criação de um túnel HTTP2 para um endpoint acessível via um proxy, estabelece um túnel Websocket para contornar potenciais 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 Upgrade para o proxy reverso com uma versão de protocolo Sec-WebSocket-Version incorreta no cabeçalho. O proxy, não validando o cabeçalho Sec-WebSocket-Version, acredita que a solicitação 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 ao 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 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 sem restrições a API REST privada através dessa conexão.

Os proxies reversos afetados incluem Varnish, que se recusou a abordar o problema, e a versão 1.8.0 ou anterior do proxy Envoy, com versões posteriores tendo alterado o mecanismo de atualização. Outros proxies também podem ser suscetíveis.

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.

Aviso: 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 uma conexão WebSocket existe entre o cliente e o backend. Na realidade, nenhuma conexão desse tipo existe; 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 através dela.

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

Referências

Support HackTricks

Last updated