30 oct 2014

Cómo funcionan las MongoDB Injection

Las inyecciones SQL han sido tradicionalmente uno de los vectores de ataque más utilizados por los atacantes. De hecho, es una de las técnicas más eficaces para el robo y la alteración de información sensible. Sin embargo, no existe (aún) una marcada tendencia hacia la explotación de las llamadas bases de datos NoSQL, o sea, bases de datos no relacionales pensadas para el almacenamiento de grandes cantidades de información. De entre todas estas bases de datos NoSQL, quizá el representante más ilustre sea MongoDB. ¿Es inmune a las inyecciones?

¿Qué es MongoDB?

El nombre MongoDB, viene del inglés "humongous" (inmenso). Es un sistema de base de datos no relacional de código abierto y orientado a documentos. MongoDB se basa en colecciones de documentos Json, lo que le otorga una gran flexibilidad en cuanto a la naturaleza de la información que almacena, puesto que puede haber documentos con diferente esquema dentro de una misma colección.

De MongoDB destaca su gran velocidad y escalabilidad, porque puede manejar sin apenas esfuerzo volúmenes de datos del orden de gigabytes. En los últimos tiempos, su nómina de clientes ha crecido considerablemente; Foursquare, MTV, The New York Times, etc. ya lo utilizan.

¿Es MongoDB vulnerable a inyecciones?

Al no tratarse de una base de datos SQL, podría parecer que MongoDB no es vulnerable a inyecciones maliciosas. Sin embargo, veremos que no es así. Se pueden realizar muchos tipos de inyecciones en MongoDB, aunque la viabilidad del ataque depende en gran medida del driver de Mongo utilizado.

Por ejemplo, en PHP es posible realizar una inyección muy similar a la clásica inyección SQL, alterando la consulta de manera que devuelva todo el contenido de una colección. Imaginemos la típica consulta de credenciales que hay tras un login. En SQL, sería algo como lo que sigue:

SELECT * FROM tUsers WHERE username = ‘username’ AND password = ‘password’
La consulta equivalente en MongoDB sería:
$collection -> find(array(
  "username" => $_GET[‘username’],
  "password" => $_GET[‘password’] ));
El problema es que PHP permite pasarle objetos al driver de MongoDB, sin que tengan que ser necesariamente strings. Explotando esta vulnerabilidad, podemos pasar un objeto que fuerce una condición "true" y provoque el volcado de la colección. Por ejemplo, enviando una petición como esta:
login.php?username=administrador&password[$ne]=1
Obtendríamos una consulta interna de esta forma:
$collection -> find(array( 
  "username" => "administrador"
  "password" => array("$ne" => 1) ));
Esta consulta devuelve las credenciales de todos los usuarios cuyo nombre de usuario y contraseña sea distinto ("not equal", $ne) de 1, condición que probablemente cumpla cualquier contraseña.

La solución pasa por "tipar" los objetos que se le pasan al driver. El hecho de que muchos drivers de MongoDB admitan objetos no tipados supone una vulnerabilidad.

¿Cómo comprobar si se es vulnerable?

Como no podía ser de otra manera, Faast incorpora entre su batería de plugins, uno capaz de detectar vulnerabilidades de este tipo. Sin embargo, como ya se ha mencionado, la presencia de esta vulnerabilidad depende enormemente del driver utilizado en el dominio bajo análisis.

Existen multitud de drivers para MongoDB. El plugin de Faast está orientado a detectar inyecciones en MongoDB, aprovechando la capacidad del motor Mongo para ejecutar Javascript. Utiliza la técnica de time-based detection para determinar si la URL que recibe como parámetro es vulnerable, aprovechando a su vez el comando "sleep" de MongoDB, que bloquea todas las operaciones de la base de datos durante un determinado período de tiempo.

Por ejemplo, tras recibir la URL, el plugin de Faast realiza dos peticiones independientes, concatenando las siguientes cadenas a la URL original. En la primera se ejecuta un sleep durante 10 segundos, en la segunda, no.
;if(tojson(this)[0] =="{")) {sleep("10000")};
;if(tojson(this)[0] =="{")) {sleep("0")}
Para determinar si es posible inyectar, se compara el tiempo de respuesta de ambas peticiones. Si la diferencia de tiempos es superior a un determinado umbral, se considera positivo y por tanto la URL es vulnerable. Para minimizar la influencia de tiempos de propagación, etc… y evitar falsos positivos, la prueba se repite un número determinado de veces. Será necesario que el resultado de los N intentos sea positivo para considerar la URL como vulnerable.

El auge que están viviendo los motores de bases de datos no relacionales, hace que se conviertan en un objetivo prioritario para los atacantes. Aunque las inyecciones SQL siguen siendo frecuentes, ya no representan una novedad en el mundo del cibercrimen, y las recetas y buenas prácticas para evitarlas están muy estudiadas. Sin embargo, las bases de datos NoSQL suponen un territorio nuevo que explorar. Por eso Faast pretende adelantarse a los atacantes y facilitar que se tomen las medidas adecuadas para salvaguardar la integridad de los datos de los clientes.

Fuente: ElevenPath

Suscríbete a nuestro Boletín

0 Comments:

Publicar un comentario

Gracias por dejar un comentario en Segu-Info.

Gracias por comentar!