简述
ysoserial很强大,花时间好好研究研究其中的利用链对于了解java语言的一些特性很有帮助,也方便打好学习java安全的基础,刚学反序列化时就分析过commoncollections,但是是跟着网上教程,自己理解也不够充分,现在重新根据自己的调试进行理解,这篇文章先分析URLDNS
利用链分析:
调用链如上图所示,由hashmap的key进行hash计算时,如果key为URL类的对象,则调用key.hashcode实际为调用了URL类对象的hashcode,从而触发dns解析,这个手写exp也比较容易,设置hashCode为1为了putval时候重新计算hash,否则直接返回hashCode就触发不了dns解析了
工具介绍
IDEA
ysoserial jar : https://jitpack.io/com/github/frohoff/ysoserial/master-30099844c6-1/ysoserial-master-30099844c6-1.jar
ysoserial 源码:https://codeload.github.com/frohoff/ysoserial/zip/master
使用:
接下来我们对x.txt进行反序列化操作:
package Reflect; import java.io.*; public class readobject { public static void main(String[] args) throws IOException, ClassNotFoundException { ObjectInputStream o = new ObjectInputStream(new FileInputStream("C:/users/kuaile/desktop/x.txt")); Object o1 = o.readObject(); System.out.println(o1); } }
查看我们的dnslog
倒着来分析,为什么能够发起dns请求,来看urldns类文件
首先yso会调用getobjct方法,
URLStreamHandler,引用别人对这个类的理解。
一般而言, URL 的格式是: protocol://[authority]hostname:port/resource?queryString 。 URL 类能够解析出 protocol、 hostname 、 port 等信息。 Protocol 决定了交互规范,通用的协议,比如 HTTP 、 File 、 FTP 等协议, JDK 自带了默认的通讯实现。当然,自定义实现是允许的。 Hostname 和 port 一般用于 Socket 或者基于 Socket 其他协议通讯方式。Resource 即资源上下文。可能读者利用 URL ,通过指定协议( protocol )来获取指定资源的读写,比如 JDK 内置了HTTP 、 File 、 FTP 等协议的处理方法。
在成功地构造 URL 实例之后, URL API 中定义了一个 openConnection() 方法,返回一个 java.net.URLConnection 抽象类型的实例。不过,这里 URL 对象是代理对象,实际调用的是, java.net.URLStreamHandler 对象的 openConnection() 方法。
然后实例化了hashmap类,跟进去可以看到,有序列化接口,那就搜索readobject方法
看了一下他反序列化的代码,
先跟一下hash方法,参数为key, 如果key 是 null 就返回0 否则就返回 hashcode方法处理后的值和h右移再进行亦或
因为key是java.net.URL对象,我们的key值就是我们的url,就可以跟进一下其中url类的hashcode方法
判断hashcode 不等于-1 就返回,如果等于-1 就handler.hashcode,跟一下
调用了我们URL对象,
其中InetAddress.getByName(host);
含义就是相当于进行了一次dns请求
DEBUG跟了一下,
最后是再ser就是我们反序列化的值