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");
}
}
浙公网安备 33010602011771号