Websecurity - XSS-Angriffe über XML
Wie angekündigt, geht es in dieser Folge wieder um die Sicherheit von Webanwendungen. Konkret ist dieser Text die Fortsetzung der vor der WebTech Conference 2012 begonnen Serie zur Websecurity. Dementsprechend geht es auch weiter um die von Rich Lundeen, Jesse Ou und Travis Rhodes von Microsoft auf der Konferenz Black Hat Abu Dhabi 2011 unter dem Titel "New Ways I'm Going to Hack Your Web App" vorgestellten Angriffe. Genauer: Um
XSS-Angriffe über die Extensible Markup Language (XML)
Die Extensible Markup Language XML wird für alle möglichen Zwecke verwendet, unter anderem zum Datenaustausch. Extensible Stylesheet Language Transform (XSLT) ist eine XML-Sprache, über die XML-Formate in andere XML-Formate umgewandelt werden können.
XML erlaubt in bestimmten Fällen XSS-Angriffe. Zum Beispiel...
...über URL-Fragmente in System-Identifiers:
<?xml version="1.0"?>
<!DOCTYPE billion SYTEM "#<script>alert(1)</script>"
[
<!ENTITY foo SYSTEM "#<script>alert(1)</script>">
<!NOTATION GIF SYSTEM "#<script>alert(1)</script>">
]>
<bar>&foo;</bar>
Der Fragment-Identifier
'#<script>alert(1)</script>'
kann nicht Teil des
System-Identifiers '#<script>alert(1)</script>'
sein. Dementsprechend gibt es beim Parsen eine Fehlermeldung:
Fragment identifier '#<script>alert(1)</script>' cannot
be part of the system identifier
'#<script>alert(1)</script>'
Die öffnet in diesem Fall zwei Alert-Boxen, einem Cyberkriminellen fallen
sicher viele unschöne Dinge ein, die er stattdessen in die
script
-Tags einfügen kann.
... über angepasste HTTP-500-Fehlermeldungen:
<?xml version="1.0"?>
<!DOCTYPE billion
[
<!ENTITY foo "http://ein-server.example/HTTP-500-Fehlermeldung-ausgeben.php">
]>
<bar>&foo;</bar>
Das Skript HTTP-500-Fehlermeldung-ausgeben.php
auf dem Server
ein-server.example
macht das, was sein Name vermuten
lässt: Es liefert eine angepasste HTTP-500-Fehlermeldung zurück,
die natürlich JavaScript-Code enthält. Beim Parsen der XML-Datei
wird diese Fehlermeldung dann ausgegeben:
The remote server returned an error: (500) "Hier kommt die angepasste
Fehlermeldung mit etwas JavaScript-Code, zum Beispiel
<script>alert(1)</script>"
... über eine Kombination aus XML- und XSL-Datei:
Auf den angegriffenen Server wird eine XML-Datei hochgeladen, die auf eine präparierte XSL-Datei auf dem gleichen Server verweist. Wird die XML-Datei später von einem Benutzer herunter geladen, führt sein Webbrowser automatisch die Transformation aus der XSL-Datei durch und rendert die HTML-Tags bzw. führt den JavaScript-Code aus.
Die XML-Datei angriff.xml
:
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl"
href="http://opfer-server.example/boese.xsl"?>
Die dazu gehörende XSL-Datei boese.xsl
, die auf den
gleichen Server opfer-server.example
hochgeladen werden
muss:
<?xml version="1.0" encoding="utf-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
exclude-result-prefixes="msxsl">
<xsl:template match="/">
<script>alert('Achtung XSS-Angriff!')</script>
</xsl:template>
</xsl:stylesheet>
Erlaubt eine Anwendung das Hoch- und Herunterladen beliebiger XML-Dateien, ist das gleichbedeutend mit dem Hochladen beliebiger HTML-Dateien.
Angriff auf WordPress.com
Rich Lundeen, Jesse Ou und Travis Rhodes haben auf WordPress.com eine Möglichkeit für einen XSS-Angriff gefunden. Los ging es mit einer reflektierten XSS-Schwachstelle, die über einen manipulierten Cookie ausgenutzt wird. Ein Angriff auf einen anderen Benutzer ist damit praktisch nicht möglich, da man dem kaum den präparierten Cookie unterschieben kann.
Für einen Angriff müsste also JavaScript-Code auf WordPress.com eingeschleust werden. Einem Blogbetreiber ist dies jedoch nicht möglich, da JavaScript-Code ausgefiltert wird. Um das Problem zu umgehen, suchten Rich Lundeen, Jesse Ou und Travis Rhodes nach einer Möglichkeit, Dateien erst herauf- und später wieder herunterladen zu können. Zwar können Anhänge hochgeladen werden, aber deren Extension wird über eine Whitelist geprüft und ihr Content-Type-Header beim Download passend gesetzt.
Das "Import Wordpress"-Feature zum Heraufladen alter WordPress-Blogs im
.wxr-Format (WordPress eXtended RSS, ein XML-Format) prüft, ob die
heraufgeladene WXR-Datei eine wohlformatierte, also korrekte, XML-Datei
ist. Nach dem Heraufladen wird die Datei umbenannt, das .wxr
wird zu einem .txt
. Dieses Datei kann von jedem Benutzer
gelesen werden, der ihren Pfad kennt.
Und nun wird es interessant: Beim Herunterladen wird der Content-Type nicht gesetzt. Browser, die aus dem Dateiinhalt auf den Content-Type schließen, wie zum Beispiel der Internet Explorer, erkennen diese Datei als XML-Datei. Insgesamt bedeutet dass, das beliebige XML-Dateien hoch- und runtergeladen werden können (jedenfalls wenn das Opfer einen ratefreudigen Browser verwendet).
Mit Hilfe des oben beschriebenen XSS-Angriffs über ein Paar aus XML- und XSL-Datei konnten Rich Lundeen, Jesse Ou und Travis Rhodes die Kontrolle über ein fremdes WordPress-Blog übernehmen:
- Auf WordPress.com wurde ein Blog für den Angriff angelegt.
- Eine JavaScript-Datei, die einen Cookie-Tossing-Angriff durchführt, wurde auf dem eigenen Server der Angreifer angelegt.
- Eine XSL-Datei, die Code zum Laden der in Schritt 2 angelegten
JavaScript-Datei in die damit umgewandelten XML-Dateien einfügt, wurde
unter dem Namen
badlxsl.jpg
im Blog der Angreifer gespeichert. - Eine WXR-Datei, die auf die XSL-Datei
badlxsl.jpg
verweist, wurde ins Wordpress-Blog der Angreifer geladen. - Nun muss das Opfer nur noch auf eine Seite gelockt werden, die die in Schritt 4 hochgeladene WXR-Datei lädt.
Wenn ein Benutzer die WXR-Datei betrachtet, wendet sein Browser die XSL-Transformation an. Der JavaScript-Code wird im Kontext des Angreifer-Blogs ausgeführt und nutzt die Cookie-basierte XSS-Schwachstelle im Blog des Opfers aus. Dabei wird der JavaScript-Code ausgeführt und der Angreifer erlangt die Kontrolle über das Blog des Opfers.
Sie sehen also: Auch eigentlich nicht ausnutzbare Schwachstellen lassen sich mitunter ausnutzen, und XSS ist alles anderes als harmlos.
Die Schwachstelle in WordPress wurde inzwischen natürlich längst behoben.
XML-basierte XSS-Angriffe abwehren
Um XML-basierte XSS-Angriffe abzuwehren, müssen Sie mehrere Maßnahmen kombinieren:
- Generell sollten sowieso keine ausführlichen Fehlermeldungen an
den Benutzer ausgegeben werden. Auch im Fall von Exception-Meldungen beim
Verarbeiten von XML-Dateien sollte davon keine Ausnahme gemacht werden. Es
reicht, wenn die Anwendung eine allgemeine Fehlermeldung zurück
gibt.
Wenn Sie nicht ausschließen können, dass eine Exception-Meldung ausgegeben wird, kodieren Sie die so um, dass eingefügter Code nicht ausgeführt wird. - Wenn Sie das Heraufladen von XML-Dateien erlauben, deaktivieren Sie die Verarbeitung von DTDs.
- Beim Herunterladen von XML-Dateien setzen Sie den Content-Disposition-Header, so dass die Datei wirklich heruntergeladen und nicht im Browser geöffnet wird. Eingeschleuster JavaScript-Code kann dann nicht im Kontext der die Datei liefernden Domain ausgeführt werden.
Auch in der nächsten Folge geht es um Angriffe auf Webanwendungen über Logikfehler.
Übersicht über alle Artikel zum Thema
- Neue Angriffe auf Webanwendungen über Clickjacking und Cookies
- Websecurity - XSS-Angriffe über XML
- Websecurity - Angriffe über Logikfehler
- Websecurity - Angriffe über Logikfehler, Teil 2
- Websecurity - Logikfehler in der Authentifizierung
- Websecurity - Logikfehler in der Authentifizierung und auf der Flucht
- Websecurity - Logikfehler finden
- Websecurity - Logikfehler vermeiden
Trackbacks
Dipl.-Inform. Carsten Eilers am : Drucksache: PHP Magazin 1.16 - XML-Sicherheit - XXE, XSLT und etwas SSRF
Vorschau anzeigen
Dipl.-Inform. Carsten Eilers am : Neues eBook: "Websecurity - Angriffe mit SSRF, CSRF und XML"
Vorschau anzeigen
Dipl.-Inform. Carsten Eilers am : XML-Sicherheit, Teil 6: XPath Injection
Vorschau anzeigen