In dieser Woche geht es um weitere Möglichkeiten des HTTP-Request-Smuggling. Wir betrachten dabei das Request Hijacking und in einem zweiten Schritt das Request Credential Hijacking.
Request Hijacking
Beim Request Hijacking wird eine Cross-Site-Scripting-Schwachstelle in
einer Webanwendung ausgenutzt, um einen dem Cross-Site Scripting
ähnlichen Angriff durchzuführen. Voraussetzung für derartige
Angriffe ist ein Proxy-Server zwischen Client und Webserver. Im Gegensatz
zum Vergiften des Web-Caches wie in About Security #17 muss der Proxy-Server
jedoch nicht cachen.
Im folgenden Beispiel (nach [1, PDF] ) sei der Parameter
'daten' der Seite /verwundbar.jsp einer
Webanwendung anfällig für Cross-Site Scripting.
1 POST /irgendwas.jsp HTTP/1.0
2 Connection: Keep-Alive
3 Content-Type: application/x-www-form-urlencoded
4 Content-Length: 10
5 Content-Length: 195
6
7 ist=nichtsPOST /verwundbar.jsp HTTP/1.0
8 Content-Type: application/x-www-form-urlencoded
9 Content-Length: 85
10
11 parameter1=wert1&daten=<script>alert("Datenklau:"
%2bdocument.cookie)</script>&muell=
[Zeile 11 ist dabei, wie auch bei späteren Beispielen, eine einzige
Zeile. Der Umbruch dient nur der besseren Lesbarkeit.]
Ein Microsoft ISA/2000 Proxy-Server parst das Beispiel als einzelnen
POST-Request mit einer Content-Length von 195 Bytes (Zeilen 1–11). Ein
Tomcat Web-/Application-Server parst es als einen vollständigen
POST-Request mit einer Content-Length von 10 Bytes (Zeilen 1–7
einschließlich des 'ist=nichts' in Zeile 7) und einen
unvollständigen POST-Request mit einer Content-Length von 85 Bytes
(Zeilen 7–11 ohne das 'ist=nichts' in Zeile 7).
Unvollständig, da von den 85 Bytes nur 84 geliefert wurden. Der erste
(vollständige) Request wird beantwortet und die Antwort vom ISA-Server
an den Angreifer gesendet. Der zweite (unvollständige) Request wird
vom Tomcat-Server gespeichert.
Leitet der ISA-Server danach zum Beispiel einen GET-Request von einem Client an den Tomcat-Server weiter, wird von diesem das erste empfangene Byte als Vervollständigung des gespeicherten Requests betrachtet. Der Rest des neuen Requests wird als ungültig verworfen und der vervollständigte gespeicherte Request beantwortet:
7 POST /verwundbar.jsp HTTP/1.0
8 Content-Type: application/x-www-form-urlencoded
9 Content-Length: 85
10
11 parameter1=wert1&daten=<script>alert("Datenklau:"
%2bdocument.cookie)</script>&muell=G
Der Client erhält als Antwort eine HTML-Seite mit dem eingeschleusten
JavaScript-Code
<script>alert("Datenklau:"+document.cookie)</script>.
Genauso kann jeder beliebige andere JavaScript-Code eingeschleust werden.
Der Angreifer kann auch die übertragenen Cookies und Daten der HTTP-Authentifikation stehlen. Diese befinden sich in den HTTP-Headern des Client-Requests. Durch entsprechende Wahl des Content-Length-Headers in Zeile 9 kann der Angreifer diese Daten in die Antwort an den Client schreiben lassen, von wo aus er sie sich vom gleichzeitig eingeschleusten JavaScript-Code zusenden lässt:
1 POST /irgendwas.jsp HTTP/1.0
2 Connection: Keep-Alive
3 Content-Type: application/x-www-form-urlencoded
4 Content-Length: 10
5 Content-Length: 395
6
7 ist=nichtsPOST /verwundbar.jsp HTTP/1.0
8 Content-Type: application/x-www-form-urlencoded
9 Content-Length: 600
10
11 parameter1=wert1&daten=<script>
[Code zum Sammeln und Senden der Daten]</script>
Der unvollständige HTTP-Request in den Zeilen 7–11 umfasst deutlich weniger als die angegebene Content-Length von 600 Bytes. Dadurch werden die ersten rund 300 Bytes des nächsten Requests in die Antwort integriert. Die darin enthaltenen HTTP-Header liefern die gewünschten Informationen wie Cookies des Clients, Authentifikationsdaten und die angeforderte URL, die ebenfalls sensitive Informationen enthalten kann.
Request Credential Hijacking
Ein Angreifer kann durch folgenden Angriff auch ein Skript mit den
Authentifikationsdaten (Credentials) eines Benutzers aufrufen:
1 POST /irgendwas.jsp HTTP/1.0
2 Connection: Keep-Alive
3 Content-Type: application/x-www-form-urlencoded
4 Content-Length: 10
5 Content-Length: 135
6
7 ist=nichtsGET /ein_skript.jsp?parameter1=wert1 HTTP/1.0
8 Content-Type: application/x-www-form-urlencoded
9 Content-Length: 0
10 Wegdamit:
Sendet der Client danach einen Request wie zum Beispiel
GET /eine_seite.jsp HTTP/1.0
Cookie: user_id=1234567
Authorization: Basic abrakadabra
vervollständigt der Tomcat-Server damit den unvollständigen Request zu
7 GET /ein_skript.jsp?parameter1=wert1 HTTP/1.0
8 Content-Type: application/x-www-form-urlencoded
9 Content-Length: 0
10 Wegdamit: GET /eine_seite.jsp HTTP/1.0
11 Cookie: user_id=1234567
12 Authorization: Basic abrakadabra
und führt ihn aus: Das Skript /ein_skript.jsp wird mit
den Authentifikationsdaten des Clients ausgeführt und das Ergebnis an
den Client geschickt.
Nächste Woche geht es um weitere Möglichkeiten des HTTP-Request-Smuggling.
Wenn Sie Fragen oder Themenvorschläge haben, können Sie diese gerne an die angegebene E-Mail-Adresse senden oder als Kommentar an die Kolumne anfügen.
- About Security (#1): IT-Sicherheit -- Was ist das eigentlich?
- About Security (#2): Angriffsszenarien
- About Security (#3): Eindringlinge abwehren
- About Security (#4): Gefährdung aus der Peripherie
- About Security (#5): Der Pufferüberlauf
- About Security (#6): Ausnutzung von Pufferüberlauf-Schwachstellen
- About Security (#7): Gegenwehr -- Pufferüberläufe verhindern
- About Security (#8): Vorbeugung -- Pufferüberläufe verhindern
- About Security (#9): Sourcecode Audit -- Pufferüberläufe finden
- About Security (#10): Software- Audit -- Schwachstellensuche in Binaries
- About Security (#11): SQL-Injection
- About Security (#12): SQL-Injection verhindern
- About Security (#13): Mit Stored Procedures gegen SQL-Injection
- About Security (#14): Cross-Site Scripting
- About Security (#15): Cross-Site Scripting verhindern
- About Security (#16): Skriptcode einschleusen
- About Security (#17): HTTP-Request-Smuggling
























Kommentare
Warum funktioniert der letzte Angriff, obwohl in der Zeile 9 steht: Content-Length: 0 ?
Vielen Dank und
viele Grüße
Miriam K. #zitieren
Danke.
Warum funktioniert der letzte Angriff, obwohl in der Zeile 9 steht: Content-Length: 0 ?
Weil es ein GET-Request ist. Der hat keinen Body, und eigentlich braucht er gar keinen Content-Length-Header. Einer mit dem Wert 0 schadet aber auch nicht.
Zeile 10-12 gehören noch zum Header, der Header und damit der gesamte Request endet mit dem 'abrakadabra'. Danach kommt nichts mehr.
Bei einem POST-Request käme nach dem Header eine Leerzeile und danach der Body, der dann so lang ist, wie im Content-Length-Header angegeben ist.
Ich hoffe, ich habe es verständlich erklärt?
Viele Grüße
Carsten Eilers #zitieren