Libwary
This was an interesting PHP challenge showcasing the potential impacts of insecure deserialization.
Description
Try to read the flag from The Libwary. (Impossible)
The source code for this challenge can be found here.
Spotting the Vulnerability
When looking at index.php, we see that our user object is deserialized
from the PHPSESSID cookie. Deserializing user input is always a huge no-no,
as users can send specially crafted payload to pwn the server.
In this case, the User class is being serialized, converted to base64,
and saved to the PHPSESSID cookie. The server will then deserialize it
when the user makes the request again.
What is Serialization and Deserialization?
When we create objects (or classes) during a program’s runtime, it is represented as binary directly inside the program’s memory. Once the program ends, the object ceases to exist. Some programs require the state of the objects to be preserved even after the program ends. This is where serialization and deserialization comes in handy. It allows objects to be saved in a structured format on our hard disks.
For example, we have a book object in Python, and we would like to save it:
A serializer could convert this into JSON (or any other format) and save it like this:
This is a rather simple way to serialize and lacks a decent number of features, such as saving functions and custom data types. If you’d like to find out more, Python has an amazing library for serialization and deserialization called pickle, and this guide explains how to use it.
Serialization & Deserialization in PHP
PHP stores the objects in a JSON-like format like {type:length:value}.
Do refer to the PHP serialization documentation
for a more detailed explanation.

Exploiting this Vulnerability
So how can we use this to our advantage? In the image above, we see that we have
control over the object property. Thus, we can modify this to be a Book instead
of a User, with a property name containing flag.txt!
However, there’s a catch. We see that in the __tostring function of Book, there
is a filter that replaces flag with an empty string. Thankfully, there’s a trivial way to
overcome this filter by using the payload flflagag.txt. Since this function
is not recursive, it only removes a single occurrence of flag. We can wrap this within
another flag string, and after it runs through the filter, we would be left with flag.txt!
We can modify the cookie to be a Book with name flflagaag.txt using
this command, and setting it with inspect element:
