Qué es Insecure Deserialization y cómo prevenirla

Qué es Insecure Deserialization y cómo prevenirla

La deserialización insegura (o Insecure Deserialization) es una vulnerabilidad que ocurre cuando una aplicación o una API deserializa datos manipulados por un atacante en el lado del servidor.

Es decir, durante el momento en el que se transforman los datos serializados a un objeto, un atacante puede abusar de la lógica de la aplicación, y realizar ataques de denegación de servicio (DoS), omitir autenticaciones o incluso ejecutar código malicioso de forma remota.

¿Qué es la serialización y la deserialización?

La serialización es un proceso en el que se traducen estructuras de datos (o estados de objetos) a un formato que puede almacenarse y reconstruirse con posterioridad. 

La deserialización, por otro lado, es lo opuesto a la serialización, es transformar los datos serializados provenientes de un archivo, secuencia o socket de red en un objeto, y es en este último proceso donde reside la vulnerabilidad.

proceso de serialización y deserialización

Aunque muchos lenguajes de programación permiten personalizar los procesos de deserialización, con frecuencia los atacantes logran abusar de estas características cuando la aplicación deserializa datos controlados por el atacante. 

¿Cómo funciona la deserialización insegura?

Generalmente esta vulnerabilidad ocurre por falta de comprensión de lo peligroso que puede ser la deserialización de datos controlables por el usuario. 

Ya que, idealmente, la entrada del usuario nunca debería deserializarse en absoluto. Es decir que no es posible deserializar de forma segura una entrada que no es de confianza.

Ejemplo de explotación

A continuación podemos observar un escenario de un sistema vulnerable:

  1. Al iniciar sesión en una aplicación es posible identificar que la cookie de sesión está codificada con URL y Base64. 

2. Pero luego de decodificar esta cookie, se puede obtener el objeto serializado: en el que el atributo admin contiene el valor b:0 el cual indica que el valor del booleano es falso (es decir, que el usuario no es admin).

3. Si modificamos el atributo admin con el valor b:1 y se vuelve a codificar, obtenemos como resultado el siguiente objeto serializado:

4. Y si reemplazamos la cookie de sesión por el objeto serializado en el WebStorage del navegador y refrescamos la página se puede ver cómo se habilita un enlace para acceder al Admin Panel.

5. De esta forma, un atacante puede acceder directamente al Admin Panel para operar de forma maliciosa.

¿Cuáles son los riesgos de Insecure Deserialization?

La deserialización insegura permite a un atacante manipular objetos serializados para pasar datos dañinos al código de la aplicación, e incluso, reemplazar un objeto serializado por un objeto de una clase distinta. 

Es decir, los objetos que estén disponibles para el sitio web serán deserializados e instanciados, independientemente de la clase que se esperaba. De hecho, es por ello que esta vulnerabilidad también se conoce como inyección de objetos.

Muchos ataques de deserialización finalizan antes de que se complete la deserialización. Esto significa que el proceso en sí mismo puede iniciar un ataque, sin importar si la funcionalidad de la aplicación interactúa o no directamente con el objeto malicioso. 

En definitiva, aún los sitios web y las aplicaciones basadas en lenguajes fuertemente tipados también pueden ser vulnerables a estas técnicas. 

¿Cómo solucionar esta vulnerabilidad?

Veamos un ejemplo en código PHP. Cuando se tiene control de un objeto serializado que se pasa a unserialize (), es posible tener las propiedades del objeto creado. También, puede secuestrar el flujo de la aplicación controlando los valores pasados a métodos ejecutados automáticamente como __wakeup () o __destruct ()

A esto se le llama inyección de objetos PHP (PHP Object Injection). La inyección de objetos PHP puede conducir a la manipulación de variables, ejecución de código, inyección SQL, recorrido de ruta o DoS. Una forma posible de aprovechar la inyección de objetos PHP es, como vimos en el ejemplo de explotación, mediante la manipulación de variables.

Veamos en el siguiente ejemplo en PHP, cómo un atacante podría conseguir una ejecución remota de código: 

Este código es vulnerable debido a que: 

  • Está deserializando un objeto proporcionado por el usuario a través de la función unserialize()
  • La clase Example tiene la función mágica __wakeup() que se ejecutará automáticamente cuando llame a unserialize() y la cual ejecuta eval () en la entrada proporcionada por el usuario.

Para que el atacante logre la ejecución remota de código, simplemente debe configurar la cookie data en un objeto Example serializado con la propiedad hook configurada con el código PHP deseado, que en este caso es phpinfo()

Si pasa la cadena generada anteriormente a la cookie data hará que se ejecute el código phpinfo (). Y una vez que se pase el objeto serializado al programa ocurrirá lo siguiente:

  1. El objeto serializado Example se enviará al programa en la cookie data.
  2. El programa llamará a unserialize () en la cookie data
  3. unserialize () creará una instancia de un nuevo objeto Example debido a que la cookie data es un objeto Example serializado, 
  4. unserialize () verá que la clase Example tiene implementado __wakeup (), por lo que, al ser una función mágica, se ejecutará automáticamente.
  5. __wakeup () buscará la propiedad $hook del objeto, y si no es NULL, ejecuta eval ($ hook)
  6. Como $hook no ser NULL y está configurado como phpinfo (),entonces eval(“phpinfo ();”) se ejecuta. 
  7. Finalmente, al ejecutarse el eval($hook) el atacante logra la ejecución remota de código también llamada Remote Code Execution. 

Solución

Para evitar que se produzcan inyecciones de objetos PHP, te recomendamos no pasar nunca la entrada de un usuario que no sea de confianza a unserialize ().

En caso de ser necesario, debes pasar los datos serializados que no sean de confianza a unserialize (). Es fundamental implementar una validación de datos rigurosa para minimizar el riesgo de una vulnerabilidad crítica.

Tips de remediación

Estas son algunas medidas que puedes tomar para evitar la vulnerabilidad Insecure Deserialization:

  • Evita la deserialización de la entrada del usuario a menos que sea absolutamente necesario.
  • Si necesitas deserializar datos de fuentes que no son de confianza, incorpora medidas sólidas para asegurarte de que los datos no hayan sido manipulados.
  • Si es posible, evita el uso de funciones de deserialización genéricas.
  • El método de serialización debe estar encriptado, no codificado.
  • Mantén los controles de integridad para evitar la manipulación de datos con los objetos serializados.
  • Ejecuta el código de deserialización en un entorno de privilegios bajos.
  • Implementa controles de integridad, como firmas digitales, en cualquier objeto serializado para evitar la creación de objetos hostiles o la manipulación de datos.
  • Registra las excepciones y los errores de deserialización, como cuando el tipo entrante no es el tipo esperado o la deserialización genera excepciones.

Un pentest nunca está de más

Los casos en los que puede aparecer esta vulnerabilidad son diversos y, hasta la fecha, no existe una herramienta automatizada que permita detectarla. 

Desafortunadamente, la vulnerabilidad Insecure Deserialization no es la única podría amenazar tu plataforma, por lo tanto, es recomendable hacer un ejercicio de ethical hacking (del tipo penetration testing, pruebas de intrusión o pentest) periódicamente para detectar estas vulnerabilidades y otras fallas de seguridad que pudieran estar presentes tanto en la aplicación como en las redes de tu empresa. 

En Hackmetrix contamos con un equipo especializado que te ayudará a poder detectar estas fallas y prevenir que futuros agentes maliciosos se aprovechen de ellas.

Conclusión

La vulnerabilidad Insecure Deserialization puede permitirle a un atacante realizar ataques de denegación de servicio (DoS), omisiones de autenticación y ataques de ejecución remota de código.

Evitar estos riesgos es de suma importancia para una organización ya que podría poner en peligro a los usuarios de la plataforma y eventualmente generar una brecha costosa para el negocio.

Por otro lado, para detectar esta vulnerabilidad se requiere del trabajo de una persona calificada que analice, evalúe e interprete la información, por este motivo, es recomendable realizar pruebas de intrusión periódicas para detectarlas de forma temprana.

De todas formas, ahora conoces los métodos de remediación que te ayudarán a resolver este tipo de errores y a tenerlos en cuenta en la escritura del código.

Referencias

  1. https://portswigger.net/web-security/deserialization
  2. https://seguridad-ofensiva.com/blog/owasp-top-10/owasp-top-8/
  3. https://medium.com/swlh/exploiting-php-deserialization-56d71f03282a
  4. https://hackingprofessional.github.io/Security/Aprende-que-es-Deserializacion-Insegura-OWASP-VII/
  5. https://ichi.pro/es/deserializacion-insegura-13396185752847

Backed by

Hackmetrix startup chile