Insecure Deserialization
Advanced Attack
Serialization
Serialization is the process by which some bit if data in programming lan-guage gets converted into a format that allows it to be saved in a DB ir trasferred over a Network
Deserialization
is the process of reconstructing data that has been serialized (converted into a specific format, often a sequence of bytes) back into its original form, such as objects or data structures. It involves taking serialized data and converting it back into an object or data structure that can be used in the program. Deserialization is crucial for retrieving stored or transmitted data and restoring it to its original state, allowing applications to work with the data as it was originally structured before serialization.
Risks of Insecure Deserialization
Insecure deserialization can lead to significant risks:
Remote Code Execution (RCE): Attackers can execute arbitrary code on the server, compromising its integrity.
Data Tampering: Serialized data can be manipulated to alter application logic or compromise data integrity.
Authentication Bypass: Allows attackers to bypass authentication mechanisms by tampering with session or credential data.
Denial of Service (DoS): Exploits can cause crashes or performance issues, disrupting service availability.
Privilege Escalation: Malicious objects may escalate privileges or gain unauthorized access.
Financial Loss and Reputation Damage: Resulting from breaches and loss of customer trust.
Serialization In Programming Language
PHP Serialization
When an application needs to store or transfer a PHP object over the network, it calls the PHP function serialize() to pack it up. when the application needs to use that data, it calls unserialize( ) unpack and get the underlying object
example how to add serialize in cookie
b: The_Boolean;
i: The_interger;
d: The_float;
s: Length_OF_String:"string";
a: Number_OF_Elements:{Elements};
O: Length_OF_Name:"Class_name":{properties}
The PHP code defines a User class with name and email properties. It demonstrates serialization by converting an instance of User into a string using serialize(), then deserializes it back into an object using unserialize(), displaying the reconstructed user's data.
PHP Magic Methods
PHP provides several magic methods that are crucial for customizing the serialization and deserialization processes:
__sleep()
: This method is invoked before serialization. It allows you to perform cleanup tasks, such as closing database connections and should return an array of property names that should be serialized.__wakeup()
: This method is called deserialization. It is used to reinitialize any resources or connections that were serialized along with the object, ensuring it operates correctly after deserialization.__serialize()
: Introduced in PHP 7.4, this method allows you to customize the serialization data by returning an array representing the object's serialized form. It provides fine-grained control over what data gets serialized.__unserialize()
: This method is the counterpart to__serialize()
. It allows you to customize the restoration of an object from its serialized data. This can include initializing properties or performing any necessary post-processing tasks.__destruct()
: method in PHP is a magic method that is automatically called when an object is no longer referenced or its script ends. It's used for cleanup tasks, such as closing files or database connections, releasing resources, or performing other actions that should be done when the object is no longer needed.
Java Serialization
Serialization in Java converts an object into a sequence of bytes, which can be easily stored or transmitted. It allows objects to be saved to files or sent over networks. By implementing the Serializable interface and using ObjectOutputStream, Java can serialize an object's state, which can later be deserialized back into its original form using ObjectInputStream.
Explanation:
MyClass Definition: Defines a simple
MyClass
that implementsSerializable
interface withname
andage
attributes.Serialization (main method):
Creates an instance
obj
ofMyClass
.Uses
ObjectOutputStream
to serializeobj
and write it toserialized_object.ser
.
Deserialization (main method):
Reads the serialized object from
serialized_object.ser
usingObjectInputStream
.Casts the read object to
MyClass
((MyClass) in.readObject()
) for type safety.Prints the deserialized object's attributes (
name
andage
) to verify successful deserialization.
Output:
The program outputs messages indicating the serialization and deserialization operations.
After deserialization, it prints the attributes of the deserialized object (
Name
andAge
).
This example demonstrates the complete process of serializing (ObjectOutputStream
) and deserializing (ObjectInputStream
) a Java object using Java's built-in serialization mechanism.
We will create Tow Files:
item.java -> hold code for a class name
Serialize.java -> which will contain the serialization logic
Item.java is a simple class that has two fields: id and name
Now, we will use another file (in Java one class should be contained in one file)
Using Some commands in Linux such as Strings or haxdump
the application For Java serialized Objects, you should also look for base64 strings starting with rO0AB
deserializtion
insecure deserialization Conditions
Executing OS commands in Java could be done
Example:
Ysoserial
Requerd:
java 8
update-alternatives --config java
-> switch version
.NET Serialization
Saving the states of objects using serialization in .NET can be done using various methods Example:
BinaryFormatter
DataContractSerializer
NetDataContractSerializer
XML Serialization
In .NET, there are several serialization techniques available, including binary serialization, XML serialization, JSON serialization, and custom serialization.
to make demo
requred:
windows
in search Turn window featuers on or off
Binary Serialization
How to Do Binary Serialization:
Mark the class as serializable by adding the
[
Serializable
]
attribute.Use the
BinaryFormatter
class to perform serialization and deserialization.
XML Serialization
XML serialization converts an object into XML format. It is useful for interoperability between different platforms and languages
JSON Serialization
JSON serialization converts an object into JSON format, which is both human-readable and efficient for web-based applications. The namespace is commonly used for JSON serialization in .NET Core and .NET 5/6+.
Custom Serialization (Using ISerializable
)
ISerializable
)By implementing the interface, custom serialization allows you to control how the object is serialized and deserialized. This method is used when you need to serialize non-serializable objects or need fine control over the process.
Example:
Gadget chains
Gadget chains involve leveraging pre-existing code snippets, or "gadgets," in an application to achieve exploitation during deserialization. By chaining these gadgets, an attacker can indirectly manipulate serialized data to invoke dangerous code paths.
Example of Gadget Chains
PHP Example;
imagine an attacker exploits a gadget chain in PHP, starting with a magic method like __wekeup()
Explanation:
GadgetA:
__wakeup()
method callstrigger()
onnext
.GadgetB:
trigger()
method executes the payload usingeval()
.Malicious Data: The attacker constructs a serialized chain that sets
next
to aGadgetB
object with a payload, leading to code execution.
Example in Java using ysoseial:
In Java, gadget chains can be constructed using libraries like Apache Commons Collections. The ysoserial tool automates this for known chains.
PHP Example Using PHPGGC:
Working with Pre-built Gadget Chains
Tools: Use tools like
ysoserial
for Java orPHPGGC
for PHP to generate serialized objects that exploit known gadget chains.Universal Chains: Use universal chains like
URLDNS
in Java for detection, triggering DNS lookups to confirm deserialization.Documentation: Look for documented exploits or pre-built chains online if a dedicated tool is unavailable.
Detecting Gadget Chains:
Universal Chains: Tools like
URLDNS
andJRMPClient
can help detect deserialization by causing detectable side effects like DNS lookups or TCP connections.Source Code Review: Manual inspection of available classes and their methods can reveal potential gadgets, especially focusing on magic methods like
__wakeup()
orreadObject()
.
Custom Gadget Chains:
Manual Construction: If no pre-built chain is available, analyze the application’s classes and methods to create a custom chain based on identified gadgets.
Using gadget chains, attackers manipulate serialized objects to pass data through a series of pre-existing methods, leading to dangerous operations. This often involves starting the chain with a magic method and using intermediate gadgets to funnel data into a "sink gadget" where the attack is realized.
ruby Serialization
Usage of Marshal.dump and Marshal.load
Marshal.load
Script to generate and verify the deserialization gadget chain against Ruby 2.0 through to 2.5
Universal Deserialisation Gadget for Ruby 2.x-3.x
Create Your Own Gadget Chain Exploit
Source Code Access: Obtain access to the application's source code. This is crucial for identifying classes that contain magic methods invoked during deserialization.
Identify Magic Methods: Search for classes with magic methods (
__wakeup()
,__destruct()
, etc.) that are automatically invoked during deserialization. These methods are potential entry points for your exploit.Assess Magic Method Code: Analyze the code within these magic methods. Determine if they directly dangerously manipulate user-controllable attributes. Even if they don't appear exploitable alone, they can serve as a starting point (kick-off gadget) for your gadget chain.
Follow Method Invocations: Study any methods invoked by the kick-off gadget. Look for methods that process or interact with user-controlled data. Each method invocation chain may lead you closer to a dangerous sink gadget where you can manipulate the data flow to achieve your exploit.
Track Data Access: Keep track of which attributes and values you have access to as you follow the method invocations. This helps in crafting the serialized object payload later.
Identify Sink Gadgets: A sink gadget is where your controlled data can cause significant harm. It could be a method that executes system commands, accesses sensitive files, or performs other risky operations based on its input.
Constructing the Payload: Once you've mapped out the gadget chain within the application code, create a serialized object containing your malicious payload. This involves crafting a valid serialized object format matching the source code's class declaration.
Serialization Formats: Depending on the language (e.g., PHP, Java), understand the serialization format you're working with. String-based formats (like PHP's
serialize()
output) is straightforward, but binary formats (like Java's serialized objects) may require deeper understanding and possibly custom serialization logic.Testing and Refinement: Test your exploit in a controlled environment to ensure it works as intended. Refine your gadget chain if necessary to optimize its effectiveness or to evade detection.
Secondary Vulnerabilities: Look for opportunities to exploit secondary vulnerabilities or weaknesses in the application's security posture as you construct your gadget chain. This could amplify the impact of your exploit.
PHAR Deserialization Attacks
PHAR (PHP Archive) files can be exploited for deserialization vulnerabilities in PHP, even without direct use of the unserialize() method. Here’s a detailed breakdown of how this exploitation works:
phar:// Stream Wrapper: PHP supports various URL-style wrappers for accessing different protocols via file paths. The
phar://
wrapper specifically provides a stream interface for interacting with PHP Archive files (.phar).Serialized Metadata: PHAR files contain serialized metadata in their manifest files. When you perform any filesystem operation on a
phar://
stream, PHP implicitly deserializes this metadata.Exploitation Vector: By manipulating a
phar://
stream and passing it into a filesystem method, you can potentially trigger insecure deserialization. Methods likefile_exists()
are less obviously dangerous compared to methods likeinclude()
orfopen()
, and may not have adequate protections.Upload and Execution: To execute this attack, you need to upload the PHAR file to the server. This can sometimes be achieved by disguising the PHAR file as another file type, such as a JPEG (polyglot file). PHP's stream handling does not check file extensions strictly, allowing the PHAR to be treated as an image file, bypassing validation checks.
Deserialization Trigger: Once the PHAR file is accessed via a
phar://
stream, PHP deserializes its metadata. If the object's class is supported by the website, this can trigger the execution of__wakeup()
or__destruct()
magic methods defined in the class.Magic Methods: Both
__wakeup()
and__destruct()
methods can be used as a starting point to initiate a gadget chain. These methods allow you to control the behaviour of the deserialization process, potentially leading to the execution of arbitrary code or further exploitation.
Example Scenario
Imagine a scenario where a website allows users to upload profile pictures. An attacker uploads a polyglot file that appears to be a harmless JPEG but is actually a PHAR file. When the website accesses this file using a phar://
stream for display or processing, PHP deserializes its metadata. If the attacker has crafted the PHAR to include malicious code in its __destruct()
method, this code could execute, leading to unauthorized actions on the server.
PHAR deserialization thus presents a stealthy and potentially dangerous avenue for exploiting insecure deserialization in PHP applications, leveraging PHP's inherent file-handling capabilities and relaxed stream validation.
Last updated