hacktricks/pentesting-web/h2c-smuggling.md

120 lines
10 KiB
Markdown

# Upgrade Header Smuggling
{% hint style="success" %}
Learn & practice AWS Hacking:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
Learn & practice GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
<details>
<summary>Support HackTricks</summary>
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
</details>
{% endhint %}
### H2C Smuggling <a href="#http2-over-cleartext-h2c" id="http2-over-cleartext-h2c"></a>
#### HTTP2 Over Cleartext (H2C) <a href="#http2-over-cleartext-h2c" id="http2-over-cleartext-h2c"></a>
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 href="#exploitation" id="exploitation"></a>
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 <a href="#exploitation" id="exploitation"></a>
É 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.
{% hint style="danger" %}
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.
{% endhint %}
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
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.
![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)
> **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.
![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)
{% hint style="success" %}
Aprenda e pratique Hacking AWS:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
Aprenda e pratique Hacking GCP: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
<details>
<summary>Support HackTricks</summary>
* Confira os [**planos de assinatura**](https://github.com/sponsors/carlospolop)!
* **Junte-se ao** 💬 [**grupo do Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo do telegram**](https://t.me/peass) ou **siga-nos no** **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Compartilhe truques de hacking enviando PRs para o** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repositórios do github.
</details>
{% endhint %}