Contrabando de solicitação HTTP - novas abordagens

Em 7 de outubro de 2019, o diretor de pesquisa da PortSwigger (produtor do BurpSuite) publicou um estudo sobre novas abordagens ao contrabando de solicitações HTTP. Com a ajuda deles, ele ganhou cerca de US $ 70.000 em recompensas. Neste artigo, descobrimos brevemente a essência do ataque, ferramentas e também métodos de pesquisa de servidores Web vulneráveis ​​a essa vulnerabilidade.


O que é contrabando de solicitação HTTP


Contrabando de solicitação HTTP - um ataque destinado a dessincronizar o frontend do servidor web e o backend do servidor web, como resultado do qual o invasor pode contrabandear uma solicitação HTTP além do servidor frontend. A imagem do artigo original serve como uma boa demonstração:


imagem


Esse ataque pode levar a várias conseqüências - a introdução do XSS na sessão de outros usuários, redirecionando os usuários para recursos de terceiros, envenenando o cache do servidor, similaridade ao SSRF e vários outros.


Na encarnação de contrabando de 2019, James Kettle explorou o processamento incorreto de cabeçalhos de servidores da web


Transfer-Encoding: chunked 

indicando que o corpo da mensagem será transmitido em partes ( RFC ). Devido ao fato de que alguns servidores da Web não suportam transmissão fragmentada ou manipulam o cabeçalho de maneira diferente, o front-end irá "ver" apenas uma solicitação e o back-end a reconhecerá como duas. Mais detalhes sobre os detalhes do ataque podem ser encontrados no artigo original . Há também uma tarefa prática na qual você pode praticar para encontrar a vulnerabilidade manualmente.


Para uma pesquisa rápida, James desenvolveu um plug-in para o BurpSuit, que recebe uma solicitação de entrada e cria uma observação sobre a vulnerabilidade do serviço (se houver) na saída.


Exemplos de servidores Web vulneráveis


Devo dizer que o problema do contrabando e outras vulnerabilidades relacionadas ao funcionamento dos servidores da web há muito tempo são tratados por outro pesquisador sob o apelido regilero . Nos últimos três anos, ele publicou três artigos que descrevem as vulnerabilidades encontradas em servidores Web populares, a maioria dos quais recebem CVEs de média e alta criticidade. Entre os servidores vulneráveis ​​estão o Apache Traffic Server, Jetty, Apsis.


Na esteira do interesse no problema, outro pesquisador, Nathan Davison, descobriu uma vulnerabilidade no HAProxy, que ignorou um cabeçalho formado incorretamente.


 Transfer-Encoding:[\x0b]chunked 

e o converteu no seguinte formato:


 Transfer-Encoding: chunked 

Mas o servidor back-end - gunicorn, executando proxy do aplicativo no Flask, leu o cabeçalho, o que provocou a vulnerabilidade.


Um pouco mais tarde, vários outros pesquisadores descobriram uma vulnerabilidade (atribuída a CVE-2019-16276) na implementação do servidor http golang - o servidor normalizava o cabeçalho se houvesse um espaço antes do prelet.
Pedido:


imagem


Após o processamento pelo servidor:


imagem


A vulnerabilidade poderia ser explorada se o servidor front-end ignorasse o cabeçalho com um espaço e usasse o Comprimento do conteúdo para calcular o tamanho da solicitação.


O servidor da web Caddy, escrito em Go, também era vulnerável porque usava a mesma biblioteca de rede / http. Os desenvolvedores confirmaram que, após atualizar o GO e reconstruir o pacote, o problema desaparece.


O autor deste artigo encontrou um problema semelhante no servidor lighthttpd (nenhum CVE foi atribuído). A captura de tela mostra que o servidor aceita e processa o cabeçalho que contém um espaço:


imagem


Os desenvolvedores não concordam totalmente com a RFC 7230 (e o autor também) e acreditam que a responsabilidade pelo processamento incorreto de cabeçalhos recai sobre proxies que encaminham solicitações sem normalizá-las e verificá-las. No entanto, o bug será corrigido na nova versão:


Por padrão, o lighttpd analisa (e normaliza) solicitações antes de fazer o proxy reverso delas para back-end. Isso impede os ataques mencionados em https://portswigger.net/research/http-desync-attacks-request-smuggling-reborn para servidores a montante do lighttpd.
No entanto, como mencionado por stbuehler acima, os proxies a jusante do lighttpd podem passar qualquer coisa para o lighttpd.
A alteração que será feita na próxima versão do lighttpd será rejeitar solicitações com espaço ou tab após o nome do campo e antes dos dois pontos, mas somente quando o lighttpd estiver configurado no modo (padrão) de análise estrita do cabeçalho http.

O mesmo bug foi encontrado no servidor web cheroot usado pela estrutura cherrypy. Essa mini-estrutura é encontrada em startups, geralmente é usada para escrever APIs. O relatório de erro trava no status aberto.


Condições necessárias e suficientes para a vulnerabilidade


Portanto, quais são as condições necessárias para verificar e explorar a vulnerabilidade:


  • Pedido POST. Embora o RFC não proíba explicitamente o uso de cabeçalhos Content-Length e Transfer-Encoding para solicitações GET, na verdade eles são usados ​​apenas em solicitações POST.
  • A presença de servidores front-end e back-end - se não houver, não haverá nada para sincronizar.
  • Os servidores da Web devem analisar o cabeçalho de codificação de transferência de maneira diferente, ou seja, é preciso "lê-lo" e o segundo deve ser ignorado.

Testes laboratoriais


Para um melhor entendimento e solução de problemas em servidores e proxies da Web existentes, é aconselhável implantar um ambiente de teste localmente usando o Docker.


Um exemplo de um diagrama do ambiente de teste:


imagem


Código da aplicação:


 from flask import Flask, request, jsonify app = Flask(__name__) @app.route('/', methods=['GET', 'POST']) def main(): # the next line is required for Transfer-Encoding support in the request request.environ['wsgi.input_terminated'] = True headers = {} for header in request.headers: headers[header[0]] = header[1] print (request.data) print (headers) return jsonify(body=str(request.data), headers=headers) 

Arquivo com configurações de front-end, por exemplo, caddy:


 localhost:80 log ../access.log proxy / host.docker.internal:8888 

Então tudo é simples, execute o aplicativo:


 gunicorn --keep-alive 10 -k gevent --bind 0.0.0.0:8888 -w 4 backend:app 

E recipiente:


 docker run -d -t --name caddy -p 80:80 -p 443:443 -v /Users/sun/work/caddyfile:/etc/Caddyfile abiosoft/caddy:latest 

Na loja Burp, instalamos o HTTP Request Smuggler e o Logger ++ para facilitar a depuração. Em seguida, no Repeater, formamos uma solicitação simples, por exemplo:


 POST / HTTP/1.1 Host: localhost Content-Length: 8 Connection: close body=123 

E envie-o para verificar se tudo está configurado corretamente:


 HTTP/1.1 200 OK Content-Length: 202 Content-Type: application/json Date: Mon, 07 Oct 2019 13:17:18 GMT Server: Caddy Server: gunicorn/19.9.0 Connection: close {"body":"b'body=123'","headers":{"Accept-Encoding":"gzip","Connection":"close","Content-Length":"8","Host":"host.docker.internal:8888","User-Agent":"Go-http-client/1.1","X-Forwarded-For":"172.17.0.1"}} 

Agora inicie o Launch Smuggle Probe e veja as respostas.


imagem


O mais interessante começa neste momento. É necessário analisar solicitações e respostas para entender se os serviços são vulneráveis ​​ou não. Esta parte é deixada para o leitor curioso.

Source: https://habr.com/ru/post/pt468489/


All Articles