Quand un tel code est utilisé dans un script de login :
$password = Request.Form("password")
SELECT field FROM database WHERE Login=$login AND Password=$password
il est possible de "valider" un login sans savoir le nom d’utilisateur et le mot de passe.
Pour que ce soit possible il est nécessaire d’avoir certaines conditions :
1. La requête SQL doit ressembler à celle-ci :
SELECT filed FROM DATABASE WHERE Login=$login AND Password=$Password
où les variables $login et $password résultent des champs du formulaire d’authentification que l’utilisateur remplit pour s’authentifier (page html, php, asp, cgi...)
2. Le script ne verifie pas la présence pour ces deux variables de mauvais caractères tels que : ’ ;)"#|
3. Une fois le script validé aucune vérification de mauvais caractères n’est faite sur ces deux variables.
Si ces 3 conditions sont réunies, il est possible d’outre passer le mécanisme d’authentification.
Forcer la modification de la requête SQL d’authentification Examinons la requête SQL :
où les variables $login et $password résultent des champs du formulaire d’authentification que l’utilisateur remplit pour s’authentifier.
Quand l’utilisateur essai de s’authentifier en entrant aucun login/password dans le formulaire, les variables $login et $password prendrons comme valeur " Ceci limite la vulnérabilité des chaines qui se finissent par ’ (Pour que la vulnérabilité fonctionne, il faut une requête SQL valide, sans erreur).
Une requête SQL normale issue d’une authentification d’un utilisateur normal ressemble à ceci :
ou le login est jon et le mot de passe est 1234
Si vous essayez maintenant en mettant le caractère ’ à la place du login, le serveur SQL va retourner " SQL bad syntax error" puisque que la requête est incompléte
Nous devons faire attention à fermer correctement la requette SQL (rajouter ’ pour faire une requête complète) pour créer une requête valide.
Par exmeple :
Si nous remplaçons la valeur de $login par ’or"=’ et la valeur de $password par ’or"=’ nous aurons la requête SQL suivante :
NOTE : 'or"=" retourne toujours VRAI
Que ce passe t’il quand on soumet une telle requête SQL qui retourne toujours VRAI ? La requête SQL va vérifier dans la base de donnée si nous avons rentré le bon login et le bon mot de passe. La requête SQL va retourner VRAI car la vérification du "or" logique va toujours retourner VRAI ! Ce qui fait croire au script d’authentification que nous avons rentré le bon login et le mot de passe correspondant. De plus, le script d’authentification, si aucune vérification supplémentaire n’est opérée, nous donnera l’accès sous l’identité du premier utilisateur inscrit dans la base de données, le plus souvent, l’administrateur.
Forcer partiellement la modification de la requête SQL d’authentification Comme nous l’avons vu ci-dessus, il y a plusieurs moyens de contourner l’authentification si les conditions son réunies. Il est aussi possible de modifier partiellement la requête SQL ce qui nous permettrait une attaque plus ciblée (login avec un utilisateur connu au lieu de se logger avec le premier utilisateur de la base de données...).
Il est possible de gagner les droits d’accès d’un utilisateur si l’on connait son nom d’utilisateur.
Par exemple :
Si l’on envoie toujours par le biais du formulaire la valeur jonn à $login et ’or"=" à $password, alors nous serons capable de nous logger sous l’identité de jonn et nous profiterons de ses droits.
Forcer le serveur SQL à ignorer une partie de la requête SQL Il est possible de force le serveur à ignorer une partie de la requette SQL en incluant dans la requête SQL envoyée /* et /* ( balises commentaire)
Par exemple :
Si l’on envoie toujours par le biais du formulaire la valeur ’/* à $login et */ OR "=’ à $password la requête SQL sera alors :
SELECT field FROM database WHERE Login = ’’/*’ AND Password = ’*/ OR ’’ = ’’
Une fois parsée par le serveur SQL, la requête SQL deviendra :
Cette requête renvoie toujours VRAI !
Voici un autre exemple, dans certains scripts, l’adresse email est utilisée et vérifiée comme Login. Il est possible de créer un login valide, qui passera sans problème la requête SQL et la vérification du format d’adresse email du script.
Si l’on envoie la valeur ’/*mi@mail.com à la variable $login et */ or "=’ à la variable $password, le script va parser la variable $login et vérifier si c’est bien du format EMAIL *@*.*, et le serveur SQL va parser la requête en enlevant ce qu’il y a entre les commentaire /* */ nous permettant de passer l’authentification comme nous l’avons vu plus haut.
Solution : Il existe plusieurs solutions pour résoudre ce problème. Une solution serait d’utiliser du JavaScript pour valider les caractères rentrés par l’utilisateur, mais cela peut être aussi contourné en construisant son propre formulaire d’envoi de données au script d’authentification.
Exemple de JavaScript :
function checkstring(text){
pat=/^[A-Za-z0-9]{6,10}$/;
result=text.match(pat);
return TRUE;
}
function Send(){
if (checkstring(txtName) && checkstring(txtPassword)){
login.submit();
}
}
</SCRIPT>
Voici un autre exemple en PHP :
Avant (aucune vérification pour les charactéres) :
$login_rs = @mysql_query("SELECT * FROM cro_user WHERE
user_login='$luser' AND user_password='$lpassword' AND user_status!='0'
LIMIT 0,1",$db);
if (@mysql_num_rows($login_rs)==0) {
echo "LOGGED ON";
}
}
Pour outre passer ce mécanisme vous pouvez entre comme login et mot de passe cette valeur : ’|
Voici comment corriger ce probléme :
Aprés (toutes les vérifications sont faites) :
$lpassword = trim(htmlspecialchars(addslashes($lpassword)));
if ($luser!="" && $lpassword!="") {
$login_rs = @mysql_query("SELECT * FROM cro_user WHERE
user_login='$luser' AND user_password='$lpassword' AND user_status!='0'
LIMIT 0,1",$db);
if (@mysql_num_rows($login_rs)==0) {
echo "LOGGED ON";
}
}
Document original par Memonix : http://www.securiteam.com/securityn... paru le 13/08/2001 Traduit le 13/08/2001 par Cabezon Aurélien http://www.iSecureLabs.com








Documentation publiés dans cette rubrique