Insecure Deserialization¶
Insecure deserialization vulnerabilities happen when applications deserialize program objects without proper precaution. An attacker can then manipulate serialized objects to change the program's behavior.
Serialization:
Converting data from a programming language into something that can be stored into a database on transmitted across a network.
Deserialization:
The process of returning the serialized data back into something a programming language can understand.
Found in Java, PHP, Python, Ruby, C#, etc... Developers tend to trust serialized data because it is not simple to manipulate, therefore the developer does understand the risks.
Language¶
PHP¶
Base64 Signature¶
Tzo0OiJ
Example¶
This example creates a serialized user object. It shows the serialized user, it also shows the execution of the four most useful magic functions and when they take place.
<?php
class User{
public $username;
public $status;
function __wakeup() {
echo shell_exec('ls -la');
}
function __destruct() {
echo shell_exec('whoami');
}
function __toString() {
return shell_exec('echo $(hostname)');
}
function __call($name, $args) {
echo shell_exec('ping -c 1 127.0.0.1');
}
}
$user = new User;
$user->username = 'vickie';
$user->status = 'not admin';
$serialized_string = serialize($user);
echo "*** Serialized user:\n" . $serialized_string . "\n";
echo "\n*** Executing the wakeup magic function\n";
$unserialized_data = unserialize($serialized_string);
echo "\n*** Unserialized user:\n";
echo var_dump($unserialized_data);
echo var_dump($unserialized_data->status);
echo "\n*** Executing the toString magic funciton\n";
echo $unserialized_data;
echo "\n*** Executing the call magic funciton\n";
$unserialized_data->undefined();
echo "\n*** Executing the destruct magic funciton\n";
?>
Running the code:
php serialize_user.php
Structure of serialized object¶
b:THE_BOOLEAN;
i:THE_INTEGER;
d:THE_FLOAT;
s:LENGTH_OF_STRING:"ACTUAL_STRING";
a:NUMBER_OF_ELEMENTS:{ELEMENTS}
0:LENGTH_OF_NAME:"CLASS_NAME":NUMBER_OF_PROPERTIES:{PROPERTIES}
Magic Methods¶
__wakeup()
: Executed when deserialized__destruct()
: Executed when no reference remains__call()
: Executed when an undefined method is called__toString()
: Executed when the object is treated like a string
Java¶
For Java objects to be serializable, their classes must implement the java.io.Serializable
interface. They must also implement the writeObject()
and readObject()
to perform the serializing and deserializing.
Use ysoserial
for exploitation: https://github.com/frohoff/ysoserial
Signature¶
rO0
- base64
AC ED 00 05
- Binary
Example¶
This creates a serialized user object and saves it in object.ser
. It then reads from the object.ser
file to deserialize the object.
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.Serializable;
import java.io.IOException;
class User implements Serializable{
public String username;
}
public class SerializeTest{
public static void main(String args[]) throws Exception{
User newUser = new User();
newUser.username = "vickie";
FileOutputStream fos = new FileOutputStream("object.ser");
ObjectOutputStream os = new ObjectOutputStream(fos);
os.writeObject(newUser);
os.close();
FileInputStream is = new FileInputStream("object.ser");
ObjectInputStream ois = new ObjectInputStream(is);
User storedUser = (User)ois.readObject();
System.out.println(storedUser.username);
os.close();
}
}
You can check the signature by doing this:
Base64 - it should begin with rO0
:
cat object.ser | base64
Binary - it should begin with AC ED 00 05
:
xxd object.ser
Ruby¶
Marshal.load()
Python¶
Signature¶
KG
orY3B
- Base64 Python 2gASV
- Base64 Python 3
Prevention¶
Do not deserialize untrusted data. If this is required, white-list the object classes that can be created by the deserialization before the object is deserialized.
Use JSON or some other "safe" library for serialization and deserialization.