Icono del sitio Jaymon security

Práctica de inyección en Base de Datos tipo NoSQL – (NoSQLi)

NoSQLi

NoSQLi

1. Introducción – NoSQLi

 

En este ejercicio vamos a explorar la posibilidad de realizar inyecciones en una base de datos NoSQL como MongoDB.

 

2. Montando el escenario de trabajo.

 

Se va a desarrollar una aplicación web en PHP con inicio de sesión que se conecte a una colección MongoDB donde se almacenan usuarios y contraseñas. Al ingresar credenciales, si coinciden con un registro en la base, se muestra un mensaje de bienvenida; de lo contrario, se envía un mensaje de error.

A continuación, se detalla el proceso de instalación de MongoDB con sus correspondientes extensiones de PHP bajo el framework XAMPP instalado anteriormente en nuestra máquina Windows 11.

Fig. Detalle de la descarga de MongoDB.

Fig. Detalle de la instalación de MongoDB.

Fig. Detalle de la instalación de MongoDB.

Fig. Detalle de la conexión de MongoDB.

Posteriormente, creamos la BBDD llamada “prac1” con su tabla “usuarios”.

Fig. Detalle de la creación de BBDD prac1 en MongoDB.

En la siguiente captura se muestra cómo se ha creado correctamente.

Fig. Detalle de la creación de BBDD prac1 en MongoDB.

 

Llegados a este punto, creamos el siguiente archivo JSON que será importado en la BBDD para añadir los datos correspondientes en la tabla “usuarios”.

Fig. Detalle del JSON que será importado en MongoDB para crear usuarios y contraseñas en BBDD prac1 tabla usuarios.

 

A continuación, se muestra cómo se importa el archivo anterior en la BBDD.

Fig. Detalle de la importación del archivo json_creardatos.json en MongoDB.

 

Tras la correcta importación, se observa cómo la tabla “usuarios” contiene los datos importados del archivo JSON.

Fig. Detalle de correcta importación y creación de datos en MongoDB.

Llegados a este punto, procedemos a implementar “PHP MongoDB driver” para poder usar PHP con MongoDB.

Para ello vamos al repositorio oficial de MongoDB y descargamos el paquete de dependencias acorde a nuestro escenario.

Fig. Instalación de la extensión PHP en MongoDB.

 

A continuación, se muestra la extracción del archivo descargado y la copia de los archivos clave en el directorio donde se encuentran las extensiones de PHP.

Fig. Detalle de implementación de la extensión PHP de MongoDB.

 

Una vez realizado el paso anterior, se debe añadir la siguiente línea en el archivo “php.ini”.

Fig. Detalle de implementación de la extensión PHP de MongoDB.

 

Una vez realizado los puntos anteriores, procedemos a reiniciar el servidor apache desde el panel de control de Xampp.

Si todo ha ido correctamente, al llamar a “phpinfo()” veremos que MongoDB ya está habilitado en PHP, como se muestra en la siguiente captura.

Fig. Detalle de implementación de la extensión PHP de MongoDB.

 

No obstante, es recomendable realizar la instalación de la extensión a través de la herramienta “Composer”. Así pues, instalamos esta herramienta como se muestra a continuación, desde su página oficial.

Fig. Detalle de descarga e instalación de la herramienta composer.

 

Una vez descargado e instalado procedemos a lanzar el siguiente comando que instalará la extensión MongoDB en PHP.

Fig. Detalle de instalación vía composer de la extensión PHP de MongoDB.

 

De esta manera ya ha quedado instalada correctamente la extensión PHP de MongoDB, por lo que procedemos a comprobar con el siguiente script si se realiza correctamente la conexión a la BBDD prac1 de MongoDB mediante PHP.

Fig. Detalle del código fuente de test.php.

 

Tras ejecutar vía web el script anterior, se observa que la conexión a MongoDB a través de PHP ha sido satisfactoria.

Fig. Detalle de la ejecución de test.php.

 

Llegados a este punto en que ya tenemos el escenario correctamente montado, procedemos a la creación de la página web de Login que se indica en el ejercicio. Esta va a ser una página HTML sencilla que incluirá un formulario con campos para el nombre de usuario y la contraseña, y que enviará vía POST dichos parámetros a un script PHP que se encargue del procesamiento de los datos de estos parámetros. A continuación, se muestra el código fuente.

Fig. Detalle del código fuente de login_mongo.html.

 

A continuación, se muestra el Script PHP que llevará a cabo la autenticación en PHP. Al script lo hemos llamado “login_mongo_vuln.php”. El código fuente se muestra debidamente comentado en la siguiente captura. Cabe destacar que cara a realizar el siguiente ejercicio ya hemos implementado la vulnerabilidad en el parámetro “password”, dejando el parámetro “username” correctamente sanitizado.

Fig. Detalle del código fuente de login_mongo_vuln.php.

 

Una vez introducidos ambos archivos en el directorio “htdocs” de Xampp, procedemos a llamar vía web a la página de Login como se muestra a continuación, donde se introducen las credenciales correctas contenidas en la BBDD.

Fig. Detalle de la ejecución de login_mongo.html con credenciales correctas.

 

Tras introducir las credenciales correctas, se muestra el mensaje de bienvenida.

Fig. Detalle de la ejecución de login_mongo.html con credenciales correctas.

 

A continuación se introducen unas credenciales incorrectas.

Fig. Detalle de la ejecución de login_mongo.html con credenciales incorrectas.

 

Como se muestra en la siguiente captura, tras haber introducido unas credenciales incorrectas se devuelve el siguiente mensaje de error.

Fig. Detalle de la ejecución de login_mongo.html con credenciales incorrectas.

 

Damos así por implementada la página web de Login que solicita el ejercicio, y procedemos con el siguiente punto.

 

3. Implementación de vulnerabilidad NoSQLi en el parámetro de Contraseña.

 

La implementación del parámetro de contraseña deberá permitir una vulnerabilidad de inyección NoSQL, lo que facilitará que un usuario malintencionado obtenga el mensaje de bienvenida sin conocer la contraseña correcta.

Para hacer que solo el campo de contraseña (password) sea vulnerable a inyecciones NoSQL mientras el campo de usuario (username) no lo sea, se necesita aplicar funciones de validación o sanitización a la entrada del usuario, pero no a la de la contraseña. Así pues, a continuación se muestra el código fuente en cuestión, debidamente comentado.

Fig. Detalle del código fuente de login_mongo_vuln.php.

 

Como se puede observar, la función filter_input() con FILTER_SANITIZE_STRING se utiliza para eliminar etiquetas y codificar o eliminar caracteres especiales del nombre de usuario, lo que reduce la posibilidad (la seguridad absoluta no existe) de inyecciones NoSQL en el campo de usuario. Sin embargo, al no aplicar ninguna validación o sanitización de la entrada del usuario en el campo de la contraseña, este campo será vulnerable. Esto permitirá, como veremos más adelante, que un atacante pueda inyectar payloads específicos de MongoDB en el campo de la contraseña para alterar la consulta y poder bypassear la autenticación sin conocer ninguna contraseña.

 

Se observa que con un usuario no existente en la BBDD se devuelve error, ya que para bypassear la autenticación se necesita conocer un usuario existente en la BBDD.

Fig. Detalle de la respuesta de la aplicación.

 

Se observa que con un usuario existente en la BBDD se bypassea correctamente la autenticación con la inyección NoSQL realizada en el parámetro password, el cual es vulnerable.

Fig. Detalle de la respuesta de la aplicación.

 

De esta manera ha quedado demostrada manualmente la vulnerabilidad en el parámetro “password”.

Para finalizar, me gustaría decir que para testar la seguridad de aplicaciones que utilizan MongoDB y específicamente buscar vulnerabilidades como inyecciones NoSQL, se puede hacer uso de la herramienta “NoSQLMap”, la cual está diseñada para automatizar las tareas de detección y explotación de vulnerabilidades de este tipo de inyecciones. Esta herramienta realmente puede ser utilizada para testar aplicaciones que usan varias bases de datos NoSQL, como MongoDB, CouchDB, entre otras. La podemos instalar desde su repositorio oficial como se muestra a continuación.

Fig. Detalle de la instalación de NoSQLMap.

 

4. Medidas para prevenir vulnerabilidad NoSQLi.

 

Para evitar vulnerabilidades de inyección NoSQL, o NoSQLi, en la aplicación PHP que nos atañe y que interactúa con MongoDB, se pueden tomar las siguientes medidas.

 

En lugar de construir consultas directamente a partir de cadenas que incluyen entrada del usuario, utilizar métodos y funciones que proporcionan los drivers de MongoDB para PHP que aseguran que los valores sean tratados adecuadamente y escapados de manera segura.

A continuación, se muestra el código correctamente parcheado y comentado.

Fig. Detalle del código fuente parcheado.

 

A continuación, se verifica que la vulnerabilidad ha sido correctamente subsanada empleando las mismas pruebas del punto anterior donde se comprobó la existencia de la vulnerabilidad.

Fig. Detalle de la respuesta de la aplicación.

 

BIBLIOGRAFÍA

Para lo que necesiten no duden en contactarnos en info@jaymonsecurity.com

Salir de la versión móvil