Entiende las Vulnerabilidades de Deserialización Insegura en Proyectos Ruby

Elena Digital López

En un reciente análisis exhaustivo sobre vulnerabilidades informáticas, se ha demostrado cómo un atacante puede ejecutar comandos arbitrarios en un servidor remoto simplemente enviando JSON. Esto es posible si el código ejecutado contiene vulnerabilidades de deserialización insegura. Aunque esta característica puede parecer magia, en realidad se trata de una combinación de técnica y esfuerzo.

En esta investigación se ha profundizado en cómo funcionan las vulnerabilidades de deserialización insegura y se ofrecen métodos para detectarlas en proyectos Ruby. Los ejemplos presentados utilizan la librería de serialización JSON para Ruby, Oj, aunque estas vulnerabilidades no se limitan a esta librería en particular. También se han presentado ejemplos que funcionan con otras librerías como Ox (XML), Psych (YAML) y Marshal (formato binario personalizado).

La clave de estas vulnerabilidades radica en la capacidad de las librerías de deserialización para soportar el polimorfismo, lo que implica la capacidad de instanciar clases arbitrarias o estructuras similares especificadas en los datos serializados. Un atacante puede encadenar estas clases para ejecutar código en el sistema objetivo.

El ejemplo presentado detallaba cómo construir un gadget de detección de deserialización insegura para Oj. Este gadget llama a una URL externa y está basado en un dispositivo universal de deserialización para Marshal y Ruby 3.0.3 adaptado para Oj y Ruby 3.3. Este gadget se utiliza para demostrar cómo invocar métodos de una clase de Ruby manipulando datos deserializados, permitiendo así la ejecución de comandos mediante métodos como hash.

En el caso de Oj, la deserialización insegura se podría explotar de la siguiente manera: al instanciar una clase con un campo member contenido en un JSON, se puede especificar la clase y el contenido de tal manera que, al colocarse dentro de un hash(map) como clave, se ejecuten comandos al invocar el método hash.

Además, se presentó un ejemplo donde un código JSON específico fue deserializado con Oj para abrir una calculadora en macOS como prueba de concepto. Al convertir este JSON en un objeto y colocar este objeto en un hash(map), se demostraba cómo un atacante podría manipular el comportamiento del programa para ejecutar comandos arbitrarios.

También se describieron los métodos para garantizar una ejecución más sólida de estos comandos mediante la construcción de cadenas de gadgets más complejas. Se especificó cómo usar métodos presentes en las clases estándar de Ruby para lograr el objetivo.

Para detectar estas vulnerabilidades sin tener acceso al código fuente, se puede emplear una cadena de gadgets de detección que llame a una URL especificada, marcada por servicios como Canarytokens o Burp Collaborator para recibir notificaciones cuando la URL sea llamada.

Finalmente, se presentó una cadena de gadgets para lograr la ejecución de código remoto (RCE), indicando cómo adaptar y mejorar exploits previos para versiones más recientes de Ruby. La búsqueda se centró en unir métodos y clases dentro de Ruby que permitieran la llamada de comandos arbitrarios o la manipulación de flujos de datos de manera controlada.

Para detectar vulnerabilidades de deserialización insegura con acceso al código fuente, y sin conocimientos previos de seguridad ni errores de implementación, se recomienda el uso de CodeQL y las herramientas de escaneo de código de GitHub. Esta metodología proporciona una manera sistemática de identificar y mitigar estas vulnerabilidades de manera efectiva.