readObject 倾向于解决“反序列化时如何还原一个完整对象”这个问题,而PHP的 __wakeup 更倾向于解决“反序列化后如何初始化这个对象”的问题。
Java反序列化不同于PHP反序列化,PHP反序列化漏洞产生的本质是各种魔术方法在特定场景下的触发,而Java反序列化则是实现需要显式的调用readObject和writeObject方法。
如下面是Java中对可序列化对象的序列化和反序列化实现:
package test.com;
import java.io.*;
public class Serializer {
public static byte[] Serialize(Object obj) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream objOut = new ObjectOutputStream(out);
objOut.writeObject(obj);
return out.toByteArray();
}
public static Object UnSerialize(byte[] data) throws IOException, ClassNotFoundException {
ByteArrayInputStream in = new ByteArrayInputStream(data);
ObjectInputStream objIn = new ObjectInputStream(in);
return objIn.readObject();
}
}
可以进行序列化和反序列化的类需要实现java.io.Serializable接口:
package test.com;
import java.io.IOException;
import java.io.Serializable;
public class SerializableTestClass implements Serializable {
public String name;
SerializableTestClass(String name) {
this.name = name;
}
private void writeObject(java.io.ObjectOutputStream s) throws IOException {
s.defaultWriteObject();
s.writeObject("this is a test object");
}
private void readObject(java.io.ObjectInputStream s) throws IOException, ClassNotFoundException {
s.defaultReadObject();
String message= (String) s.readObject();
System.out.println(message);
}
}
序列化与反序列化: