ysoserial-URLDNS链
前言
项目地址:
ysoserial/src/main/java/ysoserial/payloads/URLDNS.java at master · frohoff/ysoserial (github.com)
URLDNS
是ysoserial
中的一条利用链,通常用于检测是否存在Java
反序列化漏洞,特点:
- 只能发起dns请求,不能进行其他利用
- 目标无回显
- 使⽤用Java内置的类构造,对第三⽅方库没有依赖
原理分析
官方给的Gadget Chain:
1 | * HashMap.readObject() |
我们正着来走一遍
先跟进HashMap
类,是一个可序列化的类,其重写了readObject()
方法,然后通过一个for循环K key = (K) s.readObject();
进行反序列化。然后调用putVal()
函数,在其中调用hash(key)。
当key != null
时,调用hashCode()
函数。这里的 key 是可控的,就是传入的 java.net.URL
而在java.net.URL
类中,首先URL
类是一个可反序列化的类。URL
类中存在hashCode()
方法,由于hashCode
的值默认为-1
,因此会执行hashCode = handler.hashCode(this);
跟进hashCode()
,发现其调用了一个getHostAddress(u)
,其作用为解析域名,从而发起DNS
请求。我们再往下跟进,确认一下。
跟进getHostAddress(u)
调用了URL
的getHostAddress()
,继续跟进
在InetAddress.getByName(host)
中,跟进主机名获取对应的InetAddress
实例,这个过程就涉及到了DNS
请求。
利用
这条链子非常简单,在利用这一部分我分成了两块,首先我们先尝试自行利用,然后再去看看ysoserial这个项目的利用。
自行利用
bp Collaborator,用于接受dns请求
注意这里的 key
以及 value
是从 tab 中取的,而 tab 的值即 HashMap
中 table 的值。
想要修改 table 的值,就需要调用 HashMap#put
方法,而 HashMap#put 方法中也会对 key 调用一次 hash 方法,所以这里也会产生一次 dns 查询
为了避免这次 dns 查询,我们将 hashCode 设置不为 -1
的其他值
完整poc
1 | public class urlTest { |
注意!
在jdk17+已经不能直接通过 setAccessible
来访问私有属性了。
ysoserial直接利用URLDNS链
将ysoserial项目 git clone 下来,咱们直接调试jar源代码。局部调试,在源代码中调用特定class文件的main函数进行调试。
ysoserial项目是由 maven 构建的,我们查看pom.xml文件,其中存在 <mainClass>
,表明 ysoserial.GeneratePayload
就是主类。
由于在ysoserial中所有payload生成接口都可以从ysoserial.GeneratePayload
进入,我们可以调用该类的main函数同时指定参数,进入任意payload生成模块。
我们再来看看GeneratePayload的main函数
检查传递的命令行参数数量是否为2,然后分别存储从命令行输入的payload类型和命令。
如果此时直接开始调试只能在 console 中看到输出 usage 页面,ysoserial 需要添加参数来运行指定的 payloads 模块。
所以需要修改默认参数为上述所说,修改路径/方法如下。打开 IDEA 右上角的 Edit Configurations...
以上方法主要是调试整个程序,调试其他项目的思想大致如此。
ysoserial 可以不用单独调试,这里主要是为了记录方法/思想,以后遇到其他项目时就知道该怎么去调试了。
细看ysoserial的URLDNS
在渗透测试中,如果对着服务器打一发JAVA反序列化payload,而没有任何回应,往往就不知道问题出在了哪里
- 打成功了,只是对方机器不能出网?
- 还是对面JAVA环境与payload版本不一样,改改就可以?
- 还是对方没有用这个payload利用链的所需库?利用链所需库的版本不对?换换就可以?
- 还是…以上做的都是瞎操作,这里压根没有反序列化readobject点QAQ
而URLDNS模块正是解决了以上疑惑的最后一个,确认了readobject反序列化利用点的存在。不至于payload改来改去却发现最后是因为压根没有利用点所以没用。同时因为这个利用链不依赖任何第三方库,没有什么限制。
如果目标服务器存在反序列化动作(readobject),处理了我们的输入,同时按照我们给定的URL地址完成了DNS查询,我们就可以确认是存在反序列化利用点的。
从JAVA反序列化RCE的三要素(readobject反序列化利用点 + 利用链 + RCE触发点)来说,是通过(readobject反序列化利用点 + DNS查询)来确认readobject反序列化利用点的存在。
ysoserial payload生成命令:java -jar ysoserial.jar URLDNS "自己能够查询DNS记录的域名"
参考:
ysoserial/src/main/java/ysoserial/payloads/URLDNS.java at master · frohoff/ysoserial (github.com)
Java安全学习—URLDNS链 - FreeBuf网络安全行业门户
URLDNS链详解 - N1Rvana’s Blog (nlrvana.github.io)
JAVA反序列化-ysoserial-URLDNS-安全客 - 安全资讯平台 (anquanke.com)
理解Java反序列化-ysoserial URLDNS | Seikei’s Blog (s31k31.github.io)
知识星球-代码审计:Java安全漫谈 – 08.反序列化篇(2)