Introduction
Insecure deserialization is a critical security vulnerability that arises when an application processes untrusted data without proper validation during the deserialization process. This can allow attackers to manipulate serialized objects and potentially alter the applicationโs logic or gain unauthorized access. In this blog, we will explore the PortSwigger lab “Using application functionality to exploit insecure deserialization,” where we take advantage of legitimate application features to manipulate serialized objects and successfully exploit the vulnerability. We’ll walk through the steps to understand, identify, and exploit insecure deserialization in a practical environment.
Understanding Magic Method
In some cases, attackers have to manually invoke dangerous methods via accessible functionality. However, insecure deserialization becomes much more interesting when exploits can automatically trigger dangerous methods. This is enabled by the use of “magic methods.โ
What is Magic Method
Magic methods are a special subset of methods that you do not have to explicitly invoke. Instead, they are invoked automatically whenever a particular event or scenario occurs. Magic methods are a common feature of object-oriented programming in various languages. They are sometimes indicated by prefixing or surrounding the method name with double-underscores.
Developers can add magic methods to a class in order to predetermine what code should be executed when the corresponding event or scenario occurs. Exactly when and why a magic method is invoked differs from method to method. One of the most common examples in PHP is __construct(), which is invoked whenever an object of the class is instantiated, similar to Python’s init. Typically, constructor magic methods like this contain code to initialize the attributes of the instance. However, magic methods can be customized by developers to execute any code they want.
Magic methods are widely used and do not represent a vulnerability on their own. But they can become dangerous when the code that they execute handles attacker-controllable data, for example, from a deserialized object. This can be exploited by an attacker to automatically invoke methods on the deserialized data when the corresponding conditions are met.
Most importantly in this context, some languages have magic methods that are invoked automatically during the deserialization process. For example, PHP’s unserialize() method looks for and invokes an object’s __wakeup() magic method.
In Java deserialization, the same applies to the ObjectInputStream.readObject() method, which is used to read data from the initial byte stream and essentially acts like a constructor for “re-initializing” a serialized object. However, Serializable classes can also declare their own readObject() method as follows:
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
{
// implementation
}
A readObject() method declared in exactly this way acts as a magic method that is invoked during deserialization. This allows the class to control the deserialization of its own fields more closely.
You should pay close attention to any classes that contain these types of magic methods. They allow you to pass data from a serialized object into the website’s code before the object is fully deserialized. This is the starting point for creating more advanced exploits.
Challenge
This lab uses a serialization-based session mechanism. A certain feature invokes a dangerous method on data provided in a serialized object. To solve the lab, edit the serialized object in the session cookie and use it to delete the morale.txt
file from Carlos’s home directory.
You can log in to your own account using the following credentials: wiener:peter
You also have access to a backup account: gregg:rosebud
Walkthrough
Step 1: We will log in to the application using the default credentials provided. This will help us observe the application’s normal behavior and capture the login request for further analysis.
Step 2: In the login request, we can clearly see the cookie, which looks similar to the previous lab. This indicates that the cookie is serialized.
Step 3: After logging in, we are redirected to the user’s dashboard. As per the lab instructions, our goal is to delete the morale.txt file. To achieve this, we will intercept the “Delete account” request and manipulate the serialized cookie.
Step 4: We intercept the “Delete Account” request and send it to Burp Suite Repeater. Since the cookie contains serialized data, we modify it in the Repeater to exploit the insecure deserialization vulnerability and attempt to delete the morale.txt file.
Step 5: We decoded the serialized cookie: Tzo0OiJVc2VyIjozOntzOjg6InVzZXJuYW1lIjtzOjY6IndpZW5lciI7czoxMjoiYWNjZXNzX3Rva2VuIjtzOjMyOiJjZGd2Z2F6am4xNDU2NHFtMDYweGs1cm0wbTNxbDJwcCI7czoxMToiYXZhdGFyX2xpbmsiO3M6MTk6InVzZXJzL3dpZW5lci9hdmF0YXIiO30%3d
After decoding, we received the following object:
O:4:"User":3:{s:8:"username";s:6:"wiener";s:12:"access_token";s:32:"cdgvgazjn14564qm060xk5rm0m3ql2pp";s:11:"avatar_link";s:19:"users/wiener/avatar";}
This is a PHP serialized object where we can see the user’s details, such as username, access token, and avatar link. We will manipulate these values to exploit the deserialization vulnerability.
Step 6 We modify the user information by changing the username from “wiener” to “carlos” and update the avatar link. The avatar link is modified from /users/wiener/avatar
to the new path /home/carlos/morale.txt
in Carlos’ home directory. The serialized data for the user object is as follows:
O:4:"User":3:{s:8:"username";s:6:"carlos";s:12:"access_token";s:32:"cdgvgazjn14564qm060xk5rm0m3ql2pp";s:11:"avatar_link";s:23:"/home/carlos/morale.txt";}
Finally, this modified serialized data is encoded back into base64.
Step 7: Now, replace the old cookie with the newly created one in the Repeater and send the request. Unfortunately, the lab was not solved here, but we got some access tokens. For now, try each token one by one by sending the requests. The correct token will trigger the deletion of the morale.txt
file in Carlos’ home directory.
Note:
Don’t be confused about where to modify and input the access token.
In the following serialized data, the bold part is where you need to replace the access token:
{s:8:"username";s:6:"carlos";s:12:"access_token";s:32:"**cdgvgazjn14564qm060xk5rm0m3ql2pp**";s:11:"avatar_link";s:23:"/home/carlos/morale.txt";}
Replace the bold access token and then try sending the request.
Step 8: After multiple attempts, we successfully sent the request. Although the response was a 500 Internal Server Error, which typically indicates a server issue, the web application lab was marked as solved. This suggests that, despite the error response, the underlying action of deleting the morale.txt
file in Carlos’ home directory was successful. The server error might be a result of the deletion process or some other internal server mechanism, but the objective of the labโremoving the fileโwas achieved.