Today I am going to give you a good understanding of one of the top 10 listed vulnerabilities in OWASP web category: Insecure Deserialization. We will be covering the basic concepts of serialization and deserialization to all the way to the exploitation part.
So let’s not waste more time and directly dive into it.
Insecure Deserialization is a hidden threat lurking within the very data structures that power modern web applications. It often gets unnoticed while the vulnerability has the potential to wreak havoc on the entire application.
Before jumping on the vulnerability itself it is important to understand a few programming concepts associated with the vulnerability itself.
It refers to the process of converting data or objects in a computer program into a format that can be easily stored, transmitted, or reconstructed at a later time. This serialized data is typically a sequence of bytes used for various purposes.
Deserialization is the reverse process of serialization, where it involves rebuilding the serialized data structure into its original format.
Both of the process are illustrated in the following figure:
Insecure Deserialization issue arises when an application or a system does not properly validate and sanitize the data that is being deserialized. Here the application blindly trusts and processes the serialized data from untrusted sources.
Let’s illustrate the issue with an example:
Suppose you have a Python application that deserializes data from a file:
import pickle def load_data(filename): with open(filename, 'rb') as file: data = pickle.load(file) return data user_data = load_data('user_data.pickle')
Now here suppose an attacker replaces the ‘user_data’ with a malicious payload like os.system(“ls”), they can execute arbitrary code on your system.
Insecure Deserialization vulnerability can be used by attackers to perform various malicious activities including Remote Code Execution (RCE), data tampering, denial of service and more.
Now let’s move on to the solution writeup of the CTF challenge hosted by SecurityBoat on its Cyber Security Awarness Month 2023
Above shown is the home page of the vulnerable application which does not seem to have much functionalities except for the one located on the top right corner of the application i.e. light Mode.
Let’s first look into the hint provided by us which is nothing but a php code snippet on which the application is running. The code consists of a class named GetThemeNameFromFile which implements a __tostring() function which returns the filename using the file_get_contents() function in the form of a string.
The above PHP code checks whether the dark mode is on or not and deserializes the base64 decoded cookie data using the unserialize() function if the dark mode is on, else it serializes the cookie data further encoding it in base64 format.
On inspecting the cookies involved we can see that the dark_mode key has a value czo1OiJsaWdodCI7 which looks like a base64 encoded string.
On decoding the same using any decoding tool we can observe that the data is in serialized format and the language associated with the specific format is PHP. Here we have used cyberchef.
Later on navigating to the index.php page we saw that the unserialized value of the dark_mode cookie which is $darkModeData is being echoed out as a string and hence we can further verify that the payload is getting executed and we can read the server files hence we can further navigate to the location of the stored flag.
Now as we know that the application serializes the value using PHP language we can easily create a script of our own to exploit. Here we have written a script to obtain the flag stored in /etc/flag location.
The above script takes the contents of the /etc/flag file in the GetThemeNameFromFile class and then further serializes it and encodes it into base64 format.
On running the script we got a base64 encoded value which could be replaced with the original dark_mode’s value. And on refreshing the page we can see the flag which indicates the successful exploitation.
Input Validation: Validate and sanitize all incoming data, especially data used in deserialization.
Implement Access Controls: Enforce access controls to restrict who can perform deserialization and what they can deserialize.
Input Whitelisting: Implement input whitelisting, which allows only known, safe classes and objects to be deserialized.