HTTP Request Schmuggel - neue Ansätze

Am 7. Oktober 2019 veröffentlichte der PortSwigger Research Director (BurpSuite-Hersteller) eine Studie zu neuen Ansätzen für den Schmuggel von HTTP-Anfragen. Mit ihrer Hilfe verdiente er ungefähr 70.000 Dollar mit Bugbounty. In diesem Artikel werden kurz die Grundlagen des Angriffs, die Tools und auch die Methoden zur Untersuchung von Webservern erläutert, die für diese Sicherheitsanfälligkeit anfällig sind.


Was ist HTTP-Anforderungsschmuggel?


Schmuggel von HTTP-Anforderungen - Ein Angriff, der darauf abzielt, das Frontend des Webservers und das Backend des Webservers zu desynchronisieren, wodurch der Angreifer eine HTTP-Anforderung über den Frontend-Server hinweg schmuggeln kann. Das Bild aus dem Originalartikel dient als gute Demonstration:


Bild


Ein solcher Angriff kann zu einer Reihe von Konsequenzen führen - der Einführung von XSS in der Sitzung anderer Benutzer, der Umleitung von Benutzern zu Ressourcen von Drittanbietern, der Vergiftung des Server-Cache, der Ähnlichkeit mit SSRF und einer Reihe anderer.


In der Smuggling Incarnation 2019 von 2019 nutzte James Kettle die falsche Verarbeitung von Webserver-Headern aus


Transfer-Encoding: chunked 

Dies zeigt an, dass der Nachrichtentext in Teilen ( RFC ) übertragen wird. Aufgrund der Tatsache, dass einige Webserver keine Chunked-Übertragung unterstützen oder den Header anders behandeln, „sieht“ das Frontend nur eine Anforderung und das Backend erkennt sie als zwei. Weitere Details zu den Angriffsdetails finden Sie im Originalartikel . Es gibt auch eine praktische Aufgabe, bei der Sie üben können, die Sicherheitsanfälligkeit manuell zu finden.


Für eine schnelle Suche hat James ein Plug-In für BurpSuit entwickelt, das eine Eingabeaufforderung empfängt und einen Hinweis auf die Sicherheitsanfälligkeit des Dienstes (falls vorhanden) an der Ausgabe erstellt.


Beispiele für anfällige Webserver


Ich muss sagen, dass das Problem des Schmuggels und anderer Schwachstellen im Zusammenhang mit dem Betrieb von Webservern seit langem von einem anderen Forscher unter dem Spitznamen regilero behandelt wurde . In den letzten drei Jahren hat er drei Artikel veröffentlicht, in denen die Schwachstellen beschrieben werden, die er in beliebten Webservern gefunden hat, von denen die meisten CVEs mit mittlerer und hoher Kritikalität zugewiesen sind. Zu den anfälligen Servern gehören Apache Traffic Server, Jetty und Apsis.


Im Zuge des Interesses an dem Problem entdeckte ein anderer Forscher, Nathan Davison, eine Sicherheitslücke in HAProxy, die einen falsch geformten Header ignorierte.


 Transfer-Encoding:[\x0b]chunked 

und konvertierte es in die folgende Form:


 Transfer-Encoding: chunked 

Aber der Backend-Server - gunicorn, der die Anwendung auf Flask vertrat, las den Header, der die Sicherheitslücke provozierte.


Wenig später entdeckten eine Reihe anderer Forscher eine Sicherheitsanfälligkeit (CVE-2019-16276 zugewiesen) bei der Implementierung des Golang-HTTP-Servers. Der Server normalisierte den Header, wenn vor dem Prelet ein Leerzeichen vorhanden war.
Anfrage:


Bild


Nach der Verarbeitung durch den Server:


Bild


Die Sicherheitsanfälligkeit könnte ausgenutzt werden, wenn der Frontend-Server den Header mit einem Leerzeichen ignoriert und Content-Length verwendet, um die Größe der Anforderung zu berechnen.


Der in Go geschriebene Caddy-Webserver war ebenfalls anfällig, da er dieselbe net / http-Bibliothek verwendete. Die Entwickler haben bestätigt, dass das Problem nach dem Aktualisieren von GO und dem erneuten Erstellen des Pakets verschwindet.


Der Autor dieses Artikels hat ein ähnliches Problem auf dem lighthttpd-Server festgestellt (es wurde kein CVE zugewiesen). Der Screenshot zeigt, dass der Server den Header mit einem Leerzeichen akzeptiert und verarbeitet:


Bild


Die Entwickler stimmen RFC 7230 (und auch dem Autor) nicht ganz zu und sind der Ansicht, dass die Verantwortung für die fehlerhafte Verarbeitung von Headern bei Proxys liegt, die Anforderungen weiterleiten, ohne sie zu normalisieren und zu überprüfen. Der Fehler wird jedoch in der neuen Version behoben:


Standardmäßig analysiert (und normalisiert) lighttpd Anforderungen, bevor sie an Backends weitergeleitet werden. Dies vereitelt die in https://portswigger.net/research/http-desync-attacks-request-smuggling-reborn genannten Angriffe auf Server, die von lighttpd vorgelagert sind.
Wie oben von stbuehler erwähnt, können Proxys stromabwärts von lighttpd jedoch alles an lighttpd übergeben.
Die Änderung, die in der nächsten Version von lighttpd vorgenommen wird, besteht darin, Anforderungen mit Leerzeichen oder Tabulatoren nach dem Feldnamen und vor dem Doppelpunkt abzulehnen, jedoch nur, wenn lighttpd im (Standard-) Modus der strengen Analyse von http-Headern konfiguriert ist.

Der gleiche Fehler wurde auf dem Cheroot-Webserver gefunden, der vom Cherrypy-Framework verwendet wird. Dieses Mini-Framework befindet sich in Startups und wird häufig zum Schreiben von APIs verwendet. Der Fehlerbericht bleibt im geöffneten Status.


Notwendige und ausreichende Bedingungen für die Verwundbarkeit


Was sind also die notwendigen Bedingungen, um die Sicherheitsanfälligkeit zu überprüfen und auszunutzen:


  • POST-Anfrage. Obwohl der RFC die Verwendung von Headern für Inhaltslänge und Übertragungscodierung für GET-Anforderungen nicht ausdrücklich verbietet, werden sie tatsächlich nur in POST-Anforderungen verwendet.
  • Das Vorhandensein von Frontend- und Backend-Servern - wenn keine vorhanden sind, muss nichts synchronisiert werden.
  • Webserver müssen den Transfer-Encoding-Header anders analysieren, dh man muss ihn "lesen" und der zweite sollte ignoriert werden.

Labortests


Zum besseren Verständnis und zur Fehlerbehebung in vorhandenen Webservern und Proxys ist es ratsam, eine Testumgebung lokal mit Docker bereitzustellen.


Ein Beispiel für ein Testumgebungsdiagramm:


Bild


Anwendungscode:


 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) 

Datei mit Frontend-Einstellungen, zum Beispiel Caddy:


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

Dann ist alles einfach, führen Sie die Anwendung aus:


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

Und Container:


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

Aus dem Burp Store installieren wir HTTP Request Smuggler und Logger ++, um das Debuggen zu vereinfachen. Als nächstes bilden wir in Repeater eine einfache Anfrage, zum Beispiel diese:


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

Und senden Sie es, um zu überprüfen, ob alles richtig konfiguriert ist:


 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"}} 

Starten Sie nun Launch Smuggle Probe und sehen Sie sich die Antworten an.


Bild


Das interessanteste beginnt in diesem Moment. Es ist erforderlich, Anforderungen und Antworten zu analysieren, um zu verstehen, ob Dienste anfällig sind oder nicht. Dieser Teil bleibt dem neugierigen Leser überlassen.

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


All Articles