A Pentester’s Guide To Insecure Deserialization

Insecure deserialization is a critical vulnerability that goes unnoticed during security assessments, exposing applications to potential attacks. To help applications’ security posture and prevent potential data breaches, it is crucial to understand the basic concept of insecure deserialization, its implications and effective techniques. And this guide is an endeavour to present the vulnerability, advice, hands-on practice labs, fundamentals of insecure deserialization, and attack vectors thoroughly.

What is serialization?

Serialization is converting data structures or objects in a programming language into a format that can be easily stored, transmitted or reconstructed later. This is often necessary when data needs to be sent over a network or stored in a file. The serialized data can then be deserialized or converted back into the original data structure or object later. The process is commonly used in web applications, database systems and distributed systems.

The serialization process involves converting an object or data structure into a byte stream. This byte stream can then be transmitted over a network or stored on a disk. The byte stream represents the state of the object or data structure at a particular moment in time. The state includes the values of its variables, its methods and other information about the object.

Serialization is commonly used in web applications, database systems and distributed systems. In web applications, serialization is used to transfer data between a server and a client, often in the form of JSON or XML. In database systems, serialization is used to store data in a persistent format, allowing it to be accessed later. In distributed systems, serialization is used to transfer data between different nodes in a network.

The process of deserialization is the opposite of serialization. It involves converting the byte stream back into an object or data structure. This allows the object or data structure to be used again in the program or system.

 

Serialization vs Deserialization

The following table provides a brief comparison of features and attributes between serialization and deserialization:

 

Feature/Attribute

Serialization

Deserialization

Definition

Process of converting an object or data structure into a stream of bytes.

Process of converting the serialized stream of bytes back into an object or data structure.

Purpose

To store or transmit data over a network.

To reconstruct the original object or data structure from its serialized form.

Output

Stream of bytes.

Object or data structure.

Input

Object or data structure.

Stream of bytes.

Language support

Supported by many programming languages, including Java, C#, and Python.

Supported by many programming languages, including Java, C#, and Python.

Error handling

It may generate errors if there are issues with the object being serialized.

It may generate errors if there are issues with the serialized data being deserialized.

Performance

It can be slow if the object being serialized is large or complex.

It can be slow if the serialized data is large or complex.

Use case

Used to transmit data over a network, store data in a database or create object snapshots for debugging purposes.

Used to recreate objects from stored data, deserialized network messages, or load data from a database.

 

What is insecure deserialization?

Insecure deserialization is a vulnerability that arises when applications deserialize untrusted or malicious data without adequately validating or sanitising it. This can allow attackers to manipulate the serialized data to execute arbitrary code, bypass security controls, or conduct other malicious activities. Insecure deserialization attacks are often used to compromise web applications, APIs and other software systems that rely on serialization to transmit data. It is important to implement proper input validation and output encoding, use secure serialization libraries, and follow other best practices for secure software development to prevent insecure deserialization vulnerabilities.

How do insecure deserialization  vulnerabilities arise:

Insecure deserialization vulnerabilities arise when applications deserialize data tampered with by an attacker. Deserialization is the process of converting serialized data, which is a stream of bytes representing an object or data structure, back into its original form. When applications deserialize untrusted data without proper validation, insecure deserialization vulnerabilities can arise due to various factors, including using insecure serialization libraries, failing to validate input data or not properly encoding output data. In order to prevent these vulnerabilities, it is important to follow secure coding practices, use trusted libraries and implement input validation and output encoding.

 

Impact

The impact of insecure deserialization can be severe, as it can allow attackers to execute arbitrary code, bypass security controls and gain unauthorised access to sensitive data. Some of the common impacts of insecure deserialization vulnerabilities are:

  • Remote code execution (RCE):Attackers can use insecure deserialization to execute malicious code on the targeted system, which can result in the compromise of sensitive data or a complete system takeover.
  • Denial of Service (DoS):Attackers can send malformed or large serialized data to trigger resource exhaustion or crashes, leading to system downtime and disruption of critical services.
  • Tampering with data integrity:Insecure deserialization can allow attackers to modify serialized data to change its content or structure, leading to data integrity issues and unauthorised access to sensitive information.
  • Bypassing security controls:Attackers can use insecure deserialization to bypass authentication and authorisation mechanisms, allowing them to access restricted resources or perform unauthorised actions.
  • Data exfiltration:Attackers can use insecure deserialization to extract sensitive data from the targeted system and transmit it to a remote server, leading to data breaches and compromise of sensitive information.

 

How to identify insecure deserialization?

Identifying insecure deserialization vulnerabilities requires a comprehensive security testing approach, including manual and automated techniques. Here are some techniques that can help identify insecure deserialization:

  • Code Review:Reviewing the source code for the application can help identify potential insecure deserialization vulnerabilities. Look for code that uses serialization or deserialization libraries, and check for proper input validation and exception handling.
  • Fuzz Testing: Fuzz testing involves sending large amounts of input data to an application to identify vulnerabilities. Attackers can exploit vulnerabilities in the deserialization process by sending large and malformed serialized data. Fuzz testing can help identify such vulnerabilities before attackers exploit them.
  • Dynamic Analysis: Dynamic analysis involves monitoring the application during runtime to identify vulnerabilities. By intercepting network traffic and analysing data exchanged between the application and clients, security researchers can identify vulnerabilities in the deserialization process.
  • Vulnerability Scanning:Vulnerability scanning tools can help identify insecure deserialization vulnerabilities in applications. These tools can identify known vulnerabilities in the application and suggest remediation steps.
  • Manual Testing:Manual testing involves attempting to exploit vulnerabilities in the application. By crafting and sending specially crafted serialized data, security researchers can identify vulnerabilities in the deserialization process.

 

PHP serialization format

Suppose we have a PHP object that looks like this:

 

 

We can serialize this object using the serialize() function:

The output of this code will be:

Here’s what this serialized string means:

O:4:”User”:2: – This indicates that the serialized data is an object (O), with a class name of User, and has 2 properties.

s:4:”name”; – This indicates that the first property is a string (s), with a length of 4 characters, and has a value of “name”.

s:8:”John Doe”; – This indicates that the value of the “name” property is a string (s), with a length of 8 characters, and has a value of “John Doe”.

s:3:”age”; – This indicates that the second property is a string (s), with a length of 3 characters, and has a value of “age”.

i:30; – This indicates that the value of the “age” property is an integer (i), with a value of 30.

To unserialize this data, we can use the unserialize () function:

 

 

The output of this code will be:

This recreates the original User object with the values “John Doe” and 30 for its properties.

In PHP, serialization is the process of converting a PHP object into a string that can be stored or transmitted over a network. PHP provides two functions for serialized and unserialized objects:

  • Serialize () – This function takes a PHP object and returns a string that represents the serialized data of the object.
  • Unserialize () – This function takes a serialized string and returns the corresponding PHP object.

 

Java serialization format

The Java serialization format is binary and platform-independent. It includes information about the class of the serialized object, as well as the values of its non-transient and non-static fields. The format is designed to be extensible, so it can handle changes to the class definition between the serialization and deserialization phases.

In this example, the Person class implements the Serializable interface, which indicates that its instances can be serialized. The printDetails() method is not part of the serialization process.

The main() method creates a new Person object and sets its fields. It then creates a FileOutputStream and an ObjectOutputStream to serialize the object to a file named person.ser. Finally, it closes the output streams and prints a message indicating where the serialized data was saved.

 

When this program is run, it will create the file person.ser with the following contents:

This is the binary Java serialization format for the Person object. It contains the class name (Person) and a sequence of data elements, each preceded by a type code. In this case, the type codes are 5 for age, t for name, and q for address. The values of these fields are encoded in a format specific to their type (e.g., Ljava/lang/String; for the name and address fields).

 

Practice Labs

 

Modifying serialized objects

  1. Log in using your own credentials. Take note that the GET/my-account request after login includes a session cookie that appears to be URL and Base64-encoded.

 

  1. Utilise Burp’s Inspector panel to analyze the request in its decoded form. Notice that the cookie is, in fact, a serialized PHP object. Pay attention to the admin attribute, which currently holds the value b:0, indicating the boolean value false. Forward this request to Burp Repeater.
  2. In Burp Repeater, utilise the Inspector to examine the cookie once again. Modify the value of the admin attribute to b:1. Apply the changes by clicking on “Apply changes”. The altered object will be automatically re-encoded and updated in the request.

 

  1. Dispatch the request. Observe that the response now provides a link to the admin panel located at /admin, indicating that you have gained access to the page with admin privileges.

 

Practice Lab Links:

As a team of Advanced Penetration Testers and Security Researchers, we firmly believe in a hands-on approach to cyber security.

PortSwigger

 

 

Mitigations and Best Practices

To prevent insecure deserialization vulnerabilities, it is important to follow secure coding practices and implement the following measures:

  • Input validation: Validate and sanitize all input received by the application to prevent malicious input from being processed by the application.
  • Implement secure serialization: Use secure serialization techniques that ensure the integrity of serialized data and prevent attackers from tampering with the serialized data.
  • Implement secure deserialization: Use secure deserialization techniques that prevent attackers from injecting malicious code into the application by manipulating the serialized data.
  • Implement access controls: Implement access controls to prevent unauthorized access to sensitive data and functions.

 

  • Ankit Kumar

Consultant – Cyber Security

Quick Enquiry

Wordpress Social Share Plugin powered by Ultimatelysocial