java反序列化漏洞原理

1.首先是序列化的过程

序列化:  ObjectOutputStream类 --> writeObject()

将对象进行序列化,把字节序列写到一个目标输出流中.ser

2.反序列化

反序列化: ObjectInputStream类 --> readObject()

从一个源输入流中读取字节序列,再把它们反序列化为一个对象

 

如果序列化字节序列内容可控,那么即可执行恶意类

参考代码:

这段代码中exec本来是去序列化一个String类型对象,并存储序列化流文件,之后读取序列化流文件展示。

如果对象改变,变成一个恶意类evil,则反序列化,还原对象时则会还原成恶意类,而执行构造函数中的恶意代码

import java.io.*;

public class main {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        new main().exec();

    }

    public void exec() throws IOException, ClassNotFoundException {
        //String s="hello";
        evil s=new evil();
        byte[] ObjectBytes=serialize(s);
        File file = new File("test.ser");
        FileOutputStream fos = new FileOutputStream(file);
        fos.write(ObjectBytes);
        File file2 = new File("test.ser");
        FileInputStream fis = new FileInputStream(file);
        byte[] byteArray = new byte[(int) file.length()];
        fis.read(byteArray);
        String s2=(String)deserialize(byteArray);
        System.out.println(s2);
    }

    private byte[] serialize(final Object obj) throws IOException {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        ObjectOutputStream objOut = new ObjectOutputStream(out);
        objOut.writeObject(obj);
        return out.toByteArray();
    }

    private Object deserialize(final byte[] serialized) throws IOException, ClassNotFoundException {
        ByteArrayInputStream in = new ByteArrayInputStream(serialized);
        ObjectInputStream objIn = new ObjectInputStream(in);
        return objIn.readObject();
    }

}

  

import java.io.IOException;

public class evil {
    public evil() throws IOException {
        Runtime rt = Runtime.getRuntime();
        rt.exec("calc");
    }
}

  

posted @ 2023-06-29 18:32  妇愁者纞萌  阅读(68)  评论(0编辑  收藏  举报