SOAP

Published: July 19, 2023

Description

The SOAP stock-check endpoint fails to sanitize XML entities. Inject an external entity to have the backend disclose /etc/passwd.

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

  1. Step 1Capture the POST body
    With 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.

  2. Step 2Inject the entity
    Insert 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 named xxe whose 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_PROCESSING in 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.

Want more picoCTF 2023 writeups?

Useful tools for Web Exploitation

Related reading

What to try next