Blind XXE with out-of-band interaction via XML parameter entities
Level: Practitioner
Today we will solve Portswigger’s “Blind XXE with out-of-band interaction via XML parameter entities” lab from their XXE (XML external entity) injection series. Here we will learn what our parameter entities and how to use them.
This is what we know:
This lab has a “Check stock” feature that parses XML input, but does not display any unexpected values, and blocks requests containing regular external entities.
To solve the lab, use a parameter entity to make the XML parser issue a DNS lookup and HTTP request to Burp Collaborator.
Let’s run Burp and let’s start!
When we open the lab, we see a webstore with different products. Let’s open one of them and click on the “Check stock” button.
Now let’s head to Burp, find that request (POST /product/stock) in HTTP history and send it to Repeater. We can see that the request includes some XML:
To perform XXE, the first thing we need to do is create a DOCTYPE element that contains an entity. If you want to know a little bit more about how entities function, then you can check out my write-up for Portswigger’s apprentice-level lab “Exploiting XXE to perform SSRF attacks”. [reference]
First, we declare the entity and send the request. It doesn’t matter what the entity is called or what exactly it is referencing, right now we are just checking whether we can declare entities at all. For example, my payload looks like this:
<!DOCTYPE test [ <!ENTITY test "test"> ]>
We place it right after the XML declaration:
The response doesn’t result in an error. This means that we can indeed declare entities without a problem. As the next step, let’s check if we can also reference the entity we just declared. We do this by using the name of the entity (“test” in this case) between an ampersand (&) and a semicolon (;) and replacing the current productId value with that.
The response returns this error: “Entities are not allowed for security reasons”. This means that we can’t reference the entity within the XML document.
Luckily, in this case, we can use an alternative method: parameter entities. Basically it means that we will reference the entity within the DOCTYPE, rather than outside of it. In order to use parameter entities, we add the percent sign (%) in front of the name of the entity and then reference it using the percent sign (%) and a semicolon (;), so now our payload looks like this:
<!DOCTYPE test [<!ENTITY % test "test"> %test; ]>
When we send this request, we get a different reponse: “XML parsing error”! This is good because it shows us that the app is parsing XML. Now, let’s try doing an out-of-band call to check if we can get the app to communicate to our Collaborator server. Since now we’re dealing with an external entity, we need to add the keyword SYSTEM, followed by our Collaborator payload (right click -> Insert Collaborator payload):
<!DOCTYPE test [<!ENTITY % test SYSTEM "http://Burp-Collaborator-Payload"> %test; ]>
Now our XML looks like this:
When we send the request, we still get “XML parsing error”. However, when we go to the Collaborator tab and click “Poll now”, we see some results that confirm XXE via out-of-band interaction. We have solved the lab!