Hi Guys,
Today, i am going to share about NoSQL injection and bruteforce. I found it is quite interesting since NoSQL was intended not be SQL Injectable as normal SQL query
This injection basically impact to all the NoSQL database below

I will try to give the detailed steps on the MongoDB database and using PHP code to make it easier to understand.
The NoSQL query explained
db.users.find( <-- Collection
{username: rioasmara,password: adminPass123}, <-- projection
{age: {$gt:20} } <-- query criteria
).limit(1)
this line db.items.find(queryObject) is composed of
db — current database object
Items — collection names ‘items’ in the current database
find — method to execute on the collection
queryObject — an object used to select data
For those who are used to a normal SQL, I would like to give sample of comparation of basic username and password check query
SQL Query
SELECT * FROM accounts WHERE username = 'rioasmara' AND password = 'adminPass123'
SQL Query Compromissed
The adversaries supply data as username = rioasmara’ —
SELECT * FROM accounts WHERE username = ‘rioasmara’ — AND password = ‘’
NoSQL Query
As we look at the below code, There is no longer string manipulation available. We now that find function will accept array
db.accounts.find({username: rioasmara, password: adminPass123});
NoSQL Injection Attack
The attack vector for the NoSQL Injection is quite similar to the common SQL injection where the attacker inject malicous code into the input parameter as show below.

Lets look at the PHP code
The code below match the username and password based on the input array given. In the code below we can see that the code developer does not do input parameter sanitation that allow the attacker to inject code into the input. We can see below the input parameter is converted directly into PHP array

if we print out the $temp variable will look like this

db.users.find( <-- Collection
{username: rioasmara,password: adminPass123} <-- Projection
).limit(1)
the above query will return document where the username is rioasmara and password is adminPass123
Lets do the injection

The new $temp variable will look like below

db.users.find( <-- Collection
{username: rioasmara},
{password: {$ne:WrongPass} } <-- Query Criteria
).limit(1)
With the above code means we are searching the document where the username is rioasmara and password is not equal to WrongPass. Since the actual password of rioasmara is adminPass123 then basically the above query will return a True condition or return one document
below is criteria operator
$ne — not equal
$gt — greater than
$regex — regular expression
$where — clause lets you specify a script to filter results
Brute Force Username and Password
With the above injection then basically we can do username and password bruteforce by injecting $regex. the code will look like below

Lets prepare the burpsuite intruder
The Injection Point
Here we will try to find user with username regex start with a char (e.g a-z,A-Z or 0-9) and password is not equal to 1 and search the return status that is 302 which means data is found and allow us to be redirected to authenticated homepage

The Payload
include all a-z, A-Z, 0-9 and all special character

The Result
The result we found that there is 302 respond status found between the other 200 respond status result. it means that the page will redirect you to other page login success.

As we are trying to find a complete username and password then basically we can repeat the above steps after we find the first char that is ‘a‘ and try to append ‘a’ with another char (e.g b) untill we find respond status 302 again. the payload will become like this

Bruteforce Automation
To automate the bruteforce we can develop a script to handle the repetition. I am not going to develop my own script but use the existing code available from https://github.com/an0nlk/Nosql-MongoDB-injection-username-password-enumeration
nosqli-user-pass-enum.py [-h] [-u URL] [-up parameter] [-pp parameter] [-op parameters] [-ep parameter] [-sc character] [-m Method]
Arguments | Description |
---|---|
-h, –h | show this help message and exit |
-u URL | Form submission url. Eg: http://example.com/index.php |
-up parameter | Parameter name of the username. Eg: username, user |
-pp parameter | Parameter name of the password. Eg: password, pass |
-op parameters | Other paramters with the values. Separate each parameter with a comma(,). Eg: login:Login, submit:Submit |
-ep parameter | Parameter that need to enumarate. Eg: username, password |
-m Method | Method of the form. Eg: GET/POST |
Bruteforce username
python3 nosqli-user-pass-enum.py -u http://localhost:9090/index.php -up username -pp password -ep password -op login:login
Bruteforce pasword
python3 nosqli-user-pass-enum.py -u http://localhost:9090/index.php -up password -pp password -ep password -op login:login