HTTP Request Smuggling / HTTP Desync Attack
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)
Essa vulnerabilidade ocorre quando uma desincronização entre os proxies de front-end e o servidor 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/reverse-proxy) e como 2 requisições pelo servidor back-end. Isso permite que um usuário modifique a próxima requisição que chega ao servidor back-end após a sua.
Se uma mensagem for recebida com um campo de cabeçalho Transfer-Encoding e um campo de cabeçalho Content-Length, o ú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 grandes dados são enviados em uma série de pedaços.
O Front-End (um balanceador de carga / Reverse Proxy) processa o cabeçalho content-length ou o cabeçalho transfer-encoding e o servidor 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 reverse proxy que será interpretada pelo servidor back-end como 2 requisições diferentes. O perigo dessa técnica reside no fato de que o servidor back-end interpretará a 2ª requisição injetada como se tivesse vindo do próximo cliente e a requisição real desse cliente será parte da requisição injetada.
Lembre-se de que em 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 deve 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 pedaço. O pedaço deve terminar com uma nova linha, mas essa nova linha não é contada pelo indicador de comprimento. Este método de transferência deve terminar com um pedaço de tamanho 0 seguido por 2 novas linhas: 0
Connection: Com base na minha experiência, é recomendado usar Connection: keep-alive
na primeira requisição do Request Smuggling.
Ao tentar explorar isso com Burp Suite desative Update Content-Length
e Normalize HTTP/1 line endings
no repetidor, pois alguns gadgets abusam de novas linhas, retornos de carro e content-lengths malformados.
Os ataques de HTTP request smuggling são elaborados enviando requisições ambíguas que exploram discrepâncias em como os servidores de front-end e back-end interpretam os cabeçalhos Content-Length
(CL) e Transfer-Encoding
(TE). Esses ataques podem se manifestar de diferentes formas, principalmente como CL.TE, TE.CL e TE.TE. Cada tipo representa uma combinação única de como os servidores de front-end e back-end priorizam esses cabeçalhos. As vulnerabilidades surgem do processamento da mesma requisição pelos servidores de maneiras diferentes, levando a resultados inesperados e potencialmente maliciosos.
Na tabela anterior, você deve adicionar a técnica TE.0, como a técnica CL.0, mas usando Transfer Encoding.
Front-End (CL): Processa a requisição com base no cabeçalho Content-Length
.
Back-End (TE): Processa a requisição com base no cabeçalho Transfer-Encoding
.
Cenário de Ataque:
O atacante envia uma requisição onde o valor do cabeçalho Content-Length
não corresponde ao comprimento real do conteúdo.
O servidor de front-end encaminha toda a requisição para o back-end, com base no valor de Content-Length
.
O servidor back-end processa a requisição como chunked devido ao cabeçalho Transfer-Encoding: chunked
, interpretando os dados restantes como uma requisição separada e subsequente.
Exemplo:
Front-End (TE): Processa a requisição com base no cabeçalho Transfer-Encoding
.
Back-End (CL): Processa a requisição com base no cabeçalho Content-Length
.
Cenário de Ataque:
O atacante envia uma requisição chunked onde o tamanho do pedaço (7b
) e o comprimento real do conteúdo (Content-Length: 4
) não se alinham.
O servidor de front-end, respeitando Transfer-Encoding
, encaminha toda a requisição para o back-end.
O servidor back-end, respeitando Content-Length
, processa apenas a parte inicial da requisição (7b
bytes), deixando o restante como parte de uma requisição subsequente não intencional.
Exemplo:
Servidores: Ambos suportam Transfer-Encoding
, mas um pode ser enganado para ignorá-lo via ofuscação.
Cenário de Ataque:
O atacante envia uma requisição com cabeçalhos Transfer-Encoding
ofuscados.
Dependendo de qual servidor (front-end ou back-end) falha em reconhecer a ofuscação, uma vulnerabilidade CL.TE ou TE.CL pode ser explorada.
A parte não processada da requisição, como vista por um dos servidores, torna-se parte de uma requisição subsequente, levando ao smuggling.
Exemplo:
Ambos os servidores processam a requisição com base apenas no cabeçalho Content-Length
.
Este cenário normalmente não leva ao smuggling, pois há alinhamento em como ambos os servidores interpretam o comprimento da requisição.
Exemplo:
Refere-se a cenários onde o cabeçalho Content-Length
está presente e tem um valor diferente de zero, indicando que o corpo da requisição tem conteúdo. O back-end ignora o cabeçalho Content-Length
(que é tratado como 0), mas o front-end o analisa.
É crucial para entender e elaborar ataques de smuggling, pois influencia como os servidores determinam o final de uma requisição.
Exemplo:
Semelhante ao anterior, mas usando TE.
Técnica reportada aqui
Exemplo:
Esta técnica também é útil em cenários onde é possível quebrar um servidor web enquanto lê os dados HTTP iniciais mas sem fechar a conexão. Dessa forma, o corpo da requisição HTTP será considerado a próxima requisição HTTP.
Por exemplo, como explicado em este artigo, no Werkzeug era possível enviar alguns caracteres Unicode e isso faria o servidor quebrar. No entanto, se a conexão HTTP foi criada com o cabeçalho Connection: keep-alive
, o corpo da requisição não será lido e a conexão ainda estará aberta, então o corpo da requisição será tratado como a próxima requisição HTTP.
Abusando de cabeçalhos hop-by-hop, você poderia indicar ao proxy para deletar o cabeçalho Content-Length ou Transfer-Encoding para que um HTTP request smuggling seja possível de abusar.
Para mais informações sobre cabeçalhos hop-by-hop visite:
hop-by-hop headersIdentificar vulnerabilidades de HTTP request smuggling pode frequentemente ser alcançado usando técnicas de temporização, que dependem da observação de quanto tempo leva para o servidor responder a solicitações manipuladas. Essas técnicas são particularmente úteis para detectar vulnerabilidades CL.TE e TE.CL. Além desses métodos, existem outras estratégias e ferramentas que podem ser usadas para encontrar tais vulnerabilidades:
Método:
Enviar uma solicitação que, se a aplicação for vulnerável, fará com que o servidor back-end aguarde dados adicionais.
Exemplo:
Observação:
O servidor front-end processa a solicitação com base em Content-Length
e corta a mensagem prematuramente.
O servidor back-end, esperando uma mensagem em partes, aguarda o próximo pedaço que nunca chega, causando um atraso.
Indicadores:
Timeouts ou longos atrasos na resposta.
Recebendo um erro 400 Bad Request do servidor back-end, às vezes com informações detalhadas do servidor.
Método:
Enviar uma solicitação que, se a aplicação for vulnerável, fará com que o servidor back-end aguarde dados adicionais.
Exemplo:
Observação:
O servidor front-end processa a solicitação com base em Transfer-Encoding
e encaminha toda a mensagem.
O servidor back-end, esperando uma mensagem com base em Content-Length
, aguarda dados adicionais que nunca chegam, causando um atraso.
Análise de Resposta Diferencial:
Enviar versões ligeiramente variadas de uma solicitação e observar se as respostas do servidor diferem de uma maneira inesperada, indicando uma discrepância de análise.
Usando Ferramentas Automatizadas:
Ferramentas como a extensão 'HTTP Request Smuggler' do Burp Suite podem testar automaticamente essas vulnerabilidades enviando várias formas de solicitações ambíguas e analisando as respostas.
Testes de Variação de Content-Length:
Enviar solicitações com valores de Content-Length
variados que não estão alinhados com o comprimento real do conteúdo e observar como o servidor lida com tais incompatibilidades.
Testes de Variação de Transfer-Encoding:
Enviar solicitações com cabeçalhos Transfer-Encoding
ofuscados ou malformados e monitorar como os servidores front-end e back-end respondem de maneira diferente a tais manipulações.
Após confirmar a eficácia das técnicas de temporização, é crucial verificar se as solicitações do cliente podem ser manipuladas. Um método simples é tentar envenenar suas solicitações, por exemplo, fazendo uma solicitação para /
resultar em uma resposta 404. Os exemplos CL.TE
e TE.CL
discutidos anteriormente em Exemplos Básicos demonstram como envenenar a solicitação de um cliente para provocar uma resposta 404, apesar de o cliente estar tentando acessar um recurso diferente.
Considerações Chave
Ao testar vulnerabilidades de request smuggling interferindo em outras solicitações, tenha em mente:
Conexões de Rede Distintas: As solicitações "ataque" e "normais" devem ser enviadas por conexões de rede separadas. Utilizar a mesma conexão para ambas não valida a presença da vulnerabilidade.
URL e Parâmetros Consistentes: Procure usar URLs e nomes de parâmetros idênticos para ambas as solicitações. Aplicações modernas frequentemente roteiam solicitações para servidores back-end específicos com base em URL e parâmetros. Correspondendo a esses aumenta a probabilidade de que ambas as solicitações sejam processadas pelo mesmo servidor, um pré-requisito para um ataque bem-sucedido.
Condições de Temporização e Corrida: A solicitação "normal", destinada a detectar interferência da solicitação "ataque", compete contra outras solicitações de aplicação concorrentes. Portanto, envie a solicitação "normal" imediatamente após a solicitação "ataque". Aplicações ocupadas podem exigir várias tentativas para confirmação conclusiva da vulnerabilidade.
Desafios de Balanceamento de Carga: Servidores front-end atuando como balanceadores de carga podem distribuir solicitações entre vários sistemas back-end. Se as solicitações "ataque" e "normais" acabarem em sistemas diferentes, o ataque não terá sucesso. Esse aspecto de balanceamento de carga pode exigir várias tentativas para confirmar uma vulnerabilidade.
Impacto Não Intencional no Usuário: Se seu ataque impactar inadvertidamente a solicitação de outro usuário (não a solicitação "normal" que você enviou para detecção), isso indica que seu ataque influenciou outro usuário da aplicação. Testes contínuos podem interromper outros usuários, exigindo uma abordagem cautelosa.
Às vezes, proxies front-end impõem medidas de segurança, examinando solicitações de entrada. No entanto, essas medidas podem ser contornadas explorando HTTP Request Smuggling, permitindo acesso não autorizado a endpoints restritos. Por exemplo, acessar /admin
pode ser proibido externamente, com o proxy front-end bloqueando ativamente tais tentativas. No entanto, esse proxy pode negligenciar inspecionar solicitações embutidas dentro de uma solicitação HTTP contrabandeada, deixando uma brecha para contornar essas restrições.
Considere os seguintes exemplos que ilustram como HTTP Request Smuggling pode ser usado para contornar controles de segurança do front-end, especificamente visando o caminho /admin
, que geralmente é protegido pelo proxy front-end:
Exemplo CL.TE
No ataque CL.TE, o cabeçalho Content-Length
é utilizado para a solicitação inicial, enquanto a solicitação incorporada subsequente utiliza o cabeçalho Transfer-Encoding: chunked
. O proxy de front-end processa a solicitação POST
inicial, mas falha em inspecionar a solicitação incorporada GET /admin
, permitindo acesso não autorizado ao caminho /admin
.
TE.CL Exemplo
Por outro lado, no ataque TE.CL, a solicitação inicial POST
usa Transfer-Encoding: chunked
, e a solicitação incorporada subsequente é processada com base no cabeçalho Content-Length
. Semelhante ao ataque CL.TE, o proxy de front-end ignora a solicitação GET /admin
contrabandeada, concedendo inadvertidamente acesso ao caminho restrito /admin
.
As aplicações frequentemente utilizam um servidor de front-end para modificar solicitações recebidas antes de passá-las para o servidor de back-end. Uma modificação típica envolve a adição de cabeçalhos, como X-Forwarded-For: <IP do cliente>
, para relatar o IP do cliente ao back-end. Compreender essas modificações pode ser crucial, pois pode revelar maneiras de contornar proteções ou descobrir informações ou endpoints ocultos.
Para investigar como um proxy altera uma solicitação, localize um parâmetro POST que o back-end ecoa na resposta. Em seguida, elabore uma solicitação, usando este parâmetro por último, semelhante ao seguinte:
Nesta estrutura, os componentes de solicitação subsequentes são anexados após search=
, que é o parâmetro refletido na resposta. Essa reflexão exporá os cabeçalhos da solicitação subsequente.
É importante alinhar o cabeçalho Content-Length
da solicitação aninhada com o comprimento real do conteúdo. Começar com um valor pequeno e aumentar gradualmente é aconselhável, pois um valor muito baixo truncará os dados refletidos, enquanto um valor muito alto pode causar um erro na solicitação.
Essa técnica também é aplicável no contexto de uma vulnerabilidade TE.CL, mas a solicitação deve terminar com search=\r\n0
. Independentemente dos caracteres de nova linha, os valores serão anexados ao parâmetro de busca.
Este método serve principalmente para entender as modificações na solicitação feitas pelo proxy de front-end, essencialmente realizando uma investigação autodirigida.
É viável capturar as solicitações do próximo usuário anexando uma solicitação específica como o valor de um parâmetro durante uma operação POST. Veja como isso pode ser realizado:
Ao anexar a seguinte solicitação como o valor de um parâmetro, você pode armazenar a solicitação do cliente subsequente:
Neste cenário, o parâmetro de comentário destina-se a armazenar o conteúdo na seção de comentários de um post em uma página acessível publicamente. Consequentemente, o conteúdo da solicitação subsequente aparecerá como um comentário.
No entanto, essa técnica tem limitações. Geralmente, ela captura dados apenas até o delimitador de parâmetro usado na solicitação contrabandeada. Para envios de formulários codificados em URL, esse delimitador é o caractere &
. Isso significa que o conteúdo capturado da solicitação do usuário vítima parará no primeiro &
, que pode até fazer parte da string de consulta.
Além disso, vale a pena notar que essa abordagem também é viável com uma vulnerabilidade TE.CL. Nesses casos, a solicitação deve terminar com search=\r\n0
. Independentemente dos caracteres de nova linha, os valores serão anexados ao parâmetro de busca.
HTTP Request Smuggling pode ser aproveitado para explorar páginas da web vulneráveis a XSS Refletido, oferecendo vantagens significativas:
A interação com os usuários-alvo não é necessária.
Permite a exploração de XSS em partes da solicitação que são normalmente inalcançáveis, como cabeçalhos de solicitação HTTP.
Em cenários onde um site é suscetível a XSS Refletido através do cabeçalho User-Agent, a seguinte carga útil demonstra como explorar essa vulnerabilidade: