XXE - XEE - XML External Entity
Last updated
Last updated
Hack the box Web attacks module Recommended!
XML External Entity (XXE) Injection
vulnerabilities occur when XML data is taken from a user-controlled input without properly sanitizing or safely parsing it, which may allow us to use XML features to perform malicious actions.
Always try simple payloads first
This trick only works with php application
we may still be able to execute commands on PHP-based web applications through the PHP://expect
filter, though this requires the PHP expect
module to be installed and enabled.
If the XXE directly prints its output, we can execute basic commands as expect://id
The most efficient method to turn XXE into RCE is by fetching a web shell from our server and writing it to the web app
Note: The expect module is not enabled/installed by default on modern PHP servers, so this attack may not always work. This is why XXE is usually used to disclose sensitive local files and source code, which may reveal additional vulnerabilities or ways to gain code execution.
we saw how we could use PHP filters to encode PHP source files, such that they would not break the XML format when referenced. But what about other types of Web Applications? . To output data that does not conform to the XML format, we can wrap the content of the external file reference with a CDATA
tag (e.g. <![CDATA[ FILE_CONTENT ]]>
). This way, the XML parser would consider this part raw data, which may contain any type of data, including any special characters.
After that, if we reference the &joined;
entity, it should contain our escaped data. However, this will not work, since XML prevents joining internal and external entities.
to bypass this limitation, we can utilize XML Parameter Entities
What's unique about parameter entities is that if we reference them from an external source (e.g., our own server), then all of them would be considered as external and can be joined, as follows:
let's try to read the submitDetails.php
file by first storing the above line in a DTD file. host it on our machine, and then reference it as an external entity on the target web application, as follows:
Now, we can reference our external entity (xxe.dtd
) and then print the &joined;
entity we defined above, which should contain the content of the submitDetails.php
file, as follows:
This trick can become very handy when the basic XXE method does not work or when dealing with other web development frameworks.
if the web application might not write any output, so we cannot control any of the XML input entities to write its content. In such cases, we would be blind
to the XML output and so would not be able to retrieve the file content using our usual methods.
If the web application displays runtime errors (e.g., PHP errors) and does not have proper exception handling for the XML input, then we can use this flaw to read the output of the XXE exploit.
First we need to cause an error,we can delete any of the closing tags, change one of them, so it does not close (e.g. <roo>
instead of <root>
), or just reference a non-existing entity.
Let's host a DTD file that contains the following payload:
%nonExistingEntity;
does not exist, so the web application would throw an error saying that this entity does not exist, along with our joined %file;
as part of the error.
Now, we can call our external DTD script, and then reference the error
entity, as follows:
To read source files
"file:///var/www/html/submitDetails.php"
).
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.
we need to make the web application send a web request to our web server with the content of the file we are reading.
we can first use a parameter entity for the content of the file we are reading while utilizing PHP filter to base64 encode it. Then, we will create another external parameter entity and reference it to our IP, and place the file
parameter value as part of the URL being requested over HTTP, as follows:
We write a simple PHP script that automatically detects the encoded file content, decodes it, and outputs it to the terminal:
So, we will first write the above PHP code to index.php
, and then start a PHP server on port 8000
, as follows:
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.
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:
Now, we can run the tool with the --host
/--httpport
flags being our IP and port, the --file
flag being the file we wrote above, and the --path
flag being the file we want to read. We will also select the --oob=http
and --phpfilter
flags to repeat the OOB attack we did above, as follows:
We see that the tool did not directly print the data. This is because we are base64 encoding the data, so it does not get printed. In any case, all exfiltrated files get stored in the Logs
folder under the tool, and we can find our file there:
we can automate the process of blind XXE data exfiltration with tools. One such tool is .