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
Mostrando entradas con la etiqueta mongoDB. Mostrar todas las entradas
Mostrando entradas con la etiqueta mongoDB. Mostrar todas las entradas
Cómo funcionan las MongoDB Injection
Publicado por
Unknown
en
19:56
domingo, 9 de noviembre de 2014
Etiquetas:
mongoDB,
NoSQL
0
comentarios
Tip para inyecciones en Mongo DB
En auditorías donde nos encontramos ante bases de
datos NOSQL como puede ser Mongo DB uno de los problemas con los que nos
solemos encontrar al igual que con bases de datos SQL es el filtrado de
los parámetros enviados, este filtrado con la idea de combatir
inyecciones se suele centrar en el remplazo o escapado de caracteres
como las comillas simples o las dobles y las backslash, pero como
veremos en este artículo a veces cuando nos encontramos ante ciertas
situaciones es posible sin necesidad de escapar los caracteres entre los
que se encuentra enjaulado el parámetro existe posibilidad de obtener
todos los resultados de una colección.
En el
ejemplo siguiente, si se estuviesen filtrando caracteres como las
comillas simples o las dobles y las backslash no podríamos inyectar otra
instrucción
{ "ip" : " Parámetro_enviado_por_GET "}
Sin
embargo si nos encontrásemos con un escenario como el siguiente que aun
no siendo tan común es posible, no sería necesario escapar los
caracteres anteriormente mencionados para poder armar una buena en la
auditoría por ejemplo listando todos los resultados de la colección.
{ "ip" : { $regex: ' Parámetro_enviado_por_GET ', $options: 'i' }}
Y
es que como veremos a continuación, basta con añadir dos caracteres que
raramente son tenidos en cuenta a la hora de filtrar los datos de
entrada a la aplicación
Así
de sencillo dos puntos o cualquier otro carácter y un asterisco y como
se aprecia nos devuelven todos los resultados de la colección, en este
caso 50, así que ya sabéis chavales añadid un caracter cualquiera y un
asterisco a vuestros diccionarios de inyecciones que os pueden dar una
grata sorpresa en vuestras auditorías, a mí me la dio, ya que me
devolvieron todos los usuarios y sus datos de la colección ordenaditos
en una tabla, que más se puede pedir.
Fuente: http://code-disaster.blogspot.com/2014/09/tip-para-inyecciones-en-mongo-db.html
Documentación de apoyo: http://whk.elhacker.net/index.php?topic=2863.0
Suscribirse a:
Entradas (Atom)
