序列化就是内存中的对象写入到 IO 流中,保存的 格式可以是二进制或者文本内容。反序列化就是O流还原成对象1.2 用途
1.3 实现方法
- 传输网络对象
- 保存Session
序列化 java.io.ObjectOutputStream 代表对象输出流,它的 writeObject() 方法可对参数指定的对象进行 序列化,把得到的字节序列写到一个目标输出流中。 反序列化 java.io.ObjectInputStream 代表对象输入流,它的 readObject() 方法从一个源输入流中读取字节序列,再把它们反序列化为一个对象,并将其返回。1.4 反序列化漏洞
1.5 利用思路**
- 如果某个类需要自定义反序列化方式,可以重写类的 readObject() 方法
- 在反序列化的过程中,会调用这个类中的重写的readObject()方法
- 如果readObject()方法的代码有一些敏感操作,就可能会引发漏洞(或者自定义的反序列方法)
- 利用自定义的readObject()方法执行代码
- 寻找重写了readObject()方法的类
利用 有没有重写了readObject()的 现成的 类?2. Apache Commons Collections 2.1 什么是CCAnnotationInvocationHandler
- package sun.reflect.annotation;
BadAttributeValueExpException
- package javax.management;
2.2 源码分析 2.2.1 InvokeTransformer
- 对JDK标准库的集合类进行了扩展,添加了一些数据结构,并且提供了工具类
- 2015年1月28日,有两个黑客发现了CC的漏洞利用链
2.2.2 ChainedTransformer
transform()方法可以通过反射机制来进行任意函数的调用
2.2.3 ConstantTransformer通过链式调用,实现InvokeTransformer方法的自动触发
public ContantTransformer(Object constantToReturn){
super();
iConstant = constantToReturn;
}
public Object transform (Object input){
return iConstant;
}
因为它是 Transformer的子类,所以可以加入到ChainedTransformer的数组参数里面去,并且用它的 new 方法返回一个 Runtime 类 。2.2.4 TransformedMap
思路:
Apache Commons Collections Apache Commons Collections Apache Commons CollectionsTransformedMap有一个功能,当Map里面的元素被添加、删除、修改的时候,自动调用
Transformer对象的transform方法,只要创建一个TransformedMap(用decorate()方法),往里面添加一个ChainedTransformer,它的transform方法就会被调用最后再找一个类,只要它在反序列化的时候会设置 map的值(setValue),那么就会自动触发map里面的Transformer数组的所有的transfrom方法,这个类AnnotationInvocationHandler
AnnotationInvocationHandler重写了readObject方法里面有一个Map的Entry对象,在序列化的时候会调用setValue。
只需要反序列化一个AnnotationInvocationHandler对象,在它的构造函数里面把前面构造好的TransformedMap传给它就行了
总结
1 、对利用类 AnnotationInvocationHandler 进行序列化,然后交给 Java 程序反序列化 2 、在进行反序列化时,会执行 readObject() 方法,该方法会用 setValue 对成员变量 TransformedMap 的 Value 值进行修改 3 、 value 修改触发了 TransformedMap 实例化时传入的参数 InvokerTransformer 的 checkSetValue——transform() 方法 4 、放到 Map 里面的是 InvokeTransformer 数组, transform() 方法被依次调用 5 、 InvokerTransformer.transform() 方法通过反射,调用 Runtime.getRuntime. exec("xx") 函数来执行系统命令



