在最近的攻防演习中遇到了许多java反序列化漏洞,但是每次都是直接exp打过去,耗时又费力。后来使用了ysoserial
的URLDNS
模块,批量检测后就精准打击了。所以这次结束后就来研究下其原理。
Java URL Class
Java的URL这个类的equal()
和hashCode()
会在调用的时候去获取域名解析的ip地址
> Two hosts are considered equivalent if both host names can be resolved into the same IP addresses
> https://docs.oracle.com/javase/8/docs/api/java/net/URL.html
详细的可以去康康源码,这里着重探究hashCode()
调用了一个handler
的类,从文档中得知,handler
是URLStreamHandler
所以跟进URLStreamHandler
可以看到调用了getHostAddress()
,这也就发起了dns
请求
HashMap
问题来了,既然hashCode()
能够发起dns
请求,那么怎么在反序列化的时候调用呢?这就用到了HashMap
HashMap
在readObject
的时候会调用putVal
,其中计算了key
的hash
值
计划通,把URL
当成key
就能调用到hashCode()
,发起dns
请求了
但是有个问题,在往HashMap
中put
元素的时候,已经调用过hashCode
了
这样hashCode
的值就会保存在实例中,远程反序列化的时候就会读取缓存,并不会调用hashCode()
所以需要将hashCode
的值重置,利用java反射就很容易实现了
|
|
URLStreamHandler
利用链已经完整了,但是有个小问题,在本地构造的时候会调用put
,会先发送dns
请求,影响检测的准确性。可以写一个类来重写getHostAddress
等函数
|
|
realworld
带个私货,花了点时间利用urldns
检测shiro
反序列化的小工具
https://github.com/LuckyC4t/shiro-urldns
参考
https://github.com/frohoff/ysoserial
https://blog.paranoidsoftware.com/triggering-a-dns-lookup-using-java-deserialization/