Broken Access Control w/ IDOR concept
OWASP Top10 series
Hello hackers and welcome to this new episode based on OWASP top10 vulnerabilities series. In this post, I will teach a thing or two on Insecure Deserialization vulnerability.
This goes as follows:
To know this, lets try to grasp the bigger picture here. When you are learning how to program, one of the first thing you will come across is how to define variables, data structures, and classes which fits your needs. Forward from this, you will learn how to manipulate them to achieve the requirements you want. Let’s go a step back, as so far these things reside in memory, but eventually you might want to share these with another system and that’s where serialization and deserialization comes to play.
So let’s say for e.g. you are playing as a toon in your favorite video game. While the toon can be seen on your screen, software tend to see and manipulates the objects that are residing in the memory.
Now we can ask, what if the game wants to store the state of that toon in a file or want to share it to an another system? surely there must be a way to transform these in-memory objects into some stream of bytes to be easily shared. Surprise, you just have learnt what serialization is all about!. When the game performs a serialization of the toon object that resides in the memory, we can say the object is serialized.
You definitely got that right fella hackers, in fact, it consist of conversion of serialized data into in-memory presentation that a software can see and manipulate.
Absolutely wrong! Let me explain it, when a software is gonna deserialize any data that is being controlled by a user without any sort of verification mechanism, we call his insecure deserialization. So to relate, lets take a look back at our video game scenario, in this case, a malicious attacker can definitely store malicious payload on a serialized file and since there is no verification being done before deserializing it, the insecure deserialization process will trigger this malicious code.
Bet this sounds juicy for a hacker now right? I love it too!!
In this part, we will dive into some basic technical concepts which can help you explore further so feel free to follow along!
Usually you find insecure deserialization in various programming languages but for the sake of simplicity, we will dive into PHP, and Java.
This is also known as PHP object injection where it takes advantage on magic functions like
__destruct. To say it simple, this vulnerable code defines a dangerous code block of a certain class in this function, and it then proceeds to perform an insecure deserialization elsewhere. For example, I would like to explain how a possible serialized based session is vulnerable to a privilege escalation as a result. I will be using one of Portswigger labs under insecure deserialization which id highly recommend you to use and follow along. The requirement of this lab was to modify the serialized object in the session cookie to privilege escalate and gain admin rights to delete an user account. So let’s get into it!
Upon login in with your user credentials, you can notice on your post-login
GET request, that a session cookie seems to exist which is encoded in URL and in Base64. You can verify this by sending the cookie value into decoder.
Switch over to your decoder tab, and decode the cookie value to URL and then to Base64 which will reveal that the cookie is a PHP serialized object
If you hadn’t noticed, the admin attribute value contains
b:0, which indicates to us that its a boolean value that’s set as false, and since this is modifiable we change this to
b:1 and encode it back to Base64 and then to URL which gives us a new amended encoded string.
Now, we head back to our repeater tab and modify the existing cookie session value with our newly generated URL encoded string. If we send the request now with our modified cookie value, we can notice our account now contains an Admin panel option.
All we really have to do now, is to change the path of the request to
GET /admin and send the request to view all the users
Lastly, to meet the lab objective, we just need to modify the request to
GET /admin/delete?username=carlos to delete the user.
This example will demonstrate a Java deserialization vulnerability by developing a custom gadget chain.
Before we dive in, id like to explain what really is a “gadget” here in this example. We can consider a “gadget” to be a snippet of a code that resides in your applications which aids malicious attackers to achieve a particular goal. While a gadget itself cant do anything dangerous with any inputs via users, it can be used by malicious attackers to invoke methods which passes inputs into another gadget, so by chaining multiple gadgets this way, it is very possible for attackers to maximize their damage.
This example uses a serialized based session mechanism as well but by constructing a gadget chain, we can exploit this labs insecure deserialization to obtain admin password. By saying that, lets dive into it!
As per our go to, lets login into your account with our credentials and check our requests and we notice our session value id consist of a serialized Java object.
Also while we doing this, we have our sitemap running at the background and we manage to find a rather suspicious page which is
ProductTemplate.java. From further inspection, we can derive that
ProductTemplate.readObject() method does actually pass the
id attribute into a SQL statement. We can send this page to repeater and send a request to identify this.
Since now we have confirmed this, we can actually write a very small Java Program that instantiates a ProductTemplate with an random
id, serialize it and further Base64 encode it.
As you can see on the image above, we created a ProductTemplate with the id set to a single apostrophe. We compile this and copy the Base64 string and submit it in a request as your session cookie. The error that prompts will confirm that the website is indeed vulnerable to SQL injection via a serialized object.
As we now know this application is indeed vulnerable to SQL injection, we can use the id attribute to perform a very simple UNION attack on the users table. This can be done by enumerating for columns and observe the columns that aren’t expecting a string. Which results to a final payload as:
' UNION SELECT NULL, NULL, NULL, cast(password as numeric), NULL, NULL, NULL, NULL FROM users--
With the final payload created, now we can edit the template again with our payload and further encode it and replace it back in our repeater cookie session value.
Noticed how severe it can be when we chain gadgets the right way? it leaked password credentials which we can now login with as admin and delete the account!
When finding for Java Deserialization look for r00AB on a Base64 string in an application, always try to persue it and test it against insecure deserialization.
As you have seen from these examples, it is safe to say that a well crafted successful attack can lead to impacts that will damage confidentiality, Integrity, and availability. Even if attackers can’t build the right payload to serialize, it is very much possible to trigger any error exceptions that can crash servers impacting availability.
To conclude this topic, what we can say is, never trust data when you are about to deserialize it and always perform checks on classes and if you are with the intention to implement any solutions which arent language dependant, we can overcome this issue by using different data formats like digital signatures or JSON.
If you liked my post and learnt a thing or two, I would appreciate spreading my blog to your friends as my intention to teach some security and as well as share abit of tips and techniques which I use personally.
See you on the next one! B)