WEB渗透 - Java反序列化

Java序列化与反序列化是让 Java 对象脱离 Java 运行环境的一种手段,可以有效的实现多平台之间的通信、对象持久化存储。

什么是序列化和反序列化

简单来说

序列化就是把对象转换为字节序列(二进制),然后储存在内存中

对象 ——> 数据

序列化依赖 ObjectOutputStream 类的 writeObject() 方法


反序列化就是把字节序列从内存中的提取出来,然后反序列化为对象

数据 ——> 对象

反序列化依赖 ObjectInputStream 类的 readObject() 方法


一个类的对象要想序列化成功,必须满足两个条件:

该类必须实现 java.io.Serializable 接口。

该类的所有属性都是可序列化的。



漏洞成因

暴露或间接暴露反序列化 API ,导致用户可以传入精心构造的反序列化对象并执行恶意代码。



漏洞原理

第一种 重写readObject

Java序列化策略支持默认和用户自定义两种

自定义序列化规则的方式就是重写 writeObjectreadObject

重写后,java就会调用用户自定义的规则

readObject方法存在执行命令的机会,通过传入恶意代码,程序反序列化时 ObejctInputStream类的readObject方法就会触发漏洞



第二种 利用反射机制

Apache-CommonCollections REC

Apache-CommonsCollections包中,有一个 InvokerTransformer 类实现了Transformer接口,InvokerTransformertransform 方法可以通过Java反射机制,调用任意Java方法。

AnnotationInvocationHandler 对象的 readObject() 方法在反序列化时会触发 setValue() 函数,进而调用 checkSetValue 函数,然后进一步触发第一步构造的 ChainedTransformer.transform 方法——

ChainedTransformer 的 transform 方法会依次调用数组中 InvokerTransformer 的transform 函数,从而实现了( Java类加载函数调用链 )反射调用 Runtime.getRuntime().exec() ,触发命令的执行。

高于8u66的版本不支持AnnotationInvocationHandler,可以用BadAttributeValueExpException,9u4以下有效果,利用原理相同但方法不同,具体请查阅资料



Java反序列化漏洞历史悠久,这里我只举例了其中两种主要的,本人对java不是很有研究,如有错误敬请指出,谢谢。

猜你喜欢

转载自www.cnblogs.com/drac4ry/p/12921182.html