What is Deserialization?
Serialization is the process of converting an object into a byte stream, which can be transferred over the network or stored in a file. Deserialization is the reverse process of converting that byte stream back into a Java object.
In Java, this is typically done using the ObjectInputStream
class, which reads the byte stream and reconstructs the object.
Here’s an example of how deserialization works in Java
import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.io.Serializable;
public class DeserializeExample {
public static void main(String[] args) {
try {
FileInputStream fileIn = new FileInputStream("serialized_object.ser");
ObjectInputStream in = new ObjectInputStream(fileIn);
MyObject obj = (MyObject) in.readObject();
in.close();
fileIn.close();
System.out.println("Deserialized object: " + obj);
} catch (Exception e) {
e.printStackTrace();
}
}
}
class MyObject implements Serializable {
private static final long serialVersionUID = 1L;
String name;
}
In this code, an object of MyObject
is deserialized from a file. However, if this serialized data is manipulated, it could lead to serious security vulnerabilities
Exploiting Java Deserialization Vulnerabilities
Attackers can exploit deserialization vulnerabilities by crafting malicious serialized objects that, when deserialized, trigger the execution of malicious code. This can happen because when an object is deserialized, constructors or special methods like readObject
are invoked, which can be controlled by an attacker.
Here’s a simplified example of how deserialization could be exploited:
- Attacker-controlled serialized data: An attacker sends a serialized object (as part of an HTTP request, for example) that contains malicious code.
- Deserialization in the application: The application blindly deserializes the data without proper validation.
- Arbitrary code execution: The attacker’s payload is executed during deserialization, leading to potential remote code execution (RCE).
Example of a vulnerable code snippet
import java.io.*;
public class VulnerableDeserialization {
public static void main(String[] args) {
try {
byte[] serializedData = getInputFromUser(); // Untrusted input
ByteArrayInputStream bis = new ByteArrayInputStream(serializedData);
ObjectInputStream ois = new ObjectInputStream(bis);
Object obj = ois.readObject(); // Vulnerable deserialization
System.out.println("Deserialized object: " + obj);
} catch (Exception e) {
e.printStackTrace();
}
}
private static byte[] getInputFromUser() {
// Simulated input, in reality, it could come from a file or network
return new byte[0];
}
}
Ddd