XML external entity (XXE) injection

Iam_Wander
8 min readJun 7, 2024

--

In todays writeup, i will dwell on yet another web vulnerability type from https://portswigger.net/web-security/xxe that allows the attacker to interfere with an application functionality in its passing of XML data.

This vulnerability type arises when an application allows an external entity to be added within its XML structure.

For instance, if an application submits XML data as shown.

<?xml version="1.0" encoding="UTF-8"?>
<stockCheck><productId>381</productId></stockCheck>

Then imagine if the application allowed us to add an entity and reference it within our product Id as shown below.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE test [<!ENTITY foo SYSTEM>]>
<stockCheck><productId>381</productId></stockCheck>

Here, the payload defines an external entity ‘foo’ and whose value is /etc/passwd. Therefore the application reveals the external files.

To get a better understanding of how these attacks work in the wild, we will solve the labs provided by https://portswigger.net

Lab: Exploiting XXE using external entities to retrieve files

in this instance, we are presented with an application in which we are required to read /etc/passwd files.

Upon further review, we see that the application has a stock check feature, which reveals a POST /product/stock when proxies to burp. The request is parsed in an XML data format.

To read the /etc/passwd files, we can introduce an external ENTITY just like we discussed in the intro.

Payload to use

Hurrah! We successfully read the /etc/passwd files.

Lab: Exploiting XXE to perform SSRF attacks

XXE attacks can also be used to perform an SSRF attack. For instance, in this web server the lab is running a simulated EC2 metadata endpoint at default URL 169.254.169.254/ which can be used to retrieve data that is sensitive.

We will abuse this XML data structure and perform an SSRF attack to retrieve these files.

After adding the ENTITY and making a call to the internal address, we get a verbose error. ‘Invalid product ID: latest’, follow the directory

"http://169.254.169.254/latest/meta-data/iam/security-credentials/admin"

Good! You’ve exposed the secret file.

Lab: Exploiting XInclude to retrieve files

In cases where the attack surface of an xxe vulnerability is not visible, a bad actor might have to establish footing in places where xml data is not passable.

Some application recieve client-side data and parse it in an xml document to the backend. In cases like this, we cannot carry a succesfull XXE attack as we do not control the XML document. This is where we can use the Xinclude.

Payload:

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

Refer: https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XXE%20Injection#xinclude-attacks

To demonstrate this in practise, we will use the lab from Portswigger.

A look at the burp request body, indeed we do not have a clear attack surface to launch an XXE exploit as we barely control the XML doc.

To determine how the application handles XML entities, we can introduce the ENTITY element in place of the product ID.

The application throws an error “Entities are not allowed for security reasons”. This indicates that there is some sort protection from XXE in place.

Now replace the productId with the Xinclude payload to call for /etc/passwd.

Hurrah!

Lab: Exploiting XXE via image file upload

This kind of attack is common in the wild, and likely 10% of web applications are vulnerable to it.

In cases where a web application accepts SVG image uploads and since the SVG uses xml, an attacker might upload a malicious SVG file to compromise a web application.

Payload

To achieve this exploit, upload an SVG image or any image type for that matter and proxy the request body via burp.

Replace the image data with the payload and load the the website to retrieve the file contents.

In a real life scenario where extracting the files might be impossible, we can prove the attack worked by using an out of band exploitation using our our web server.

You might as well use your burp collaborator for this.

Example:

Lab: Blind XXE with out-of-band interaction via XML parameter entities

In cases where regular entities are blocked due to some input validation or XML parser configuration, we can try to refference parameter entities to try and bypass this restriction.

The declaration of parameter entities include:

  1. the percent character before the entity name {<!ENTITY % myparameterentity “my parameter entity value” >}
  2. parameter entities are referenced using the percent character instead of the usual ampersand. {%myparameterentity;}

To demonstrate how this attack is possible, we will use a parameter entity to make the XML parser issue a DNS lookup and HTTP request to Burp Collaborator.

Exploiting blind XXE to exfiltrate data out-of-band

Detecting an XXE attack via an out of band technique does not necesarry show how the attack can be exploited. The main aim is for an attacker to exfiltrate sensitive data.

This may involve an attacker hosting a malicious DTD on a system that they control, and then invoking the external DTD from within the in-band XXE payload.

https://book.hacktricks.xyz/pentesting-web/xxe-xee-xml-external-entity#malicious-dtd-example

The above DTD involves the following steps:

  1. It defines an XML parameter entity called file which contains the contents of /etc/passwd.
  2. It defines an XML parameter entity called eval that calls for another parameter entity called exfiltrate this exfiltrate entity makes a HTTP request to the attackers server containing the parameter value of file entity defined earlier to call for /etc/passwd
  3. Uses the eval entity, which causes the dynamic declaration of the exfiltrate entity to be performed.
  4. Uses the exfiltrate entity, so that its value is evaluated by requesting the specified URL.

The attacker must then host the malicious DTD on a system that they control (attacker web server)

Finally, the attacker must submit the following XXE payload to the vulnerable application:

This technique may not neccessarily work in instances where the attacker may want to exfiltrate the contents of /etc/passwd as some XML parsers fetch the contents of url in the entity defined and use APIs to validate the contents allowed.

In such cases it might be possible to use FTP protocal instead of HTTP protocal. Sometimes, it will not be possible to exfiltrate data containing newline characters, and so a file such as /etc/hostname can be targeted instead.

This instance highlights a very realistic exploitation techique an attacker could use to obtain the contents of /etc/hostname.

The stock check feature parses data in XML format. We can take advantage of this and craft our DTD in our exploit server as shown below…

Copy the URL and add it to the external entity between the xml and the stockcheck feature.

Poll the Burp collaborator client to recover the DNS records.

Refer: https://book.hacktricks.xyz/pentesting-web/xxe-xee-xml-external-entity#malicious-dtd-example

Lab: Exploiting blind XXE to retrieve data via error messages

In the case of blind XXE with error message, the server load a malicious DTD that will load the contents of the file inside an error message.

This is accomplished through the following steps:

  1. An XML parameter entity named file is defined, which contains the contents of the /etc/passwd file.
  2. An XML parameter entity named eval is defined, incorporating a dynamic declaration for another XML parameter entity named error. This error entity, when evaluated, attempts to load a nonexistent file, incorporating the contents of the file entity as its name.
  3. The eval entity is invoked, leading to the dynamic declaration of the error entity.
  4. Invocation of the error entity results in an attempt to load a nonexistent file, producing an error message that includes the contents of the /etc/passwd file as part of the file name.

Just like we did in the previous lab, we will craft an exploit and instead point our file to entity to a non existent file as the lab blocks out of band interactions.

Save the url and add it to the external entity between the xml and the stockcheck feature.

--

--

No responses yet