top of page

How To Hack Deserialization for Fun and Profit

Hello everyone,

I am Nitin yadav(KD) back again with another write-up

What are deserialization attacks?

I'll try to tell you right away. Every day this topic is getting more and more famous. There are a lot of tutorials, articles, and blog posts about this topic.

Deserialization attacks are an attacker's way to make your computer do what it wants.

It is the type of vulnerability that can severely impact your application's security.

It arises when client-side JavaScript code deserializes the input data into the data structures.

This can leave a large amount of sensitive information in the hands of attackers like hackers who use it to access sensitive information such as credit cards, passwords, emails, and more.

In many programming languages, including Java, PHP, ASP.NET, and Python, it is necessary to represent arrays, lists, dictionaries, and other objects in a serialized data format that can be sent through streams and over a network and restored later.

This process is called serialization.

The final serialized format may be represented in binary or as structured text.

JSON and XML are two commonly used structured text formats used for serialization within web applications.

The reverse of the serialization process is called deserialization.

Deserialization takes serialized data from a source (a string, stored file, etc.) or network socket and turns it back into an object.

Deserialization attacks, or insecure deserialization, are the exploitation of vulnerabilities within the deserialization process by using untrusted data to abuse the logic of an application, access control, or even instigate remote code execution (RCE).

Deserialization example explained

Now let's understand the serialization and deserialization process in PHP to familiarize you with the concept before we move on to the offensive strategy.

Here's a simple class in PHP that we would like to serialize so we can deserialize it later:

Executing this script will serialize the PHP class to the following string:

Similarly, in Python, the same process can be performed with the default pickle serialization class, as demonstrated below:

The output will be an encoded string value:

Using the serialized string, we can store or transfer an array, object, or other complex data structure as a string representation.

By using unserialize, we can reverse the process and instantly access the array or object items.

Insecure deserialization

Insecure deserialization refers to a deserialization process in which the serialized string is converted back to its original object in memory by using untrusted user inputs.

Insufficient input validation can lead to logic manipulation or arbitrary code execution. Some common attack vectors in web applications that use serialization include:

1. Abusing an application’s logic operation that relies on serialized objects (i.e., purchase action)

2. Accepting user-supplied serialized objects in the cookies to identify a user

3. Using serialized objects as API authentication tokens

4. Transferring user data via Streams, WebSockets, or WebRTC channels

5. Executing serialized objects as inputs to execute commands in the file system

Many programming languages provide APIs and capabilities to perform native serialization and deserialization processes—but most of them include inherently unsafe operations, which could easily result in code execution depending on their application logic context.

For example, let’s assume our application uses PHP object serialization to determine user application privileges:

GET /login.php HTTP/1.0

Host: vuln.lab

Cookie: data=a:2: {s:8:”username”;s:4:”user”;s:4:”guid”s:32:”b6a8b…bc960”;}

Connection: close

And that the PHP server-side logic is as follows:

In this situation, an attacker could give itself administrator privileges by changing the cookie from

to the following serialized object:

PHP Object Injection

Two factors are required to successfully carry out attacks on PHP Object Injection vulnerabilities:

1. There must be an insecure implementation of the unserialize() method based on client input (i.e., cookies, stored serialized data, or serialized request parameters)

2. There must be a PHP magic method (e.g., __wakeup or __destruct) within the class that is vulnerable to being exploited to create our malicious payload or “POP Chain” (we’ll discuss this topic later)

In PHP, methods that begin with two underscores (__) are called “magic methods.” These magic methods play an important role in the application’s lifecycle, as they can be invoked during specific events.

There are 15 different magic methods:

__construct() __set() __toString()

__destruct() __isset() __invoke()

__call() __unset() __set_state()

__callStatic() __sleep() __clone()

__get() __wakeup() __debugInfo()

In PHP Object Injection attacks, we use magic methods to reconstruct our payload. Some magic methods are commonly used in serialization.

For example:

1. __sleep is called when an object is serialized and must be returned to an array.

2. __wakeup is called when an object is deserialized.

3. __destruct is called when a PHP script ends and the object is destroyed.

4. __toString is called to convert an object into a string.

PHP Object Injection with the magic method

Let’s look at an example where the user inputs proceed as a command using the __wakeup magic method. Consider the following vulnerable PHP code:

In this class, we see the implementation of a PHP magic method, __wakeup.

The script also declares a vulnerable unserialize() function. When both conditions are met, it can result in arbitrary PHP object(s) injection into the current application scope.

To create our payload, we can execute the following script:

This results in:

After URL encoding, our final payload will appear as:

Now we can append our payload as a data query string value:

GET /auth_check.php?data=O%3A13%3A%22InsecureClas… HTTP/1.0

Host: vuln.lab

Connection: close

As a result, the script will evaluate our payload command and return the phpinfo() output.

One important thing to keep in mind in PHP serialization is that the method is not serialized and will not be saved; only the name of the class and its properties are serialized.

Please notice, that the payload has been shortened for readability

Property oriented programming

The Property Oriented Programming (POP) technique can be used to create so-called POP chains that allow control over all the properties of a deserialized object.

In POP chains, magic methods are used as the initial “gadget”—a snippet of code borrowed from the codebase—and these gadgets can then be chained together to achieve our goal (i.e., code execution).

As a basic example, let’s assume we’ve found vulnerable code that implements the __destruct() magic method in our library as follows:

What this block of code does is define a class named LoggerIO—which inherits from a parent class IO—and implements the magic method __destruct().

This calls the removeFile() method internally.

In addition, it sets the filename property to a predefined string “log.txt.” To better understand the vulnerability impact of the removeFile() method, let’s inspect class IO:

Until now, our initial gadget is the __destruct() magic method, which calls the removeFile() method.

The removeFile() method then becomes our new gadget. Inspecting the destroy() method reveals its susceptibility to classic remote code execution (RCE) vulnerabilities.

To exploit this vulnerability, we need to change the value of the LoggerIO class property to a string such as “log.txt | touch hack.txt,” which will then allow us to execute a command using the destroy() method within the IO class.

To create our final POP chain, we can use the following script:

This will result in our final payload being submitted to the following serialized string: