A día de hoy, una de las aplicaciones de Software Libre de mensajería instantánea (IM) disponibles en el mercado para su uso a nivel empresa o particular, por robustez, por funcionalidades y por ser una solución multi-dispositivo, podría ser el popular Rocket.chat. En este artículo vamos a ver cómo se rompe la arquitectura de seguridad y se puede acceder a los datos enviamos en los mensajes por culpa de un fallo de seguridad que hay que corregir.
Figura 1: Cómo romper la arquitectura de cifrado de
mensajes extremo a extremo de Rocket.Chat [1 de 2]
Rocket.chat permite varias modalidades de uso de cara a una compañía, pudiendo montar un servidor centralizado OnPremise, tu propio servidor OnCloud, o simplemente mediante, el uso del servidor público que proporciona la propia compañía Open.rocket.chat. La conexión al servidor puede realizarse desde múltiples dispositivos como se puede ver en la imagen anterior, tiene cliente Web, aplicación de escritorio para Windows/Linux/MacOS y app móvil para Android e iOS.
La funcionalidad a revisar en el artículo, será la del cifrado Extremo a Extremo o "End-2-End" (E2E). Dicha funcionalidad, implementa una capa de seguridad adicional al cifrado TLS a nivel de red utilizado de forma común mediante el protocolo HTTPS, en la mayoría de las comunicaciones actualmente. Como veremos al final, se podrá hacer un descifrado de los mensajes, y veremos cómo se puede mejorar la arquitectura de cifrado. Para entender mejor toda la arquitectura de cifrado, tienes el libro de Cifrado de las comunicaciones digitales: de la cifra clásica a RSA 2ª Edición de 0xWord
Figura 2: Arquitectura de conexiones multi-cliente para Rocket.chat
La funcionalidad a revisar en el artículo, será la del cifrado Extremo a Extremo o "End-2-End" (E2E). Dicha funcionalidad, implementa una capa de seguridad adicional al cifrado TLS a nivel de red utilizado de forma común mediante el protocolo HTTPS, en la mayoría de las comunicaciones actualmente. Como veremos al final, se podrá hacer un descifrado de los mensajes, y veremos cómo se puede mejorar la arquitectura de cifrado. Para entender mejor toda la arquitectura de cifrado, tienes el libro de Cifrado de las comunicaciones digitales: de la cifra clásica a RSA 2ª Edición de 0xWord
Figura 3: Libro de Cifrado de las comunicaciones digitales: de la cifra clásica a RSA 2ª Edición de 0xWord |
Arquitectura de Rocket.Chat
Para implementar esta función, Rocket.Chat cuenta con un diseño de arquitectura E2E del cual se ha realizado un pequeño estudio, para preparar este artículo. Esta arquitectura utiliza operaciones criptográficas de varios tipos, diferenciadas por su naturaleza matemática en simétrica, asimétrica y operaciones de hashing:
Dicho framework trabaja con JavascriptCore que ademas de ejecutarse en los navegadores web, permite la posibilidad de integración de librerías implementadas en otros lenguajes de programación, como puedan ser Java para sistemas operativos Android u Objetive-C para sistemas operativos iOS:
Las conexiones que se implementan entre los diferentes clientes y el servidor central de Rocket.Chat podrán ser de dos tipos diferenciados por la dirección en la que se comunican:
- Criptografía Simétrica: algoritmo utilizado AES, origen y destino comparten una clave de cifrado.
- Criptografía Asimétrica: algoritmo utilizado RSA, mediante el uso de un par de claves Publica y Privada, los datos serán cifrados con la clave pública y descifrados con la la clave privada.
- Hashing: algoritmo utilizado PBKDf2, la función derivación matemática que generará un resultado irreversible del cual no se puede obtener los datos originales de entrada.
Figura 4: GitHub de Rocket.Chat
Dicho framework trabaja con JavascriptCore que ademas de ejecutarse en los navegadores web, permite la posibilidad de integración de librerías implementadas en otros lenguajes de programación, como puedan ser Java para sistemas operativos Android u Objetive-C para sistemas operativos iOS:
Figura 5: Arquitectura de JavascriptCore con Java y Objetive-C
Las conexiones que se implementan entre los diferentes clientes y el servidor central de Rocket.Chat podrán ser de dos tipos diferenciados por la dirección en la que se comunican:
Figura 6: Conexiones API REST y WebSocket
La conexión vía API Rest es Cliente → Servidor y unidireccional, mientras que la conexión vía Websocket permite en modo full-duplex transferencias bi-direccionales Servidor → Cliente y Cliente → Servidor.
Descripción de la arquitectura E2E
La funcionalidad E2E, se arranca tras la autenticación inicial de un usuario (U) sobre sobre un dispositivo (D).
- El dispositivo (D), solicitará al usuario (U) o generará unas credenciales específicas E2E (En función de si es la primera vez o no, que el usuario se autentica en el dispositivo con el servidor de Rocket.Chat).
- Tras introducir las credenciales mediante la derivación de la contraseña junto al identificador unívoco del usuario (U) UID y el uso del algoritmo criptográfico de hashing PBKDF2, se generará la primera clave criptográfica de la aplicación master-key.
A continuación, el dispositivo (D) como cliente del servidor de Rocket.Chat procederá con la generación o solicitud (en función de si es la primera vez en la que el usuario se autentica en el dispositivo) de un par de claves RSA de longitud 2048 que serán las claves criptográficas E2E del usuario:
- Generación public_key, private_key: RSA-OAEP 2048
- Utilizando la master-key, mediante criptografía simétrica utilizando el algoritmo AES-CBC el dispositivo (D), cifrará la private_key.
Figura 8: Generación de claves pública y privada para cifrado asimétrico
- La función de la API Rest que proporciona este servicio, es e2e.setUserPublicAndPrivateKeys.
- El servidor de Rocket.Chat en su BD no relacional (mongodb) almacenará estas claves asociadas al usuario (U), en la colección users.
Figura 9: Envío de claves pública y privada a servidor de Rocket.Chat
La aplicación para cifrar los datos punto a punto, requiere de una habitación o chat seguro por tanto ya sea dirigido desde el usuario (U), al usuario unívoco (U₁) o a los múltiples usuarios (U₁),(U₂)...(U_n), por lo tanto será necesario crear un grupo cifrado.
- La operación de la API Rest del servidor de Rocket.Chat que proporciona este servicio será create.group, especificando los parámetros adecuados de grupo privado y encriptado.
- El servidor de Rocket.Chat generará en la BD no relacional una entrada en la tabla rocketchat_subscriptions por cada usuario (U1..n), que pertenezca a la habitación segura alojada en la colección rocketchat_room.
- Se cifrará la Room-Key: de forma asimétrica mediante el algoritmo RSA para cada usuario del chat seguro.
- Se utilizará para el cifrado la public_key, disponible en la colección users del servidor, reportada mediante la invocación al servicio API Rest de Rocket.Chat e2e.requestSubscriptionsKeys.
Figura 11: Envío de claves Room-Key a los usuarios del grupo
Para la obtención de la clave de cifrado de mensajes E2E, en determinado grupo cualquier usuario que sea miembro de este, deberá realizar los siguientes pasos:
- El usuario (U), ya autenticado en la aplicación y en la arquitectura E2E estando en posesión de su master-key.
- Solicitará la clave de sesión E2EKey, almacenada para su usuario (U), en la colección rocketchat_subscription (cifrada asimétricamente con RSA).
- Solicitara sus claves de cifrado al servidor, public_key y private_key (esta última, cifrada simétricamente con AES).
- Descifrará con AES, la clave privada mediante el uso de la master-key.
- Descifrará con RSA, utilizando la clave privada (private_key) descifrada y la clave E2E (E2EKey) obteniendo la room-key o session-key.
Visto todo esto, si eres amante de la seguridad informática, el hacking y te gusta la criptografía, supongo que ya has visto algunos puntos débiles de esta arquitectura que, si se pueden atacar, pueden romper la seguridad de la plataforma. En la segunda parte de este artículo lo vemos.
Saludo,
Autor: Ildefonso González Sánchez, pentester.
Excelente contenido gracias
ResponderEliminar