Java学习之URLDNS链
先放代码,感觉还是自己跟着视频手写一遍更好理解,很多理解放在注释中了
1 | import java.lang.reflect.Field; |
原理
看一下大佬总结的原理
java.util.HashMap 重写了 readObject, 在反序列化时会调用 hash 函数计算 key 的 hashCode.而 java.net.URL 的 hashCode 在计算时会调用 getHostAddress 来解析域名, 从而发出 DNS 请求.
开始分析
进入到hashMap类中可以看到它有序列化的接口
并且重写了readObject,这个方法用于序列化数据,在Java中,如果readObject被重写那么首先会调用重写的readObject,下面这里的s为输入流证明可控
开始调试,首先直接在下面这里进入hashMap类
然后找到readObject方法在putVal()方法位置下断点
这里hash()方法对key值重新进行了计算而key值为URL类的对象,跟进看一下
hash()方法里面调用了hashCode()方法,这里key是URL的对象所以这里的hashCode方法是URL类中的,这里调试的时候一定要到key为URL对象后才能进入URL类中hashCode()方法,不然进入的就是Object中的hashCode()方法,对于小白这里很容易迷糊,比如我,继续跟进
来到了URL的hashCode()方法,可以看到这里值不为-1的话就直接返回了,所以值必须为-1,在这个类中它的值已经初始化好了
继续分析,下面这里对hashCode进行了处理,跟进handler对象的hashCode()方法
可以看到handler是URLStreamHandler的对象
可以看到在对hashCode进行处理时调用了getHostAddress()方法,这个方法可以获取IP地址
跟进这个方法,这里直接贴一位大佬带有注释的代码
1 | protected synchronized InetAddress getHostAddress(URL u) { |
从这里可以看出,如果你之前已经访问过dns的域名那么就不会出发第二次,我就是因为这个卡了半天还以为代码有问题,最后在下面这里发起DNS请求
后面具体怎么发起请求可参考Java反序列化漏洞之URLDNS利用链(7) | LeiH - Blog (leihehe.top)
执行程序可看到请求成功
利用链
HashMap.readObject()->HashMap.putVal()->HashMap.hash()->URL.hashCode()
总结
虽然这是Java反序列化最简单的一条链但是我一点都没感觉轻松,所以这篇分析还有很多不足之处,感觉自己手写分析之后再去看ysoserial上的URLDNS链会轻松很多,一开始直接拿那个链分析一直没进度