The XML External Entity (XXE) attack is a type of attack against an application that parses XML input. An XXE attack typically occurs when XML input containing a reference to an external entity is processed by a weakly configured parser. An attacker can leverage an XXE attack to access sensitive data and read local or remote files. In a similar manner to SSRF, an attacker could introduce malicious code through Remote Code Execution (RCE).
To understand how we can use an XXE attack, we must first understand how XML works. Typically, XML is used to declare elements, attributes and text. XML documents can specify a set of mark-up declarations that define a document type, the XML parser will then validate the XML document to ensure that it correct prior to it being processed. This is done via XML Scheme Definition or Data Type Definition. For our application, we will concentrate on Data Type Definitions (DTD) as this is where XXE vulnerabilities occur.
In our application, XXE is present on the message delete request. We can verify that XML exists in the application, by first deleting an existing message whilst capturing the request via Burpsuite. The screenshot below notes that we have two XML entities,
< request > and
< id >.
Within the two XML entities, we have the numerical id value that the system allocated when the message was first created, 87. If we can create our own XML entity and include it within these two existing entities we should be able to get the XML parser to read our request. In this case, I forward the request inside Burpsuite and return to our web browser, and see that the message has been deleted. Repeating the process, I delete another message, this time however I will capture the request and include my own XML code, declaring a new XML entity called xxe, as shown below:
Looking at the above code, what we are doing is creating a new XML entity called xxe, then we are passing it a system command, asking it to retrieve the local password file “file:///etc/passwd”. We then include the newly created XML entity xxe inside the existing XML
< request > entity. So, our request is now
< request >< id >88&xxe;< /id > request >. You will also notice that we specify the XML entity that we want the XML parser to target,
< !DOCTYPE request [ < !ELEMENT request ANY >, which makes sense as the application already has an existing
< request > xml entity and this is the area we wish to inject our new xxe entity containing the system request into.
At this point, if we were to forward our modified request in Burpsuite, the server will delete the message and forward us directly back to the messages page. The reason for this is that the code executes the delete request and then drops the 2nd part of the query &xxe; which contains our xxe entity request.
What we need to do is remove the number within the request and id xml entities, so our final request shows as
< request >< id >&xxe; id > request > as shown in the screenshot below:
After forwarding our modified request and returning to the browser, we see that we are presented with the contents of the etc/passwd file which have been pulled from the underlying server upon which the application is hosted, as shown below: