Description
The SOAP stock-check endpoint fails to sanitize XML entities. Inject an external entity to have the backend disclose /etc/passwd.
Setup
Open the provided web portal in Burp Suite's built-in browser and intercept a request to any "Details" button.
Modify the XML payload to include a malicious DOCTYPE that defines an external entity pointing to /etc/passwd.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]>
<stockCheck><productId>&xxe;</productId></stockCheck>Solution
- Step 1Capture the POST bodyWith Burp intercept on, click a Details button to pause the request. The body already contains stockCheck XML you can modify.
Learn more
XXE (XML External Entity) injection exploits the XML parser's ability to resolve external references. The XML specification allows documents to declare entities - named values that can be referenced by
&name;syntax anywhere in the document. External entities are a specific type where the entity's value is loaded from a URI at parse time, which can point to local files (file:///etc/passwd), internal network resources (http://internal-server/), or even other protocols.Burp Suite is a web security testing platform widely used in CTF and professional penetration testing. Its Proxy tool intercepts HTTP/HTTPS traffic between your browser and the server, allowing you to inspect and modify requests before they are sent. The Repeater tool lets you replay modified requests without re-clicking in the browser, and Intruder automates payload fuzzing.
The SOAP (Simple Object Access Protocol) name is a hint: SOAP is a web service protocol that uses XML for message formatting. XML-based APIs are particularly susceptible to XXE because they must parse XML by design. Modern APIs favor JSON, which has no equivalent external reference mechanism.
- Step 2Inject the entityInsert the DOCTYPE snippet defining &xxe;, then replace the productId value with &xxe;. Forward the request to have the server echo /etc/passwd, including the flag.
Learn more
The injected DOCTYPE declaration
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]>tells the XML parser: "define an entity namedxxewhose value should be read from the local file /etc/passwd." When the parser later encounters&xxe;in the document body, it substitutes the file contents. If the server then includes that value in its response, the file is leaked to the attacker./etc/passwd is a world-readable file on Linux systems containing user account information (username, UID, GID, home directory, shell). In this challenge, the flag has been appended to or embedded within /etc/passwd - a common CTF convention. In real attacks, XXE is used to read application config files (
/etc/nginx/nginx.conf), private keys (/etc/ssl/private/server.key), AWS credentials (/root/.aws/credentials), or source code.XXE is ranked in the OWASP Top 10. The fix is to disable external entity processing in the XML parser (most modern parsers have this option:
FEATURE_SECURE_PROCESSINGin Java's JAXP,resolve_entities=Falsein Python's lxml). Alternatively, switching to JSON-based APIs eliminates the attack surface entirely.
Flag
picoCTF{XML_3xtern@l_3nt1t1ty_4db...}
Any file path works, but /etc/passwd proves the XXE and includes the picoCTF token in the response.