HTTP Response Smuggling / Desync
Last updated
Last updated
Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE) Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
A técnica deste post foi retirada do vídeo: https://www.youtube.com/watch?v=suxDcYViwao&t=1343s
Primeiramente, esta técnica explora uma vulnerabilidade de HTTP Request Smuggling, então você precisa saber o que é:
A principal diferença entre esta técnica e um comum HTTP Request smuggling é que em vez de atacar a requisição da vítima adicionando um prefixo a ela, nós vamos vazar ou modificar a resposta que a vítima recebe. Isso é feito ao invés de enviar 1 requisição e meia para abusar do HTTP Request smuggling, enviar 2 requisições completas para desincronizar a fila de respostas dos proxies.
Isso ocorre porque vamos conseguir desincronizar a fila de respostas para que a resposta da requisição legítima da vítima seja enviada ao atacante, ou injetando conteúdo controlado pelo atacante na resposta para a vítima.
HTTP/1.1 permite solicitar recursos diferentes sem precisar esperar pelos anteriores. Portanto, se houver um proxy no meio, é tarefa dos proxies manter uma correspondência sincronizada das requisições enviadas para o backend e as respostas que vêm dele.
No entanto, há um problema em desincronizar a fila de respostas. Se um atacante enviar um ataque de HTTP Response smuggling e as respostas para a requisição inicial e a smuggled forem respondidas imediatamente, a resposta smuggled não será inserida na fila de resposta da vítima, mas será apenas descartada como um erro.
Portanto, é necessário que a requisição smuggled demore mais tempo para ser processada dentro do servidor backend. Assim, quando a requisição smuggled for processada, a comunicação com o atacante já terá terminado.
Se nesta situação específica uma vítima enviou uma requisição e a requisição smuggled for respondida antes da requisição legítima, a resposta smuggled será enviada para a vítima. Portanto, o atacante estará controlando a requisição "realizada" pela vítima.
Além disso, se o atacante então realizar uma requisição e a resposta legítima para a requisição da vítima for respondida antes da requisição do atacante. A resposta para a vítima será enviada ao atacante, roubando a resposta da vítima (que pode conter, por exemplo, o cabeçalho Set-Cookie).
Outra diferença interessante com o comum HTTP Request Smuggling é que, em um ataque comum de smuggling, o objetivo é modificar o início da requisição da vítima para que ela realize uma ação inesperada. Em um ataque de HTTP Response smuggling, como você está enviando requisições completas, você pode injetar em um payload dezenas de respostas que estarão desincronizando dezenas de usuários que estarão recebendo as respostas injetadas.
Além de poder distribuir mais facilmente dezenas de exploits entre usuários legítimos, isso também pode ser usado para causar um DoS no servidor.
Como explicado anteriormente, para abusar desta técnica, é necessário que a primeira mensagem smuggled no servidor exija muito tempo para ser processada.
Esta requisição que consome tempo é suficiente se apenas quisermos tentar roubar a resposta da vítima. Mas se você quiser realizar um exploit mais complexo, esta será uma estrutura comum para o exploit.
Primeiramente a requisição inicial abusando do HTTP Request smuggling, em seguida a requisição que consome tempo e depois 1 ou mais requisições payload cujas respostas serão enviadas para as vítimas.
Assim como com payloads conhecidos de HTTP Request Smuggling, você pode roubar a requisição da vítima com uma diferença importante: Neste caso, você só precisa que o conteúdo enviado seja refletido na resposta, nenhum armazenamento persistente é necessário.
Primeiro, o atacante envia um payload contendo uma requisição POST final com o parâmetro refletido no final e um grande Content-Length
Então, uma vez que a requisição inicial (azul) foi processada e enquanto a requisição lenta está sendo processada (amarela), a próxima requisição que chega de uma vítima será adicionada na fila logo após o parâmetro refletido:
Então, a vítima receberá a resposta para a requisição lenta e se, nesse meio tempo, o atacante enviar outra requisição, a resposta da requisição de conteúdo refletido será enviada a ele.
Até este ponto, aprendemos como abusar de ataques de HTTP Request Smuggling para controlar a requisição cuja resposta um cliente vai receber e como você pode então roubar a resposta que era destinada à vítima.
Mas ainda é possível desincronizar ainda mais as respostas.
Existem requisições interessantes como a requisição HEAD que são especificadas para não ter nenhum conteúdo dentro do corpo das respostas e que devem (devem) conter o Content-Length da requisição como se fosse uma requisição GET.
Portanto, se um atacante injeta uma requisição HEAD, como nas imagens:
Então, uma vez que a azul é respondida ao atacante, a próxima requisição da vítima será introduzida na fila:
Então, a vítima receberá a resposta da requisição HEAD, que vai conter um Content-Length mas nenhum conteúdo. Portanto, o proxy não enviará esta resposta para a vítima, mas esperará por algum conteúdo, que na verdade será a resposta para a requisição amarela (também injetada pelo atacante):
Seguindo o exemplo anterior, sabendo que você pode controlar o corpo da requisição cuja resposta a vítima vai receber e que uma resposta HEAD geralmente contém em seus cabeçalhos o Content-Type e o Content-Length, você pode enviar uma requisição como a seguinte para causar XSS na vítima sem que a página seja vulnerável a XSS:
Abusando do ataque de Confusão de Conteúdo de desincronização de resposta comentado anteriormente, se o cache armazenar a resposta para a requisição realizada pela vítima e essa resposta for uma injetada causando um XSS, então o cache está envenenado.
Requisição maliciosa contendo o payload de XSS:
Resposta maliciosa para a vítima que contém o cabeçalho que indica ao cache para armazenar a resposta:
Note que neste caso, se a "vítima" for o atacante, ele pode agora realizar envenenamento de cache em URLs arbitrárias já que ele pode controlar a URL que será armazenada com a resposta maliciosa.
Este ataque é semelhante ao anterior, mas em vez de injetar um payload dentro do cache, o atacante estará armazenando informações da vítima dentro do cache:
O objetivo deste ataque é abusar novamente da desincronização da resposta para fazer o proxy enviar uma resposta 100% gerada pelo atacante.
Para alcançar isso, o atacante precisa encontrar um endpoint da aplicação web que esteja refletindo alguns valores dentro da resposta e saber o tamanho do conteúdo da resposta HEAD.
Ele enviará um exploit como:
Após a primeira requisição ser resolvida e enviada de volta ao atacante, a requisição da vítima é adicionada na fila:
A vítima receberá como resposta a resposta HEAD + o conteúdo da resposta da segunda requisição (contendo parte dos dados refletidos):
No entanto, note como os dados refletidos tinham um tamanho de acordo com o Content-Length da resposta HEAD que gerou uma resposta HTTP válida na fila de respostas.
Portanto, a próxima requisição do segundo vítima estará recebendo como resposta algo completamente elaborado pelo atacante. Como a resposta é completamente elaborada pelo atacante, ele também pode fazer o proxy armazenar a resposta.
Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE) Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)