jueves, julio 30, 2020

Unos consejos para fortificar MongoDB en el mundo NoSQL

Conocí el mundo de los NoSQL allá por el año 2013 cuando comenzamos con ElevenPaths a construir nuevas tecnologías. Teníamos muchos retos tecnológicos por completar ante nosotros. Fue una etapa en la que aprendimos mucho ante todos los cambios y avances en tecnología que aparecían ante nosotros. Hay algo que nos enseñaban cuando estudiábamos en la carrera y es que un Ingeniero debe buscar soluciones, es decir, analizar el problema, analizar una posible solución, diseñar, implementar, etcétera.

Figura 1: Unos consejos para fortificar MongoDB en el mundo NoSQL

A uno de esos problemas de aquella época le dimos solución basándonos en un tipo de bases de datos no relacionales llamas "Not Only SQL"  o NoSQL. Hoy me quiero centrar en una de esas NoSQL, en MongoDB. Es, por mérito propio uno de los motores de base de datos no relacional más utilizados hoy en día. En su día sacamos alguna noticia sobre MongoDB dónde su seguridad no quedaba bien parada, pero quizá no sea la seguridad que MongoDB puede aportar, si no la configuración que le apliquemos. Es decir, no es problema del producto y sí de la configuración que el administrador ejecute, con el caso de estos artículos del blog:
El caso de MacKeeper fue recordado por los 13 millones de usuarios filtrados y los 21 GB de información sensible. Algunos echaron la culpa al producto, pero realmente y clarísimamente, fue una mala configuración. No es el único caso en el que este tipo de soluciones se han visto involucradas, por ejemplo, y más recientemente, tenemos el caso de las miles de apps de iOS que filtraron datos en Firebase, pero no solo en Firebase, en el listado aparece MongoDB también.

Figura 2: El caso de MacKeeper y los datos filtrados

En el artículo de hoy vamos a hablar de cómo fortificar MongoDB. La gente de MongoDB pone a disposición de sus usuarios / administradores una serie de “tips”. En muchos casos, hay cosas “obvias”, por ejemplo, que la conexión vaya cifrada entre la aplicación y la base de datos. De esto ya hemos hablado en el pasado con los ataques Network Packet Manipulation.

Figura 3: Libro de Cifrado de las comunicaciones digitales:
de la cifra clásica a RSA 2ª Edición de 0xWord

Sea como sea, siempre viene bien tener un listado de “tips” o una “checklist” dónde verificar algunas de las cosas que debemos configurar sí o sí en una base de datos, en este caso, no relacional como puede ser MongoDB.

Habilitar el control de acceso y configurar RBAC

Para que no ocurra como en los ejemplos anteriores de filtrado de información, es muy importante habilitar el control de acceso. Como hemos visto, si tu MongoDB da soporte a una aplicación web o un servicio expuesto en la red, es una de las primeras cosas que van a buscarse en un Hacking de Web Technologies. Los motores NoSQL con acceso anónimo son objetivo de pentesters y atacantes peor intencionados. Para ello, se puede utilizar un mecanismo de autenticación SCAM o x509 que trae el propio MongoDB. Además, se puede integrar con Kerberos o LDAP. 

Otra recomendación sería crear primero un administrador de usuarios y luego ir creando los usuarios necesarios. Es importante, crear un usuario por cada aplicación o persona que requiere acceder al sistema. Como define una de las mínimas de la seguridad informática, debemos seguir el principio del menor privilegio. Es decir, vamos a crear roles que definan derechos de acceso para un conjunto de usuarios.  

Figura 4: Hacking Web Technologies 2ª Edición

De esta forma, podemos crear usuarios y asignarlos solo a los grupos/roles que ellos necesiten para poder ejecutar sus tareas u operaciones. Cuando hablamos de usuarios, hay que tener en cuenta que muchas veces son las propias aplicaciones que requieren conectarse contra la base de datos.

Ya hemos comentado sobre RBAC de forma implícita, pero por si acaso, decir que RBAC es un control de acceso basado en roles (Role Based Access Control). Es decir, consiste en asignar derechos de acceso, como comenté antes, a los usuarios en función de los roles y las operaciones o tareas que tienen que realizar.  Para habilitar la autenticación, simplemente debemos cambiar la directiva “auth” o habilitar a true en el fichero de configuración /etc/mongodb.conf.

Figura 5: Configurando /etc/mongodb.conf

El resultado es que cuando queremos conectarnos con MongoDB a la base de datos que hayamos creado pues nos solicitarán credenciales. Puedes ver más sobre la creación de usuarios en la documentación oficial de MongoDB.

Figura 6: Conectándonos con nuestro usuario a MongoDB

Esto es algo muy básico, pero que como hemos visto pues no es algo que siempre se configure. Importante, antes de habilitar la autenticación hay que tener en cuenta el crear usuarios. Eso se hace con la función db.createUser y un documento JSON con el siguiente formato:

{
user: “pablo”,
pwd: “xxx”,
roles: [“dbOwner”] #si queremos que sea el propietario
}

MongoDB tiene lo que se llama “Collection-level access control” y permite hacer un permiso muy específico sobre las colecciones de datos. Es decir, puedes indicar qué tipo de acción puede hacer un rol sobre una colección de datos. Hay que recordar que una colección de datos está dentro de una base de datos. Sería como las tablas en el mundo SQL.

Cifrar comunicaciones con TLS/SSL y cifrar y proteger datos almacenados

El cifrado es clave tanto en lo que a la comunicación entre el cliente y el servidor como en el almacenamiento de los datos. Ya hemos comentado lo que son los ataques de Network Packet Manipulation. Además, Wireshark da soporte para mostrar los paquetes de MongoDB y diseccionarlo de forma sencilla. En otras palabras, si alguien se pone en medio de la comunicación entre la aplicación y el servidor de MongoDB toda la información que viaje entre ambos nodos quedará expuesta.

Figura 7: Paquetes MongoDB en WireShark

Explicar el proceso para proteger la comunicación entre cliente y servidor daría para uno o dos posts, por lo que os dejo el enlace a dicha información y se puede configurar de manera sencilla. Hay que tener en cuenta que habrá que configurar tanto servidor como cliente. 

Encypted at Rest: Almacenamiento seguro de la información  

Ahora, hablemos de la protección de la información en el interior de la base de datos. Cuando se crea un usuario, se nos indica en la documentación que la contraseña no se almacena en texto plano, como era de esperar. MongoDB dispone de una “feature” importante que es el motor de almacenamiento cifrado o Encrypted Storage Engine. Esta “feature” solo está disponible en MongoDB 3.2 en adelante y en la versión Enterprise

Figura 8: Encryption at Rest y MongoDB


Si el cifrado está activo, MongoDB Enterprise utiliza AES256-CBC a través del uso de OpenSSL. Se utiliza la misma clave para cifrar que para descifrar. MongoDB también soporta un cifrado en modo FIPS y AES con el modo Galois/Counter Mode.  Cuando se habilita este cifrado, el proceso incluye las siguientes acciones:
  • Generación de una clave maestra y la generación de claves para cada base de datos. Es decir, que cada base de datos estará cifrada con una clave diferente. Esto es algo lógico.
  • Cifrar los datos de cada base de datos con las claves generadas previamente para cada base de datos. También se cifrarán las claves de la base de datos con la clave maestra.
  • El cifrado es llevado a cabo de forma transparente. Este cifrado se lleva a cabo en todo el almacenamiento, es decir, los archivos que contienen los datos están completamente cifrados. Lo interesante es que los datos descifrados solo existirán en la memoria y nunca en el disco, donde siempre estarán cifrados.
Nota: Ya hemos hablado en este blog sobre ataques a procesos en memoria con el objetivo de sacar información.

Registros y auditoría de las acciones

La trazabilidad es una de las subdimensiones de la seguridad. Es algo importante y el tener un registro de actividad también lo es. Habilitar la auditoría en un MongoDB es algo vital y que permite conocer que está ocurriendo en tu base de datos. Cuando se habilita la auditoría se escriben eventos en la consola del propio MongoDB, en el Syslog o en archivos.

Figura 9: Configuración de Filtros de Auditoría en MongoDB

Se registran operaciones de autenticación, de acceso, de autorización, etcétera. Se puede configurar filtros para restringir eventos capturados. Esto se puede hacer a través de la configuración de los filtros de auditoría. En la auditoría se registran:
  • Autenticación y cómo se dijo anteriormente, también la autorización.
  • Operaciones del cluster de MongoDB.
  • Operaciones de lectura y escritura.
  • Operaciones con el esquema o DDL.
  • Mensajes personalizados de aplicaciones.
Asegurar el entorno de MongoDB

Este paso es muy importante. De nada valdrá tener las mejores recomendaciones y consejos en el ámbito del hardening a MongoDB, si luego tenemos las capas inferiores desprotegidas. Imagínate que permitimos que cualquier usuario pueda acceder a este equipo físicamente y no ponemos barreras, ¿Serviría tener cifrado los datos en disco? Si no tiene un login de usuario, si no tiene un firewall que rebaje la exposición, si no hay unas barreras físicas que evitan que cualquiera pueda acceder a ese equipo físicamente, etcétera.

Figura 10: Auditando MongoDB con Tenable Nessus

En este caso las recomendaciones van por la parte del firewall, pero no hay que quedarse solo con eso. Si vemos el modelo defensa en profundidad, la seguridad va en armonía con todas las capas. No vale fortificar mucho una capa, si luego por debajo, la base, no se sostiene.  Hay un artículo interesante de la gente de Tenable en la que hablan sobre la auditoría a MongoDB con Nessus.

Ejecuta MongoDB con opciones de seguridad habilitadas

Este apartado habla sobre la necesidad de ejecutar MongoDB con un usuario dedicado en el sistema. De forma que si es comprometida, no haya mucho que se pueda hacer hasta que haya una escalada de privilegio en el sistema. Además, hay una serie de opciones de seguridad que se pueden trabajar desde el principio y que ayudan a tener un entorno más seguro dentro de MongoDB. Seguramente, a estos consejos o recomendaciones se pueden añadir más y entrarían en opciones de seguridad habilitadas desde el principio.

Deshabilitar la escritura side-server: MongoDB soporta la ejecución de código Javascript. Para llevar a cabo la mitigación de una posible vulnerabilidad a nivel de aplicación, es recomendable deshabilitar el código del lado del servidor. Esto se puede deshabilitar en el archivo de configuración con la directiva noscripting = false.

Deshabilitar la interfaz de estado: ¿Qué es la interfaz de estado? Esto es un servidor HTTP que expone un sitio web el cual contiene estadísticas e información que pueden ser de interés para un administrador del sistema, pero también para un atacante. En el archivo de configuración se puede deshabilitar esta opción con la directiva nohttpinterface = true.

Desactivar la interfaz REST: Es una interfaz administrativa que es interactiva, la cual se encuentra desactivada por defecto. Esta interfaz no tiene soporte para autenticación y se debe restringir el acceso a dicha interfaz, por ejemplo, por dirección IP o mediante interfaz de loopback. Para deshabilitar esta interfaz en el fichero de configuración debemos verificar rest = false.

Limitar la exposición en la red: Limitar la exposición de direcciones IP de un servidor o de interfaces de red es importante. La opción bind_ip indica la interfaz de red por la que se escucharán peticiones en la base de datos. Esto ya depende de cada uno y sus necesidades. Se puede utilizar la directiva bind_ip para limitar la accesibilidad a la red de un programa MongoDB. También se puede jugar con un firewall y dejar pasar el tráfico que provenga de la dirección IP dónde se encuentra la aplicación. En el fichero de configuración se configura esta opción con la directiva bind_ip = [dirección IP de la interfaz que queremos].

Estos son algunos tips para mejorar la seguridad de una basa de datos MongoDB. Por supuesto, hay más cosas que se pueden hacer, pero con estas estamos mejorando bastante la seguridad de MongoDB. Es importante alinear los esfuerzos con el resto de capas, tal y como se indica en el modelo defensa en profundidad.

Saludos,

Autor: Pablo González Pérez (@pablogonzalezpe), escritor de los libros "Metasploit para Pentesters", "Hacking con Metasploit: Advanced Pentesting" "Hacking Windows", "Ethical Hacking", "Got Root",  “Pentesting con Powershell” y de "Empire: Hacking Avanzado en el Red Team", Microsoft MVP en Seguridad y Security Researcher en el equipo de "Ideas Locas" de la unidad CDCO de Telefónica.  Para consultas puedes usar el Buzón Público para contactar con Pablo González

Figura 11: Contactar con Pablo González

1 comentario:

  1. creo que hay una errata...
    noscripting=true debería ser, verdad?

    ResponderEliminar