1Java反序列化漏洞背景介绍
简单来说序列化是将对象状态转换为可保持或传输的格式的过程(bytestream)。与序列化相对的是反序列化,它将流转换为对象。这两个过程结合起来,可以轻松地存储和传输数据。
1.1Java序列化
1.Java提供了一种对象序列化的机制,该机制中,一个对象可以被表示为一个字节序列,该字节序列包括该对象的数据、有关对象的类型的信息和存储在对象中数据的类型
2.将序列化对象写入文件之后,可以从文件中读取出来,并且对它进行反序列化。对象的类型信息、对象的数据,还有对象中的数据类型可以用来在内存中新建对象
3.整个过程都是Java虚拟机(JVM)独立的,在windows上序列化的对象可以在centos上反序列化该对象,该过程是跨平台的。
4.类ObjectInputStream和ObjectOutputStream是高层次的数据流,它们包含序列化和反序列化对象的方法
首先定义一个Person类,该类实现了Serializable接口。
importjava.io.Serializable;
publicclassPersonimplementsSerializable
{
privateStringname;
privateintage;
publicPerson(){
}
publicPerson(Stringstr,intn){
System.out.println(InsidePersonsConstructor);
name=str;
age=n;
}
StringgetName(){
returnname;
}
intgetAge(){
returnage;
}
}
一个类想要序列化成功必须要满足的条件有
1.该类必须实现java.io.Serializable对象
2.该类的所有属性必须是可序列化的。如果有一个属性不是可序列化的,则该属性必须注明是短暂的(仅存在于内存中)
3.判断一个Java标准类是否是可序列化的,只需要查看文档中该类有没有实现java.io.Serializable接口
ObjectOutputStream类用来序列化一个对象,writeObject()方法可以实现序列化。下面是使用ObjectOutputStream类的writeObject()方法进行序列化的示例代码。将Person类序列化到myPerson.ser中
当序列化一个对象到文件时,按照Java的标准约定是给文件一个.ser扩展名
publicvoidsavePerson()
{PersonmyPerson=newPerson(Jay,24);try{FileOutputStreamfos=newFileOutputStream(E:\\myPerson.ser);ObjectOutputStreamoos=newObjectOutputStream(fos);System.out.println(Person--Jay,24---Written);System.out.println(Nameis:+myPerson.getName());System.out.println(Ageis:+myPerson.getAge());oos.writeObject(myPerson);oos.flush();oos.close();}catch(Exceptione){//TODO:handleexceptione.printStackTrace();}}
1.2Java反序列化ObjectInputStream类的readObject()方法用于反序列化,下面是进行反序列化的实例代码。从myPerson.ser文件当中读取序列化后的内容并恢复到了Person类当中。publicvoidrestorePerson()
{try{FileInputStreamfis=newFileInputStream(E:\\myPerson.ser);ObjectInputStreamois=newObjectInputStream(fis);PersonmyPerson=(Person)ois.readObject();System.out.println(\n--------------------\n);System.out.println(Person--Jay,24---Restored);System.out.println(Nameis:+myPerson.getName());System.out.println(Ageis:+myPerson.getAge());}catch(Exceptione){//TODO:handleexceptione.printStackTrace();}}
平常状况下正常的数据流被反序列化的时候产生的是预期的正常的对象。
但是当在进行反序列化的时候,被反序列化的数据是被经过恶意静心构造的,此时反序列化之后就会产生非预期的恶意对象。这个时候就可能引起任意代码执行。而ObjectInputStream这个类就是在具体工作中负责反序列化,当执行readObject()代码的时候,会读取被序列化之后的bytestream,由于Java的特性,虽然这个读入的object最终会在类型转换时出现classcastexception,但这个对象事实上已经创建了,其构造函数和类构造函数都已经被调用,也就是事实上已经有了受限制的函数执行。并且它没有对生成的对象的类型做任何限制这就为任意代码执行增加了可能。
2通过ApacheCommonsCollections利用反序列化漏洞简析
Ysoserial工具在生成payload的时候支持生成4种payloadApacheCommonsCollections3和4,Groovy,Spring,只要目标应用的ClassPath中包含这些库,ysoserial生成的payload即可让readObject()实现任意命令执行。影响比较广泛的就是ApacheCommonsCollections这个库,我们着重介绍一下通过ApacheCommonsCollections构造的利用。
2.1CommonsCollections简介
TheJavaCollectionsFrameworkwasamajoradditioninJDK1.2.ItaddedmanypowerfuldatastructuresthatacceleratedevelopmentofmostsignificantJavaapplications.Sincethattimeithasbe白癜风丸零售价格是多少元什么原因导致白癜风