hacktricks/pentesting-web/h2c-smuggling.md
2023-06-06 18:56:34 +00:00

102 lines
9.4 KiB
Markdown

# Upgrade de Header Smuggling
<details>
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks Cloud ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
- Você trabalha em uma **empresa de segurança cibernética**? Você quer ver sua **empresa anunciada no HackTricks**? ou você quer ter acesso à **última versão do PEASS ou baixar o HackTricks em PDF**? Confira os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)!
- Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
- Adquira o [**swag oficial do PEASS & HackTricks**](https://peass.creator-spring.com)
- **Junte-se ao** [**💬**](https://emojipedia.org/speech-balloon/) [**grupo do Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo do telegram**](https://t.me/peass) ou **siga-me** no **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
- **Compartilhe suas técnicas de hacking enviando PRs para o [repositório hacktricks](https://github.com/carlospolop/hacktricks) e [hacktricks-cloud repo](https://github.com/carlospolop/hacktricks-cloud)**.
</details>
## H2C Smuggling <a href="#http2-over-cleartext-h2c" id="http2-over-cleartext-h2c"></a>
### HTTP2 Sobre Texto Claro (H2C) <a href="#http2-over-cleartext-h2c" id="http2-over-cleartext-h2c"></a>
Uma conexão HTTP normalmente dura apenas durante a duração de uma única solicitação. No entanto, H2C ou "**http2 sobre texto claro**" é onde uma conexão http normal transitória é atualizada para uma conexão persistente que usa o protocolo binário http2 para se comunicar continuamente em vez de uma solicitação usando o protocolo http em texto simples.
A segunda parte do smuggling ocorre quando um **proxy reverso é usado**. Normalmente, quando solicitações http são feitas a um proxy reverso, o proxy lidará com a solicitação, processará uma série de regras de roteamento, encaminhará a solicitação para o backend e, em seguida, retornará a resposta. Quando uma solicitação http inclui um cabeçalho `Connection: Upgrade`, como para uma conexão websocket, o **proxy reverso manterá a conexão persistente** entre o cliente e o servidor, **permitindo a comunicação contínua necessária para esses protocolos**. Para uma conexão H2C, o RFC requer que 3 cabeçalhos estejam presentes:
```
Upgrade: h2c
HTTP2-Settings: AAMAAABkAARAAAAAAAIAAAAA
Connection: Upgrade, HTTP2-Settings
```
Então, onde está o bug? **Ao atualizar uma conexão, o proxy reverso frequentemente deixará de lidar com solicitações individuais**, assumindo que, uma vez estabelecida a conexão, seu trabalho de roteamento está concluído. Usando o H2C Smuggling, podemos contornar as regras que um proxy reverso usa ao processar solicitações, como roteamento baseado em caminho, autenticação ou processamento WAF, desde que possamos estabelecer uma conexão H2C primeiro.
![](<../.gitbook/assets/image (454).png>)
### Proxies Vulneráveis <a href="#exploitation" id="exploitation"></a>
Observe a explicação da vulnerabilidade que o servidor proxy precisa **encaminhar o cabeçalho Upgrade**, e às vezes o **cabeçalho Connection** também precisa ser encaminhado com sucesso.
Por padrão, os seguintes serviços **encaminham** o **Upgrade** e os cabeçalhos **Connection** durante o proxy-pass, permitindo assim o h2c smuggling out-of-the-box:
* HAProxy
* Traefik
* Nuster
Por padrão, esses serviços **não** encaminham ambos os cabeçalhos Upgrade e Connection durante o proxy-pass, mas **podem ser configurados de maneira insegura** (passando cabeçalhos Upgrade e Connection não filtrados):
* AWS ALB/CLB
* NGINX
* Apache
* Squid
* Varnish
* Kong
* Envoy
* Apache Traffic Server
### Exploração <a href="#exploitation" id="exploitation"></a>
A postagem original do blog aponta que nem todos os servidores encaminharão os cabeçalhos necessários para uma atualização de conexão H2C compatível. Isso significa que balanceadores de carga como AWS ALB/CLB, NGINX e Apache Traffic Server, entre outros, **impedirão uma conexão H2C por padrão**. No entanto, no final da postagem do blog, ele menciona que "nem todos os back-ends eram compatíveis, e poderíamos **testar com a variante não compatível `Connection: Upgrade`, em que o valor `HTTP2-Settings` é omitido do cabeçalho `Connection`**".
{% hint style="danger" %}
Observe que, mesmo que a URL de `proxy_pass` (o ponto final para o qual o proxy encaminha a conexão) aponte para um **caminho** específico, como `http://backend:9999/socket.io`, a conexão será estabelecida com `http://backend:9999`, para que você possa **acessar qualquer outro caminho dentro desse endpoint interno abusando dessa técnica. Portanto, não importa se um caminho é especificado na URL de proxy\_pass.**
{% endhint %}
Usando as ferramentas [**https://github.com/BishopFox/h2csmuggler**](https://github.com/BishopFox/h2csmuggler) **e** [**https://github.com/assetnote/h2csmuggler**](https://github.com/assetnote/h2csmuggler), você pode tentar **contornar as proteções impostas** pelo proxy estabelecendo uma conexão H2C e acessar recursos protegidos pelo proxy.
Siga este link para [**mais informações sobre essa vulnerabilidade no Nginx**](../network-services-pentesting/pentesting-web/nginx.md#proxy\_set\_header-upgrade-and-connection).
## Smuggling de Websocket
Semelhante à técnica anterior, esta **em vez disso** de criar um **túnel HTTP2** para um endpoint acessível por meio de um proxy, criará um **túnel Websocket** para o mesmo propósito, **contornando as limitações potenciais dos proxies** e falando diretamente com o endpoint:
![](<../.gitbook/assets/image (651) (2) (1).png>)
### Cenário 1
Temos um backend que expõe uma **API WebSocket pública** e também tem uma **API REST interna não disponível** externamente. Um cliente mal-intencionado deseja acessar a API REST interna.
No **primeiro** passo, o cliente envia uma **solicitação de atualização** para o proxy reverso, mas com uma **versão de protocolo incorreta** dentro do cabeçalho `Sec-WebSocket-Version`. O **proxy** não valida o cabeçalho `Sec-WebSocket-Version` e pensa que a **solicitação de atualização está correta**. Além disso, ele traduz a solicitação para o backend.
No segundo passo, o backend envia **resposta com o código de status `426` porque a versão do protocolo está incorreta** dentro do cabeçalho `Sec-WebSocket-Version`. No entanto, o **proxy reverso não verifica** a resposta suficiente do backend (incluindo o código de status) e **pensa que o backend está pronto para a comunicação WebSocket**. Além disso, ele traduz a solicitação para o cliente.
Finalmente, o **proxy reverso pensa** que a **conexão WebSocket está estabelecida entre o cliente e o backend**. Na realidade, não há conexão WebSocket - o backend recusou a solicitação de atualização. Ao mesmo tempo, o proxy mantém a conexão TCP ou TLS entre o cliente e o backend em estado aberto. **O cliente pode facilmente acessar a API REST privada enviando uma solicitação HTTP sobre a conexão.**
![](https://github.com/0ang3el/websocket-smuggle/raw/master/img/2-4.png)
Foi descoberto que os seguintes proxies reversos são afetados:
* Varnish - a equipe se recusou a corrigir o problema descrito.
* Envoy proxy 1.8.0 (ou mais antigo) - em versões mais recentes, o mecanismo de atualização foi alterado.
* Outros - TBA.
### Cenário 2
A maioria dos proxies reversos (por exemplo, NGINX) **verifica o código de status do backend** durante a parte de handshake. Isso torna o ataque mais difícil, mas não impossível.
Vamos observar o segundo cenário. Temos um backend que expõe uma API WebSocket pública e uma API REST pública para verificação de integridade e também tem uma **API REST interna não disponível** externamente. Um cliente mal-intencionado deseja acessar a API REST interna. O NGINX é usado como proxy reverso. A API WebSocket está disponível no caminho `/api/socket.io/` e a API de verificação de integridade no caminho `/api/health`.
A API de verificação de integridade é invocada enviando uma solicitação POST, o parâmetro com o nome `u` controla a URL. O backend alcança o recurso externo e retorna o código de status de volta ao cliente.
No **primeiro** passo, o cliente envia uma solicitação POST para invocar a **API de verificação de integridade, mas com um cabeçalho HTTP adicional `Upgrade: websocket`**. O NGINX pensa que é uma **solicitação de atualização normal**, ele procura apenas o cabeçalho `Upgrade`, ignorando outras partes da solicitação. Além disso, o proxy traduz a solicitação para o backend.
No **segundo** passo, o backend invoca a API de verificação de integridade. Ele alcança o recurso externo controlado por usuários mal-intencionados que retorna a **resposta HTTP com o código de status `101`**. O backend traduz essa resposta para o proxy reverso. Como o NGINX valida apenas o código de status, **ele pensará que o backend está pronto para a comunicação WebSocket**.