
Differential-Test-Framework für HTTP-Implementierungen
The HTTP Garden ist eine Sammlung von HTTP-Servern und -Proxys, die so konfiguriert sind, dass sie kombinierbar sind, zusammen mit Skripten, die die Interaktion mit ihnen erheblich erleichtern und das Auffinden von Schwachstellen viel einfacher machen. Für coole Demos der Schwachstellen, die du mit dem HTTP Garden finden kannst, schau dir unseren ShmooCon-2024-Vortrag an.
Wir möchten uns bei unseren Freunden von Galois, Trail of Bits, Narf Industries und Dartmouth College bedanken, die dieses Projekt ermöglicht haben.
Dieses Material basiert auf Arbeiten, die von der Defense Advanced Research Projects Agency (DARPA) im Rahmen des Vertrags HR0011-19-C-0076 unterstützt wurden.
pip) oder über deinen Systempaketmanager beziehen kannst:docker
pyyaml
tqdm
Wenn du Python-Pakete mit deinem Systempaketmanager installierst, beachte, dass die Paketnamen je nach System möglicherweise mit py3-, python3- oder python- präfigiert werden müssen.
./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 | ✓
Es scheint, als wären sie sich alle einig. (Beachte, dass der Garden dies bemerkt, obwohl Nginx content-length- und content-type-Header hinzugefügt hat, und nicht zulässt, dass diese unbedeutende Abweichung in der grid-Ausgabe erscheint.)
Probieren wir ein Payload, das in einem Chunked-Message-Body eine nackte LF-Zeilenendung verwendet. Das ist in der Spezifikation nicht erlaubt.
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 | ✓
Okay, Gunicorn hat also mit 400 geantwortet, Hyper hat nicht geantwortet und Nginx hat akzeptiert. Dies ist ein Verstoß gegen die Spezifikation durch die Nginx-Autoren, den sie nicht beheben wollen.
Dir ist vielleicht auch aufgefallen, dass Gunicorn und Hyper in der grid-Ausgabe zuvor als übereinstimmend angezeigt wurden, obwohl sie nicht genau dieselbe Antwort hatten.
Das liegt daran, dass ihre Antworten im Wesentlichen äquivalent sind (eine Ablehnung der Nachricht), und der Garden berücksichtigt dies.
imagesDas Verzeichnis images enthält ein Unterverzeichnis für jeden HTTP-Server und jeden Transducer im Garden.
Jedes Ziel erhält ein eigenes Docker-Image.
Alle Programme werden nach Möglichkeit aus dem Quellcode gebaut.
Damit wir einfach mehrere Versionen jedes Ziels bauen können, sind alle Ziele mit einer Repository-URL (APP_REPO), einem Branchnamen (APP_BRANCH) und einem Commit-Hash (APP_VERSION) parametrisiert.
toolsDas Verzeichnis tools enthält die Skripte, die für die Interaktion mit den Servern verwendet werden. Darin findest du
probe_quirks.py: Ein Skript zum Auflisten harmloser HTTP-Parsing-Eigenheiten in den getesteten Systemen, die während des Fuzzings ignoriert werden sollen,repl.py: Die primäre Benutzeroberfläche des HTTP Garden,update.py: Ein Skript zum Aktualisieren der Commit-Hashes in 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 |
Im Folgenden findest du Erklärungen für einige bemerkenswerte Auslassungen im Garden:
Siehe TROPHIES.md für eine vollständige Liste der Bugs, die der Garden gefunden hat.
| Name | Begründung |
|---|
| Alles von Microsoft | Das MSRC hat uns gesagt, „HTTP-Smuggling wird nicht als Schwachstelle betrachtet“, und ich verspüre kein besonderes Bedürfnis, Microsoft zu helfen. |
| unicorn | Verwendet denselben HTTP-Parser wie yahns. |
| SwiftNIO | Verwendet llhttp für das HTTP-Parsing, das bereits von node_stdlib abgedeckt wird. |
| Bun | Verwendet picohttpparser für das HTTP-Parsing, das bereits von h2o abgedeckt wird. |
| Deno | Verwendet hyper für das HTTP-Parsing, das bereits im Garden enthalten ist. |
| Daphne | Verwendet twisted für das HTTP-Parsing, das bereits im Garden enthalten ist. |
| pitchfork | Verwendet denselben Parser wie yahns. |
| nghttpx | Verwendet lhttp für das HTTP-Parsing, das bereits von node_stdlib abgedeckt wird. |
| Cheroot | Ignoriert unsere Meldungen. |
| CherryPy | Verwendet cheroot für das HTTP-Parsing. |
| libhttpserver | Verwendet libmicrohttpd für das HTTP-Parsing, das bereits im Garden enthalten ist. |
| Werkzeug | Verwendet die CPython-Standardbibliothek für das HTTP-Parsing, die bereits im Garden enthalten ist. |
| Caddy | Verwendet die Go-Standardbibliothek für das HTTP-Parsing, die bereits im Garden enthalten ist. |
| Tengine | Verwendet den HTTP-Parser von Nginx. |
| OpenResty | Verwendet den HTTP-Parser von Nginx. |
| Google Cloud Global External Application Load Balancer | Basiert auf Envoy. |
| Google Cloud Regional External Application Load Balancer | Basiert auf Envoy. |
| Phusion Passenger | Verwendet llhttpd für das HTTP-Parsing, das bereits von node_stdlib abgedeckt wird. |
| passim | Verwendet libsoup für das HTTP-Parsing, das bereits im Garden enthalten ist. |
| boa | Nicht mehr gewartet. |
| Ulfius | Verwendet libmicrohttpd, das bereits im Garden enthalten ist. |
| Vultr Load Balancer | Das ist einfach HAProxy, das bereits im Garden enthalten ist. |
| VMWare Avi Load Balancer | Das ist einfach Nginx, das bereits im Garden enthalten ist. |
| Sanic | Verwendet httptools, das bereits von Uvicorn abgedeckt wird. |
| CPython http.server | Nicht für den Produktionseinsatz gedacht. |
| openjdk_stdlib | Bietet keinen kohärenten Kanal für die Offenlegung von Schwachstellen. |
| dart_stdlib | Hat frühere Meldungen ignoriert. |
| eventlet | Die HTTP-Bibliothek ist nur ein Fork derjenigen in der CPython-Standardbibliothek. |
| uwsgi | Unterstützt keine Chunked-Message-Bodies. |