XML eXternal Entity (XXE) attack:

External Entity: The set of valid entities can be extended by defining new entities. If the definition of an entity is a URI, the entity is called an external entity. Unless configured to do otherwise, external entities force the XML parser to access the resource specified by the URI, e.g., a file on the local machine or on a remote systems. This behavior exposes the application to XML eXternal Entity (XXE) attacks, which can be used to perform denial of service of the local system, gain unauthorized access to files on the local machine, scan remote machines, and perform denial of service of remote systems.

Example 1

Some XML parsers will resolve external entities, and will allow a user controlling the XML message to access resources; for example to read a file on the system. The following entity can be declared, for example:

<!ENTITY x SYSTEM "file:///etc/passwd">

You will need to envelope this properly, in order to get it to work correctly:

<!DOCTYPE test [
<!ENTITY x SYSTEM "file:///etc/passwd">]>

You can then simply use the reference to x: &x; (don’t forget to encode &) to get the corresponding result inserted in the XML document during its parsing (server side).

In this example, the exploitation occurs directly inside a GET request, but it’s more likely that these types of requests are performed using a POST request, in a traditional web application. This issue is also really common with web services, and is probably the first test you want to do, when attacking an application that accepts XML messages.

This example can also be used to get the application to perform HTTP requests (by using http:// instead of file://) and can be used as a port scanner. However, the content retrieved is often incomplete since, the XML parser will try to parse it as part of the document. –PentesterLab

Example 2

In this example, the code uses the user’s input, inside an XPath expression. XPath is a query language, which selects nodes from an XML document. Imagine the XML document as a database, and XPath as an SQL query. If you can manipulate the query, you will be able to retrieve elements to which you normally should not have access.

If we inject a single quote, we can see the following error:

Warning: SimpleXMLElement::XPath(): Invalid predicate in /var/www/xml/example2.php on line 7 Warning: SimpleXMLElement::XPath(): xmlXPathEval: evaluation failed in /var/www/xml/example2.php on line 7 Warning: Variable passed to each() is not an array or object in /var/www/xml/example2.php on line 8

Just like SQL injection, XPath allows you to do boolean logic, and you can try:

' and '1'='1 and you should get the same result.

' or '1'='0 and you should get the same result.

' and '1'='0 and you should not get any result.

' or '1'='1 and you should get all results.

Based on these tests and previous knowledge of XPath, it’s possible to get an idea of what the XPath expression looks like:

[PARENT NODES]/name[.='[INPUT]']/[CHILD NODES]

To comment out the rest of the XPath expression, you can use a NULL BYTE (which you will need to encode as %00). As we can see in the XPath expression above, we also need to add a ] to properly complete the syntax. Our payload now looks like hacker']%00(or hacker' or 1=1]%00 if we want all results).

If we try to find the child of the current node, using the payload '%20or%201=1]/child::node()%00, we don’t get much information.

Here, the problem is that we need to got back up in the node hierarchy, to get more information. In XPath, this can be done usingparent::* as part of the payload. We can now select the parent of the current node, and display all the child node usinghacker'%20or%201=1]/parent::*/child::node()%00.

One of the node’s value looks like a password. We can confirm this, by checking if the node’s name is password using the payloadhacker']/parent::*/password%00.