PHP Object Injection

1

On the OWASP site, he explains this type of flaw that makes code injection possible. But a part is not clear to me and if someone who understands can clarify me. The excerpt reads as follows:

In order to successfully exploit PHP Object Injection vulnerability two conditions must be met:

  

The application must have a class which implements PHP magic method   (such as __wakeup or __destruct) that can be used to carry out   malicious attacks, or to start a "POP chain".

-

  

All of the classes used during the attack must be declared when the   vulnerable unserialize () is being called, otherwise object autoloading   should be supported for such classes.

That is, when it says that the application must implement a magic method so that there is success in exploiting this failure. Is it referring to any and all classes in my application, or just the class of the object being serialized?

Ex:

let's say I have an object

class Usuario{
   ...
}

and an object

class Setup{
   function __construct() {
     ...
  }

  function __wakeup() {
     ...
  }
}

And I was serializing my obj $user . Could an attacker use the magic methods of class Setup for a possible attack? or these methods should exist in the class of the object being serialized. In this case the class Usuario ?

$user = new Usuario();
echo serialize($user);
    
asked by anonymous 20.04.2017 / 21:42

1 answer

3

The class should already exist, with magic methods, this is the only thing you need, in general .

Imagine you have this:

class Teste {

    public  $nome = '';

    public function __destruct(){
        echo 'Olá, ' . $this->nome;
    }

}

If you do this:

$id = unserialize($_GET['token']);

A user could do this:

pagina.php?token=O:5:"Teste":1:{s:4:"nome";s:28:"Isso%20aqui%20está%20meio%20bugadao";}

It would result in this:

Olá, Isso aqui está meio bugadao

Try this here.

O:5:"Teste":1:{                       Objeto com 5 caracteres, nome de  "Teste" com 1 parâmetro 
s:4:"nome";                           String com 4 caracteres com valor "nome".
s:28:"Isso aqui está meio bugadao";}  String com 28 caracteres com valor "Isso aqui está meio bugadao".

unserialize is not recommended for use in contact with the client (do not use in POST / GET / COOKIE, anything where the client can change it), including in the documentation itself:

  

Do not pass untrusted user input to unserialize () regardless of the options value of allowed_classes. Unserialization can result in code being loaded and executed due to object instantiation and autoloading, and a malicious user may be able to exploit this. Use the safe, standard data interchange format such as JSON (via json_decode () and json_encode ()) if you need to pass serialized data to the user.

     

If you need to unserialize externally stored serialized data, consider using hash_hmac () for data validation. Make sure data is not modified by anyone, but you.

Not even DateTime/DateTimeZone escaped with unserialize .

If this is really the only option, make sure that you are verifying the integrity of the content being "unserialized", remember that using openssl_encrypt can guarantee confidentiality, but it can not guarantee integrity, making it useless! Make sure the content has not changed, using HMAC for example .

However, as a better alternative you have json_decode / json_encode , although there are also some problems (which I remember is that it is vulnerable to Hash-DoS) with json_* s much less severe, but unserialize has already been (if not yet) vulnerable as some DoS .

I believe you can get some information on:

20.04.2017 / 23:36