ysoseria
ysoserial 是一个专门用来生成利用Java反序列化漏洞的载荷(payload)的工具。 项目地址:https://github.com/frohoff/ysoserial
ysoserial的payload源码位于./src/main/java/ysoserial/payloads/
中
每个payload中都有一个main函数,其中调用了PayloadRunner.run
,可以通过执行mian函数来单独调试某个payload。
每个PayloadRunner.run()
都会尝试接收一个命令行参数作为要执行的命令,在IDEA中可以进入运行配置中指定参数。
URLDNS
URLDNS是ysoserial中的一条反序列化链名称,主要作用就是可以指定一个URL,当目标进行反序列化后会发起DNS请求,通过观察DNSlog就能判断序列化数据是否被反序列化。
这个算不上是一个利用链,因为我们传入的参数是url而非命令,触发的结果也不是命令执行而是DNS请求,因此主要用于判断是否存在java反序列化漏洞。并且URLDNS这条利用链并不依赖于第三方的类,而是JDK中内置的一些类和方法。
编辑配置
在URLDNS类的getObject方法中,会生成paylaod,这个方法会返回一个对象,这个对象就是最后被序列化的对象,是HashMap类型。触发反序列化的方法是readObject方法,于是继续看HashMap类的readObject方法。
HashMap类的readObject方法主要是让HashMap对象在字节流中恢复其状态。此处需要关注最后一个hash函数,因为在ysoserial注释中说明了,此处hashcode的计算操作触发了DNS请求。跟进hash函数 
这里是调用了key的hashCode方法
而hashCode方法中,是对handler进行hashcode的计算,handler是URLStreamHandler对象。如果不是-1,则表示算过了,之后不算了,直接返回hashCode;是-1则进入handler.hashCode()计算中,触发DNS也是在这一步。
继续跟入handler.hashCode()
方法
getProtocol()
获取协议名,调用getHostAddress()
方法,继续跟入

InetAddress.getByName(host)
的作用是根据主机名,获取其IP地址,在网络上其实就是一次 DNS查询,此处触发DNS记录。
有DNS记录
|
|
POC编写:传入一个 URL 对象,由于其hashCode字段是私有的,修改之前需要开权限setAccessible(true)
,然后设置为-1,就会触发DNS。
|
|
总结:在URLDNS里面其实导致反序列化的根本原因是因为hashmap重写了readobject反序列化方法,而重写后的readobject方法调用了putVal导致的一个利用链。
参考: https://www.cnblogs.com/N0r4h/p/15840776.html https://www.cnblogs.com/nice0e3/p/13772184.html