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: http://blog.elevenpaths.com/2014/10/como-funcionan-las-mongodb-injection.html
Suscribirse a:
Enviar comentarios (Atom)
No hay comentarios:
Publicar un comentario