Insecure Desarialization

online debugger:

https://www.onlinegdb.com/

  1. Try to change object ex. for administrator

  2. Insecure deserialization of object - fn that delete file (unlink)

function __destruct() {
        if (file_exists($this->lock_file_path)) {
            unlink($this->lock_file_path);
        }
    }
    
    

O:14:"CustomTemplate":1:{s:14:"lock_file_path";s:23:"/home/carlos/morale.txt";}

  1. set access token to integer, and bypass authorization

O:4:"User":2:{s:8:"username";s:13:"administrator";s:12:"access_token";i:0;}

PHP-based logic is particularly vulnerable to this kind of manipulation due to the behavior of its loose comparison operator (==) when comparing different data types. For example, if you perform a loose comparison between an integer and a string, PHP will attempt to convert the string to an integer, meaning that 5 == "5" evaluates to true.

Unusually, this also works for any alphanumeric string that starts with a number. In this case, PHP will effectively convert the entire string to an integer value based on the initial number. The rest of the string is ignored completely. Therefore, 5 == "5 of something" is in practice treated as 5 == 5.

This becomes even stranger when comparing a string the integer 0:

0 == "Example string" // true

Why? Because there is no number, that is, 0 numerals in the string. PHP treats this entire string as the integer 0.

Consider a case where this loose comparison operator is used in conjunction with user-controllable data from a deserialized object. This could potentially result in dangerous logic flaws.

$login = unserialize($_COOKIE) if ($login['password'] == $password) { // log in successfully }

Let's say an attacker modified the password attribute so that it contained the integer 0 instead of the expected string. As long as the stored password does not start with a number, the condition would always return true, enabling an authentication bypass. Note that this is only possible because deserialization preserves the data type. If the code fetched the password from the request directly, the 0 would be converted to a string and the condition would evaluate to false.

  1. use functionality of the app to delete file

Edit the serialized data so that the avatar_link points to /home/carlos/morale.txt. Remember to update the length indicator. The modified attribute should look like this:

s:11:"avatar_link";s:23:"/home/carlos/morale.txt"

Click "Apply changes". The modified object will automatically be re-encoded and updated in the request.

Change the request line to POST /my-account/delete and send the request. Your account will be deleted, along with Carlos's morale.txt file.

phpgcc

replace session cookie inside browser

JAVA Commons

ruby

https://devcraft.io/2021/01/07/universal-deserialisation-gadget-for-ruby-2-x-3-x.html

Last updated