Le nom parle de lui-même : cette faille apparaît quand il est possible d'injecter du code SQL dans les requêtes SQL qui sont faites dans une page web
. C'est actuellement la "meilleure" vulnérabilité Web en rapport fréquence/surface d'exploitation. Les conséquences d'une faille SQL peuvent être multiples, du contournement de formulaires d'authentification au dump complet de la base de données en passant par l'exécution arbitraire de code. Dans ce premier article, nous allons essayer de nous familiariser avec des injections simples (appellées aussi injections du premier ordre).
L'idée est bien souvent de zapper une variable de la requête, par exemple un mot de passe. Une requête SQL classique pour la vérification de mots de passe est SELECT * from admins WHERE login='$login' AND password='$password', en français "Sélectionner les lignes de la base de données qui appartiennent à la table "admins" et dont les champs pseudo et password sont respectivement égaux aux variables $pseudo et $password". Ainsi, il y a deux manières de passer l'identification sans avoir le mot de passe, voir même le pseudo :
- Imaginons que le programmeur vérifie qu'il existe des lignes qui répondent correctement à la requête SQL, autrement dit il vérifie que le nombre de lignes renvoyées n'est pas égal à 0. Imaginons que nous envoyons comme pseudo ' OR 1=1#, le # étant le caractère de commentaire supprime tout ce qui le suit dans la requête (selon les serveurs, on trouve aussi -- ou les commentaires style C /* */). Ainsi, la requête devient SELECT * from admins WHERE login='' OR 1=1, ce qui se lit "Sélectionner les lignes de la base de données qui appartiennent à la table "admins" et qui on soit un pseudo nul, soit telles que 1=1". Vous l'avez compris, 1=1 est une expression toujours vraie, par conséquent cette requête renverra toutes les lignes de la base de données. Ainsi, le nombre de lignes est différent de 0 et l'utilisateur aura bypass cette requête.
- La deuxième manière est beaucoup plus sûre, elle permet de s'identifier en tant qu'un pseudo connu à l'avance. Ainsi, vous remplissez le champ pseudo convenablement (il est souvent assez aisé de connaître certains pseudos réels) et injectez du code SQL comme précédemment dans le champ mot de passe. Ainsi, la requête devient vraie uniquement pour la ligne contenant le pseudo de la victime et vous devenez identifié en tant que la personne ciblée. Ainsi, même si le programmeur a vérifié qu'il n'existait qu'une ligne correspondant au couple (pseudo,mot de passe), vous passerez l'identification.
Ce type de faille est en général facile à reconnaître, puisque si l'on injecte un simple guillemet dans le formulaire, une erreur du type suivant interviendra : Warning: mysql_numrows(): supplied argument is not a valid MySQL result resource (pour peu que les rapports d'erreurs soient activés, ce qui est le cas par défaut ; sinon il est tou de même possible en général d'observer des différences de comportement comme l'apparition page vide).
Voici une liste non-exhaustive d'instructions toujours vraies qui peuvent être utilisées (certains sites se défendent en dressant une liste de ce type d'instructions, ce qui est stupide puisque il y en a une infinité). Attention, tous ne marchent pas dans tous les cas, réfléchhissez à chacune d'entre elles pour être bien sûr d'avoir compris !
'='
'OR 1=1
'OR a=a
'OR'
'OR''='
'OR"="
'OR'="
'OR '="
'OR "='
'OR ''='
'OR '=''
'OR "=''
'OR ''="
En ce moment, un nouveau type est à la mode, les UNION qui imposent de connaitre un minimum la morphologie de la requête, ou du moins de la deviner :
UNION ALL SELECT pseudo,password FROM admins
UNION ALL SELECT pseudo,password FROM admins WHERE pseudo='OR 1=1# AND password='OR ''="
UNION ALL SELECT pseudo,password FROM admins WHERE pseudo='OR "=' AND password='OR "='
Un petit exemple
Comme d'habitude, nous allons prouver nos dires par un petit exemple. Notre exemple est composé de 3 pages : index.php, la page de login du site, auth.php, la page de vérification de l'authentification, et enfin la page qui est protégée, admin.php (qui n'est pas réellement protégée, mais volontairement bloquée par referrer, ce qui nous permettra d'illuster le HTTP headers spoofing). Nous nous sommes placés dans le cas où l'utilisateur connait le pseudo d'un des admins (ce qui est pratiquement toujours le cas), SeriousHack. Il est à remarquer que dans énormément de sites, root, admin, administrator ou webmaster sont aussi des logins très courants.
<!-- index.php - Bases Hacking Administration login Page -->
<html>
<head>
<body>
</html>
<?
?>
<?
<html>
<head>
<body>
</html>
<html>
<head>
- <div align="center"><h1>Bases Hacking Administration Zone</h1></div>
<title>Faille de type SQL Injection</title>
<body>
- <img src="../images/penguinroot.gif">
<br><br>
<div align="center">
<form action="./auth.php" method="POST">
- <table>
- <tr>
- <td>Login</td>
<td><input type="text" name="pseudo" maxlength="30"></td>
<tr>
- <td>Pass</td>
<td><input type="password" name="mdp" maxlength="30"></td>
<tr><td colspan=2 align="center"><input type="submit" name="login" value="Login"></td></tr>
</div>
</html>
<?
- // auth.php - Authentification des admins Bases Hacking
$login = $_POST["pseudo"];
$mdp = $_POST["mdp"];
if ($login != "" && $mdp != "") {
@mysql_connect("localhost", "serioushack", "mdpmysql") or die("Impossible de se connecter à la base de données");
@mysql_select_db("users") or die("Table inexistante");
$resultat = mysql_numrows(mysql_query("SELECT * from admin WHERE pseudo='$login' AND mdp='$mdp';"));
mysql_close();
if ($resultat == 1) echo "Authentification réussie, vous allez être redirigés immédiatement. <script>window.location='./admin.php'</script>";
else header("Location: ./");
?>
<?
- //admin.php - Bases Hacking Administration Panel
$headers = http_get_request_headers(); //On récupère les headers et on vérifie que l'user est passé par auth.php
if (!isset($headers["Referer"]) || $headers["Referer"] != "http://".$headers["Host"]."/hacking/admin/auth.php")
- header("Location: ./");
<html>
<head>
- <div align="center"><h1>Bases Hacking Administration Zone</h1></div>
<title>Faille de type SQL Injection et Referrer Spoofing</title>
<body>
- <img src="../images/penguinroot.gif">
<br><br>
[Message d'accueil]
</html>
Comme prévu, la requête est modifiée par notre injection et nous réussissons à afficher admin.php (qui nous aurait redirigés si nous n'étions pas au préalable passés par auth.php), et ce sans le moindre mot de passe !
Les injections SQL sont communes, sous des formes plus ou moins faciles à exploiter et à démasquer. Ceci dit, unr programmation rigoureuse permet de les éradiquer aisément. Un court article de recommandations de programmation Web sécurisée vous donnera plus d'informations sur les bonnes pratiques permettant d'éviter ce genre de failles.
betmatik
RépondreSupprimerkralbet
betpark
tipobet
kibris bahis siteleri
poker siteleri
bonus veren siteler
mobil ödeme bahis
slot siteleri
QNQ0M