readObject 倾向于解决“反序列化时如何还原一个完整对象”这个问题,而PHP的 __wakeup 更倾向于解决“反序列化后如何初始化这个对象”的问题。

    Java反序列化不同于PHP反序列化,PHP反序列化漏洞产生的本质是各种魔术方法在特定场景下的触发,而Java反序列化则是实现需要显式的调用readObject和writeObject方法。

    如下面是Java中对可序列化对象的序列化和反序列化实现:

    1. package test.com;
    2. import java.io.*;
    3. public class Serializer {
    4. public static byte[] Serialize(Object obj) throws IOException {
    5. ByteArrayOutputStream out = new ByteArrayOutputStream();
    6. ObjectOutputStream objOut = new ObjectOutputStream(out);
    7. objOut.writeObject(obj);
    8. return out.toByteArray();
    9. }
    10. public static Object UnSerialize(byte[] data) throws IOException, ClassNotFoundException {
    11. ByteArrayInputStream in = new ByteArrayInputStream(data);
    12. ObjectInputStream objIn = new ObjectInputStream(in);
    13. return objIn.readObject();
    14. }
    15. }

    可以进行序列化和反序列化的类需要实现java.io.Serializable接口:

    1. package test.com;
    2. import java.io.IOException;
    3. import java.io.Serializable;
    4. public class SerializableTestClass implements Serializable {
    5. public String name;
    6. SerializableTestClass(String name) {
    7. this.name = name;
    8. }
    9. private void writeObject(java.io.ObjectOutputStream s) throws IOException {
    10. s.defaultWriteObject();
    11. s.writeObject("this is a test object");
    12. }
    13. private void readObject(java.io.ObjectInputStream s) throws IOException, ClassNotFoundException {
    14. s.defaultReadObject();
    15. String message= (String) s.readObject();
    16. System.out.println(message);
    17. }
    18. }

    序列化与反序列化:
    image.png