Injections SQL avancées, l’art de l’exploitation [Partie 1]

Jusqu’à présent, je n’ai trouvé aucun tutoriel sur le net qui détaille assez bien les injections SQL. On en trouve souvent pour outrepasser un formulaire de connexion, mais pour ce qui des vraies injection avec la méthode UNION, c’est très mal expliqué dans la plus part des cas. Alors, je me suis dis qu’il était grand temps d’arranger ça. Aujourd’hui, vous allez enfin comprendre ces foutues injections et par la suite vous allez vous sentir un peu con d’avoir utilisé Havij !

 

Préparons le terrain

Vous aurez besoin d’Apache, PHP et MySQL en local.

Nous allons créer un script tout simple, qui récupère le nom, le prénom ainsi que l’âge d’un membre, suivant l’ID récupéré en GET.

Commençons par voir  la structure de la base de données :

 ╔══════╤═══════════╤════════╗
 ║  ID  │ Name      │  Age   ║
 ╠══════╪═══════════╪════════╣
 ║  1   │ John      │   24   ║
 ╟──────┼───────────┼────────╢
 ║  2   │ Jeff      │   19   ║
 ╟──────┼───────────┼────────╢
 ║  3   │ Jerry     │   42   ║
 ╚══════╧═══════════╧════════╝

Je vous copie le code nécessaire si vous voulez tester, le but de ce tutoriel n’étant pas de coder ce genre de système.

MySQL :

--
-- Structure de la table `users`
--

CREATE TABLE IF NOT EXISTS `users` (
`id` int(2) NOT NULL AUTO_INCREMENT,
`name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`age` int(3) NOT NULL,
PRIMARY KEY (`id`),
KEY `id` (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=4 ;

--
-- Contenu de la table `users`
--

INSERT INTO `users` (`id`, `name`, `age`) VALUES
(1, 'John', 24),
(2, 'Jeff', 19),
(3, 'Jerry', 42);

Et le petit script PHP qui va avec :

mysql_connect('localhost', 'root', '');
mysql_select_db('sql_test');

$sql = 'SELECT id,name,age FROM users WHERE id='.$_GET['id'];
$q = mysql_query($sql) or die(mysql_error());

while($data = mysql_fetch_assoc($q)) {
	echo "ID : {$data['id']}
Nom : {$data['name']}
Age : {$data['age']}

";
}

?>

Ce script prend tout simple les informations depuis la base de données à partir de l’ID du membre.

Exemple :

Si on visite la page http://localhost/sql_test.php?id=2 ça nous affichera :

ID : 2
Nom : Jeff
Age : 19

Exploitation

Maintenant que nous avons notre script sous la main, on est fin prêt pour bidouiller !

Comme vous le voyez, le script ne présente aucune sécurité. C’est à dire qu’aucun caractère n’est filtré, bref on peut taper ce qu’on veut et surtout…modifier la requête, d’ailleurs c’est ce qu’on va faire !

Tentons de faire planter le script en donnant un argument qui n’a pas été prévu :

http://localhost/sql_test.php?id=2′

En ajoutant un ‘ à la fin de la requête, on génère une erreur de syntaxe, ce qui provoque un bug.

Je suppose que ça, vous connaissiez déjà. Car maintenant, on va passer aux choses sérieuses !

À présent, je vais vous dire un secret, approchez-vous…

Voyez cette requête : (Si vous ne connaissiez pas la méthode ORDER BY, je vous invite à consulter cette page).

SELECT * FROM users WHERE id=1 ORDER BY age

Cette requête est un peu stupide, me diriez-vous, puisqu’on sélectionne un seul membre et on tri quand même le résultat (en d’autres termes, c’est inutile de trier une liste qui comporte un seul élément). Par contre, c’est cela qui va nous servir par la suite à déduire le nombre de colonnes !

Le secret est que, pour appeler nos colonnes, on utilise souvent leur nom (ici on a id,name,age) mais ce que vous ne savez probablement pas, c’est qu’on peut les appeler par leurs ID !

Pour exemple, utilisons la même requête que celle de tout à l’heure, mais cette fois-ci en appelant la colonne par son ID :

SELECT * FROM users WHERE id=1 ORDER BY 3

Et le résultat est le même ! (il aurait était le même aussi si on avait sélectionné tous les membres et pas qu’un seul).

Vous vous demander à quoi bon cela va nous servir.. Tout simplement parce qu’on peut trouver le nombre de champ facilement avec ça !

Exemple :

http://localhost/sql_test.php?id=2 ORDER BY 1

http://localhost/sql_test.php?id=2 ORDER BY 2

http://localhost/sql_test.php?id=2 ORDER BY 3

http://localhost/sql_test.php?id=2 ORDER BY 4

Les trois premières lignes ne génèrent pas d’erreur, c’est à dire que la page ne change pas. Quand à la 4ème, la page change (dû à l’erreur). On en déduit que la colonne 4 n’existe pas, et en conséquent qu’il existe que trois colonnes. Magique, non ?

Maintenant qu’on sait qu’on a exactement trois colonnes, on peut faire un tas de choses avec !

L’UNION fait la force

Je pense que j’en ai assez dis pour cette première partie ! Dans la seconde partie nous verrons la méthode UNION qui permet, comme son nom l’indique, de grouper les résultats de plusieurs requêtes en un seul résultat. Ainsi on pourra avoir plein d’infos utiles, on va se régaler ;)

 

[image]

Rédigé par Lyes, le 1 décembre 2011 — 12 commentaires → Afficher l'article