
Descripción
The user lookup functionality for this lab is powered by a MongoDB NoSQL database. It is vulnerable to NoSQL injection.
To solve the lab, log in as carlos
.
Tip: The password only uses lowercase letters.
Exploiting NoSQL operator injection to extract unknown fields writeup
Al entrar en el laboratorio encontraremos una tienda online:

Entraremos en el apartado ‘My account’ e intentaremos entrar con el usuario ‘carlos’, pero con cualquier contraseña. La petición que encontraremos en el logger será la siguiente:

Llevamos la petición al ‘Repeater’ y modificamos el JSON de la siguiente manera:
{"username":"carlos","password":{"$ne": "test"},"$where":"1"}
Esto hace lo siguiente:
- Envía como nombre de usuario a ‘carlos’.
- Como contraseña, indicamos que sea cualquiera excepto ‘test’.
- Por último, como la condición debe ser evaluada a ‘True’ para que el inicio de sesión sea exitoso, añadimos un ‘»$where»:»1″‘, que siempre es True, consiguiendo el acceso a la cuenta.

Ahora vemos que la cuenta está bloqueada y que necesita que reseteemos la contraseña. Con el objetivo de obtener el token para resetearla, vamos a explorar la base de datos para ver todos los campos que tiene y encontrar el campo que tenemos que ver. Nos llevamos la petición al ‘Intruder’ con Ctrl + I o Click derecho -> Send to Intruder. Allí modificamos el JSON de la siguiente manera:
{"username":"carlos","password":{"$ne": "test"},"$where":"Object.keys(this)[1].match('^.{§0§}§a§.*')"}

Con esto, en el operador ‘$where’ ejecutaremos un JavaScript que se encargue de lo siguiente:
- Object.keys(this): Recupera todos los campos del objeto de la base de datos.
- [1]: Empezando por el campo 1, dado que el campo 0 suele ser el id.
- .match(‘^.{§0§}§a§.*’): Si el carácter en el lugar §0§ equivale al carácter §a§ devuelve true.
Una vez finalice el ataque, ordenando las respuestas por el Payload 1 y por la longitud de estas, podremos ver los campos. En este caso el primero es ‘username’.

Nota: Es posible hacer esto con un tercer ‘§b§’, que se encargue de recorrer todos los campos, aunque se generan en total 7.000 peticiones para 10 posibles campos. Debido a que en este laboratorio sólo hay 4 campos es más rápido y menos invasivo subir esta valor manualmente.
Al hacerlo con el resto de campos encontraremos la siguiente información:
- _id
- username
- password
- pwResetTkn
Nota: El campo número 5 (accedido con el índice 4), sólo aparecerá si entramos en «Forgot password?» e introducimos el usuario ‘carlos’. Si no, nos devolverá el código 500 en el ataque.


Ahora sabemos el nombre del campo, por lo que modificamos la petición del ‘Intruder’:
{"username":"carlos","password":{"$ne": "test"},"$where":"this.pwResetTkn.match('^.{§0§}§a§.*')"}

Nota: En este caso, la longitud del token es de 15, por lo que hay que modificar el ataque en ‘Payloads’:

Una vez finalizado, si ordenamos por orden ascendente el Payload 1 y la longitud encontraremos el token:

Copiamos este token manualmente, y nos lo llevamos a la petición del GET de ‘/forgot-password’.
Nota: Si no aparece esta petición en el logger, se puede conseguir refrescando la página que aparece al enviar el nombre de usuario, aunque esto generará un token nuevo y será necesario repetir la última parte del ataque en el ‘Intruder’.

Nota: Es importante no usar comillas al introducir el token nuevo en la URL.
Ahora, en la respuesta, damos Click derecho -> Show response in browser, que nos copiará en el portapapeles la URL. Vamos al navegador y accedemos para cambiar la contraseña de carlos:

Ahora podremos iniciar sesión en ‘My account’ con el usuario de ‘carlos’ y la contraseña que acabamos de introducir. Finalizando así el laboratorio:
