在最近的攻防演习中遇到了许多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/