Upgrade Header Smuggling
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:
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:
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çalhoSec-WebSocket-Version
, acredita que a solicitação Upgrade é válida e a encaminha para o backend.O backend responde com um código de status
426
, indicando a versão de protocolo incorreta no cabeçalhoSec-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.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:
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çalhoUpgrade
, negligenciando outros aspectos da solicitação, e a encaminha para o backend.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
Last updated