反序列化杂谈
0x00 前言
看了些shiro环境因为重写了resolveClass的方法导致很多链无法利用后,终于搞清楚了原理。所以想搞清楚反序列化底层究竟是怎么回事。基础打牢对后面的反序列化的问题才会有更深刻的认实。
0x01 使用场景
抓取数据包的时候,很多数据是非常直观的,所以使用场景内对参数的敏感程度非常重要。
1 | 1、 http参数,cookie,sesion,存储方式可能是base64(rO0),压缩后的base64(H4sl),MII((Media Independent Interface(介质无关接口);或称为媒体独立接口?没遇到过)等 |
0x02 readObject方法分析
在前面先贴一张readObject
的执行流程图,这是一张weblogic的反序列化执行流程图。第一个readObject
直接忽略,到下篇文weblogic再做讲解。
1 | resolveClass:686, ObjectInputStream (java.io) |
可以看到这里Class.forName不进行类的初始化,只是获得这个类对象。所以这里我们static代码块是不会被执行的。
接下来走出这个函数,走进这个函数,一看这个函数就是要初始化什么东西,我们再详细看看里面的参数的关键参数:
ObjectStreamClass Filed参数里面的Integer的age 和String类型的name;剩下的就是name和序列化的suid。
cl参数是一个class类,那关键的肯定是name参数和classloader,决定这个类是由哪个类加载器加载,这里可以很清楚的看到是应用类加载器。剩下的两个参数都是null。
这个方法一执行完,我静态代码块里的计算机就跳出来了。
就是里面的这句话。entry是个Object用来接收参数。
执行了一堆初始化,直到最后一句执行完才生成计算机。
我觉得是这个类的实例在生成的时候,内部类cl也要去实例化,导致的static代码块的触发。
回到readOrdinaryObject方法,这里将这个类newInstance()了,但是静态代码块的方法在前面就执行了。这里的newInstance是调用ObjectStreamClass的newInstance
然后在这个方法把序列化的数据填充进去
resolveClass这个方法究竟是做什么的?
将类的序列化描述符加工成该类的 Class 对象。