Vulnerabilidad de Deserialización Insegura
Table of Contents
ToggleIntroducción
Para entender un poco mejor la vulnerabilidad de deserialización insegura, veamos el siguiente ejemplo:
Supongamos que unos turistas nos piden que los ayudemos para llegar a cierta ciudad. Entonces, como no sabemos su idioma, trazamos una ruta con color, o imágenes, e indicaciones para que se orienten. Por lo tanto, hemos serializado la información en una imagen para que luego los turistas la puedan deserializar y llegar a su destino.
Cuando hablamos de objetos en la programación simplemente nos referimos a generar líneas de código que serán reutilizables para no volver a escribirlas. Esto nos trae el beneficio de ahorrarnos espacio en memoria y dolores de cabeza a los programadores. Los objetos poseen ciertos métodos y funciones que definen los “estados” y “comportamientos” del mismo. Por ejemplo, podemos decir que un perro es un “objeto” ya que cumple con ciertas cualidades de estado, como ser grande, chico, de raza, etc..Y con ciertas cualidades de comportamiento como dormir, ladrar, correr, etc.. Estas cualidades especifican los métodos y funciones que componen a un objeto.
¿Qué entendemos por «Deserialización Insegura»?
Veamos la siguiente definición, según Acunetix-2017:
“La vulnerabilidad de deserialización insegura ocurre cuando se utilizan datos que no son de confianza para abusar de la lógica de una aplicación”
Esta vulnerabilidad tiene la particularidad que no existen, por ahora, herramientas que ayuden a encontrar deserialización insegura o algún fallo similar. En realidad, esto depende de la lógica y el conocimiento en cuanto a datos serializados y POO (programación orientada a objetos) que pueda tener un hacker para descubrirla y/o un desarrollador para evitarla. La serialización es el proceso de convertir un objeto en bytes a sistema binario para su mejor almacenamiento o transporte. Cuando hablamos de deserialización estamos hablando de lo opuesto, es decir, de pasar un archivo de sistema binario a objeto.
¿Cómo surge esta Vulnerabilidad?
La vulnerabilidad de deserialización insegura se lleva a cabo cuando en un programa mal diseñado podemos modificar sus datos porque no hay filtrado ni validación de entrada. Entonces, de esta forma nos aprovechamos de la “deserialización”, introduciendo o inyectando código malicioso, para así poder enviar la información modificada al servidor donde este lo interpretará como una función normal sin restricciones. Así es como podemos ejecutar un RCE (Ejecución Remota de Comandos), un DoS (Denegación de servicio) e incluso, escalar privilegios y acceder a datos confidenciales alterando la integridad de los mismos.
Este proceso de vulnerabilidad se puede llevar a cabo en cookies, APIs, sitios web de ecomerce (tiendas online). En toda aplicación que almacene datos sin restricciones o validación en la integridad de los datos consultados. La vulnerabilidad de deserialización insegura también se conoce como “Inyección de objeto PHP”
Práctica con TryHackme
A continuación estaremos llevando a cabo diferentes procedimientos para entender mejor la lógica en detalle de la vulnerabilidad de deserialización insegura.
Ejemplo con Cookies
En esta máquina lo que haremos será revisar el valor de la cookie, la cual nos proveerá de mucha información.
Podemos ver que tenemos un sitio web, cuyo tema a tratar, es sobre el editor de texto “Vim”. Para poder ingresar, primero debemos registrarnos a través de la opción Join Us.
Con lo que se nos presentará el siguiente perfil nos nuestros datos:
Una vez registrados, podemos hacer uso de BurpSuit para revisar las cookies o, dando click derecho y eligiendo la opción “Inspeccionar”. Luego nos dirigimos a la opción de “Storage” o “Almacenamiento” y buscamos nuestra cookie:
Podemos notar a simple vista, las vulnerabilidades que se encuentran dentro, ya que vemos la contraseña de nuestro usuario en texto plano y otras, como la cookie “sessionid” codificada en base 64 (la cual vamos a deserializar). Por lo tanto, nuestra primera flag en esta máquina la encontraremos decodificando el valor de ssesionid. Para esto, copiamos y pegamos dicho valor en nuestra Shell y realizamos lo siguiente:
Como se observa, hemos encontrado nuestra flag, remarcada al final del resultado. Ahora bien, recordemos que a través de la cookie “Usertype” podemos ver nuestro nombre de usuario. Esto nos lleva a pensar que, dependiendo el valor de dicha cookie, será el usuario que se registre en la web. Entonces, podríamos cambiar dicho valor por “admin”:
En nuestro perfil, veríamos un link http://IP_ADRESS_MACHINE/myprofile. Por lo tanto, una vez cambiado el valor del userType, deberíamos actualizar el sitio web y estar en el panel de admin. Podemos verificar esto en nuestro navegador ya que, veremos el siguiente link: http:// IP_ADRESS_MACHINE/admin.
Como vemos, hemos podido realizar un log in como administrador. Al final, se puede apreciar la flag para realizar nuestra máquina.
Ejecución de Código
Para realizar este laboratorio, primero tengamos en cuenta que dentro de nuestro perfil IP_MACHINE/myprofile veamos la sección “Exchange your vim”
Si hacemos click aquí y luego en “Provide you feedback!” veremos lo siguiente:
Podemos observar que aquí radica la vulnerabilidad ya que, al ingresar dichos datos, estos se almacenan de forma codificada para luego ser enviada a la aplicación Flask (para almacenarse en una base de datos). Es decir, cuando hacemos click en “Exchange your vim” se codifica y almacena una cookie (llamada «encodedPayload») en nuestro navegador. Entonces por detrás debería haber un código como el siguiente:
Ahora bien, cuando damos click en “Provide your feedback” el valor de dicha cookie se decodifica y luego se deserializa. Por lo tanto, por detrás debería haber un código como el siguiente:
Teniendo en cuenta esto, podemos verificar que esta vulnerabilidad se puede explotar con la librería pickle de Python.
Por lo tanto, la aplicación asume que cualquier dato codificado es confiable. Y es aquí donde está el problema ya que, podemos ingresar código malicioso codificado para generar una ejecución remota de comando y lograr tener acceso a sistema. Veamos esto en detalle:
Primero, debemos ponernos en escucha, esto lo haremos a través del puerto 444 de la siguiente manera:
Ahora bien, recordemos que, debido al código que se deserializa tiene un formato base64, no podemos simplemente generar un shell inverso. Por tanto, debemos codificar nuestros propios comandos en base64 para que se ejecute el código malicioso. A continuación, se muestra dicho script dentro del archivo des-rce.py:
Una vez hecho el script, procedemos a ejecutarlo para que nos devuelva el formato base64:
Ahora procedemos a copiar y pegar dicho resultado dentro del valor de la cookie “encodePayload”
Recordar:
Copiamos y pegamos SOLO LO QUE SE ENCUENTRA DENTRO DE LAS MARCAS DE AGUA O COMILLAS (‘este contenido’), con respecto al archivo codificado resultante. Luego actualizamos el sitio web y verificamos el resultado en nuestra Shell:
Como podemos ver, hemos tenido acceso remoto al sistema y solo nos quedaría buscar la flag para completar nuestro laboratorio. Para esto debemos probar cada archivo o directorio al que tengamos acceso. Veamos a continuación:
¿Cómo evitamos esta Vulnerabilidad?
Debemos tener en cuenta y llevar acabo las siguientes prácticas:
Asegurarnos, en caso de ser posible, de la deserialización en la entrada del usuario.
El método de serialización debe estar encriptado y no codificado.
En caso de querer deserializar datos de fuentes desconocidas, debemos asegurarnos de incorporar medidas sólidas para verificar que los datos no hayan sido manipulados.
Implementar firmas digitales como método de seguridad para evitar la manipulación de datos.
Ejecutar el código de deserialización en un entorno de privilegios bajos, ya que, en el caso de ingresar un atacante, no tenga privilegios elevados.
Monitorear aquellas conexiones de red entrantes y salientes desde contenedores o servidores que utilizan funcionalidades de deserialización.