
Framework de testes diferenciais para implementações HTTP
O HTTP Garden é uma coleção de servidores e proxies HTTP configurados para serem combináveis, juntamente com scripts para interagir com eles de uma forma que torna a descoberta de vulnerabilidades muito, muito mais fácil. Para ver algumas demonstrações interessantes das vulnerabilidades que você pode encontrar com o HTTP Garden, confira nossa palestra no ShmooCon 2024.
Gostaríamos de agradecer aos nossos amigos da Galois, da Trail of Bits, da Narf Industries e do Dartmouth College por tornar este projeto possível.
Este material é baseado em trabalho apoiado pela Defense Advanced Research Projects Agency (DARPA) sob o número de contrato HR0011-19-C-0076.
pip) ou do gerenciador de pacotes do seu sistema:docker
pyyaml
tqdm
Se você estiver instalando pacotes Python com o gerenciador de pacotes do seu sistema, lembre-se de que os nomes dos pacotes podem precisar ser prefixados com py3-, python3- ou python-, dependendo do sistema.
./garden.sh start --build gunicorn hyper nginx haproxy
./garden.sh repl
garden> payload 'GET / HTTP/1.1\r\nHOST: a\r\n\r\n' | transduce haproxy | fanout | grid
'GET / HTTP/1.1\r\nHOST: a\r\n\r\n'
⬇️ haproxy
'GET / HTTP/1.1\r\nhost: a\r\n\r\n'
gunicorn: [
HTTPRequest(
method=b'GET', uri=b'/', version=b'1.1',
headers=[
(b'host', b'a'),
],
body=b'',
),
]
hyper: [
HTTPRequest(
method=b'GET', uri=b'/', version=b'1.1',
headers=[
(b'host', b'a'),
],
body=b'',
),
]
nginx: [
HTTPRequest(
method=b'GET', uri=b'/', version=b'1.1',
headers=[
(b'host', b'a'),
(b'content-length', b''),
(b'content-type', b''),
],
body=b'',
),
]
g
u
n
i h n
c y g
o p i
r e n
n r x
+-----
gunicorn|✓ ✓ ✓
hyper | ✓ ✓
nginx | ✓
Parece que todos concordam. (Observe que, embora o Nginx tenha adicionado os cabeçalhos content-length e content-type, o Garden está ciente disso e não deixa essa discrepância insignificante aparecer na saída de grid.)
Vamos tentar um payload que usa uma terminação de linha com LF simples em um corpo de mensagem chunked. Isso é proibido pela especificação.
garden> payload 'POST / HTTP/1.1\r\nHost: a\r\nTransfer-Encoding: chunked\r\n\r\n0\n\r\n' | fanout | grid
gunicorn: [
HTTPResponse(version=b'1.1', method=b'400', reason=b'Bad Request'),
]
hyper: [
]
nginx: [
HTTPRequest(
method=b'POST', uri=b'/', version=b'1.1',
headers=[
(b'transfer-encoding', b'chunked'),
(b'host', b'a'),
(b'content-length', b'0'),
(b'content-type', b''),
],
body=b'',
),
]
g
u
n
i h n
c y g
o p i
r e n
n r x
+-----
gunicorn|✓ ✓ X
hyper | ✓ X
nginx | ✓
Ok, então o Gunicorn respondeu 400, o Hyper não respondeu e o Nginx aceitou. Isso é uma violação da especificação pelos autores do Nginx que eles não se importam em corrigir.
Você também deve ter notado que, embora o Gunicorn e o Hyper não tenham tido exatamente a mesma resposta, eles apareceram como concordantes na saída de grid anteriormente. Isso ocorre porque suas respostas são essencialmente equivalentes (uma rejeição da mensagem), e o Garden leva isso em consideração.
imagesO diretório images contém um subdiretório para cada servidor HTTP e transdutor do Garden. Cada alvo recebe sua própria imagem Docker. Todos os programas são compilados a partir do código-fonte quando possível. Para que possamos facilmente compilar várias versões de cada alvo, todos os alvos são parametrizados com uma URL de repositório (APP_REPO), nome do branch (APP_BRANCH) e hash de commit (APP_VERSION).
toolsO diretório tools contém os scripts usados para interagir com os servidores. Dentro dele, você encontrará
probe_quirks.py: Um script para enumerar peculiaridades benignas de análise HTTP nos sistemas em teste que devem ser ignoradas durante o fuzzing,repl.py: A interface principal do usuário com o HTTP Garden,update.py: Um script para atualizar os hashes de commit em docker-compose.yml,|-| | aiohttp | | apache_httpd | | apache_tomcat | | appweb | | aws_c_http | | cpp_httplib | | eclipse_grizzly | | eclipse_jetty | | fasthttp | | go_stdlib | | gunicorn | | h2o | | haproxy_fcgi | | hyper | | hypercorn | | ktor | | libevent | | libmicrohttpd | | libsoup | | lighttpd | | mongoose | | netty | | nginx | | node_stdlib | | openbsd_httpd | | openlitespeed | | openwrt_uhttpd | | protocol_http1 | | puma | | tornado | | | | | | | | | | | | |
|-| | apache_httpd_proxy | | apache_traffic_server | | envoy | | go_stdlib_proxy | | h2o_proxy | | haproxy | | lighttpd_proxy | | nghttpx | | nginx_proxy | | openlitespeed_proxy | | pound | | squid | | varnish | | yahns_proxy |
A seguir estão as explicações para algumas omissões notáveis do Garden:
Consulte TROPHIES.md para obter uma lista completa de bugs que o Garden encontrou.
| Nome | Justificativa |
|---|
| Qualquer coisa da Microsoft | A MSRC nos disse que "HTTP smuggling não é considerado uma vulnerabilidade", e não sinto nenhuma necessidade especial de ajudar a Microsoft. |
| unicorn | Usa o mesmo analisador HTTP que o yahns. |
| SwiftNIO | Usa llhttp para análise HTTP, que já é coberto por node_stdlib. |
| Bun | Usa picohttpparser para análise HTTP, que já é coberto por h2o. |
| Deno | Usa hyper para análise HTTP, que já está no Garden. |
| Daphne | Usa twisted para análise HTTP, que já está no Garden. |
| pitchfork | Usa o mesmo analisador que o yahns. |
| nghttpx | Usa lhttp para análise HTTP, que já é coberto por node_stdlib. |
| Cheroot | Ignora nossos relatórios. |
| CherryPy | Usa cheroot para análise HTTP. |
| libhttpserver | Usa libmicrohttpd para análise HTTP, que já está no Garden. |
| Werkzeug | Usa a stdlib do CPython para análise HTTP, que já está no Garden. |
| Caddy | Usa a stdlib do Go para análise HTTP, que já está no Garden. |
| Tengine | Usa o analisador HTTP do Nginx. |
| OpenResty | Usa o analisador HTTP do Nginx. |
| Google Cloud Global External Application Load Balancer | Baseado no Envoy. |
| Google Cloud Regional External Application Load Balancer | Baseado no Envoy. |
| Phusion Passenger | Usa llhttpd para análise HTTP, que já é coberto por node_stdlib. |
| passim | Usa libsoup para análise HTTP, que já está no Garden. |
| boa | Não mantido. |
| Ulfius | Usa libmicrohttpd, que já está no Garden. |
| Vultr Load Balancer | É apenas HAProxy, que já está no Garden. |
| VMWare Avi Load Balancer | É apenas Nginx, que já está no Garden. |
| Sanic | Usa httptools, que já é coberto pelo Uvicorn. |
| CPython http.server | Não foi feito para uso em produção. |
| openjdk_stdlib | Não oferece um canal coerente de divulgação de vulnerabilidades. |
| dart_stdlib | Ignorou relatórios anteriores. |
| eventlet | A biblioteca HTTP é apenas um fork daquela presente na stdlib do CPython. |
| uwsgi | Não suporta corpos de mensagem chunked. |