Java序列化与反序列化


一、Java序列化和反序列化

1、序列化和反序列化的含义和用途

Java对象(存在于内存)———序列化——>>字符串/二进制流(存在于磁盘、网络)
Java对象(存在于内存)<<———反序列化——字符串/二进制流(存在于磁盘、网络)
这样做就是为了方便存储和传输,实现对象的持久化,方便协议解释

序列化主要使用场景

1、持久化内存数据
2、网络传输对象
3、远程方法调用(RMI)

序列化
java.io.ObjectOutputStream.writeObject()
反序列化
java.io.ObjectInputStream.readObject()
反序列化漏洞出现的原因

readObject()是可以进行重写的,如果我们重写了这个类,那么在代码中就不会去调用原始的readObject(),而是调用我们重写的readObject(),如果重写的readObject()中执行了一些敏感的方法,再加上一些参数可被控制就会造成漏洞
在这里插入图片描述
验证POC,确定一个程序是否有漏洞的操作,会打开一个计算器

public class UnsafeTest{}
    public static void main(String args[]) throws Exception{
    	UnsafeClass Unsafe = new UnsafeClass();
        Unsafe.name = "hacked by yy";
        //序列化
        FileOutputStream fos = new FileOutputStream("D: /yy.java");
        ObjectOutputStream os = new ObjectOutputStream(fos);
        os.writeObject(Unsafe);
        os.close();
        /从反序列化
        FileInputStream fis = new FileInputStream("D: /yy.class");
        ObjectInputStream ois = new ObjectInputStream(fis);
        UnsafeClass objectFromDisk = (UnsafeClass)ois.readObject();
        System.out. println(objectFromDisk.name);
        ois.close();
    }
    
}

如果我们运行上面的代码,进行序列化和反序列化时,计算器被打开,则证明漏洞存在(用来序列化的类是重写后的,加了Runtime)
如果有一个接口或程序,允许接受一个序列化字符串,然后去将其反序列化,那么我们可以自己构建一个恶意类,里面包含重写的readObject()方法,进行序列化,交给接口或程序去反序列化,就会因为传输来的类中有重写的readObject()方法,在反序列化时,会使用重写的方法,从而执行我们包含在其中的命令

实际上并没有这么简单,因为要知道服务器上有没有这个类(自己写的类不一定在别人的项目中存在),所以,我们需要去寻找在java中有没有一个现存的类,要求 重写了readObject()方法,然后还要有 存在参数能够控制,让我们的恶意代码让他去帮我执行的这样的类

1、重写类的readObject()方法
2、反序列过程中会执行自定义的readObject()


下一期

Apache Commons Collections 反序列化漏洞

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Whoam_laowei

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值