Java反序列化-URLDNS
ysoserial项目地址:ysoserial
导入到idea即可
Payload生成工具:java -jar ysoserial-[version]-all.jar [payload] '[command]'
测试靶场
|
URLDNS
|
- 需支持DNS查询
- JDK自带,不依赖于第三方库
- 最简单的payload,虽然不能RCE,却是反序列化漏洞检测最简单和最有效的办法
Gadget Chain
通过HashMap
触发DNS查询。
|
调试方法
回溯分析
此处getHostAddress是解析域名,而想要调用这个方法,需要调用URLStreamHandler.hashCode,使得u可以传入getHostAddress进行域名解析
我们通过查看谁调用了URLStreamHandler.hashCode,右键Find Usages,可以看到URL调用了URLStreamHandler.hashCode
URL类下,handler.hashCode函数传入了this,也就是说我们需要URL类来调用hashCode
hashCode
属性默认是-1
。这段代码的意思就是,当第一次调用hashCode
方法的时候,hashCode为-1
,不会进入if判断。当第二次或以后调用hashCode
方法的时候,就会进入if判断了,直接返回hashCode
属性。所以我们就可以通过反射来修改hashCode
我们可以看到handler是URL的URLStreamHandler
由transient修饰的属性无法被序列化和反序列化, 那么为什么还是成功解析URL呢?
这就需要看到URL类的readResolve方法,这个方法在反序列化的时候执行。这个方法先通过getURLStreamHandler获取到一个URLStreamHandler,再通过setDeserializedFields把URL类的handler属性设置为URLStreamHandler对象,这样反序列化出来的HashMap中的URL类的handler属性就不会为空了
我们继续回溯hashCode,看下类可控,并且调用hashCode()
可以看到HashMap调用到了key.hashCode()
我们来看下key调用了hashCode,满足我们的要求,我们只要key为URL类即可
继续往下回溯,看谁调用了hash,并且是readObject调用
可以看到这个是读取key和value的值映射放入HashMap,所以说我们只要将键值put到HashMap即可
靶场演练
使用ysoserial生成payload
|