Base de connaisances

Injection SQL

leave a comment »

Injection SQL

D’une grand popularité, l’injection SQL est relativement sympa à mettre en place. Elle a un fort impact sur le système attaqué. L’utilisation du langage SQL est fortement répondu dans le monde des applications web. La syntaxe de SQL mélange les instructions de bases du langage avec les saisies utilisateurs. On va essayer de mieux comprendre la chose à travers deux exemples. Merci de prendre un peu de temps avec notre ami à tous pour comprendre les technologies utilisées à côté de SQL.

Exemple 1

Dans cet exemple, on aura besoin d’une 2 champs pour introduire un nom d’utilisateur et un mot de passe. On crée une liste à l’aide de l’instruction SQL qui suit

CREATE TABLE users ( 
   id INTERGER PRIMARY KEY, 
   username VARCHAR(30), 
   password VARCHAR(41)
);

On choisit 41 caractères pour le mot de passe, car la fonction SQL PASSWORD() réalise un hash du mot de passe de 41 caractères. Le mot de passe n’apparaîtra pas en clair dans la base de données. On peut obtenir les informations qu’on désire de la table user_table si le couple nom d’utilisateur et mot de passe existe. La requête en SQL peut être la suivante :

SELECT id FROM users WHERE username='MonUtilisateur' AND password='PASSWORD('monMDP')

Ainsi, si le couple (MonUtilisateur, monMDP) existe, alors l’id de cet utilisateur sera retourné, sinon rien. Si on écrit cette requête en JAVA, on obtient un code s’approchant de celui-ci :

String query = "SELECT id FROM users WHERE "username = '"+ username + "' AND " + "password = 
               PASSWORD('" + password + "')";

On chercher à obtenir l’id de notre utilisateur. Imaginons maintenant qu’une personne entre comme nom d’utilisateur ‘OR 1=1 — et comme mot de passe test.  On obtient la requête suivante :

SELECT id FROM users WHERE username = ''OR 1=1 --' AND password = PASSWORD('test')";

Dans le langage SQL,, le tiret double introduit un commentaire. La requête n’est prise en compte jusqu’au tiret double , ainsi ‘ AND password = PASSWORD(‘test’) n’est pas considéré. Dans le cas présent, on connaît la requête, mais elle est souvent obscure. Comment faire ?

On utilise le troisième point présenté dans le fonctionnement des attaques par injection, c’est-à-dire le message d’erreur fourni par l’application lorsqu’elle n’arrivera pas à exécuter notre requête. Le message d’erreur est assez explicite pour nous faire comprendre notre erreur. On peut comprendre son erreur, l’erreur peut nous faire savoir que la requête n’attendait pas des caractères, mais un entier. On corrigera ainsi notre exemple pour mettre OR 1=1 — et non ‘OR 1=1 —. la différence est le .

Tant que la syntaxe est correcte, on peut effectuer des instructions. Le code peut devenir pour l’exemple pris :

SELECT id FROM users WHERE username = ''OR 1=1 --; DROP TABLE users;

Cette commande réaliser l’instruction SELECT, car syntaxiquement correcte, puis on détruit la table users. On a notre attaque par injection SQL. L’exploitation est relativement simple.

Exemple 2

On va utiliser DVWA pour cette exemple. La démonstration montrera les trois niveaux de sécurité proposé par cet outil de tests de vulnérabilités. On va prendre chaque niveau et expliquer les problèmes qu’on y rencontre. Une chose avant de commencer. Cet outil est en PHP, on connaît maintenant une des 3 choses à savoir pour correctement attaquer. On se retrouve à chaque fois devant le champ suivant :

user_ID

Niveau 1 : Low

Si on teste directement notre expression favorite, ‘OR 1=1 ‘, nous obtenons le message d’erreur suivant :

error_low_sql_injection

Ce message, à lire attentivement, nous dit qu’on a un problème de proximité de  »’. On avons 3 fois ‘, il nous manque un quatrième pour faire la paire. Nous allons mettre ‘OR 1=1 —‘ pour faire les deux déjà présent dans l’expression et les deux nôtres pour que l’expression OR 1=1 — soit prise correctement en compte. 

ok_expression_low_sql_injection

On pourrait tester chaque ID et récupérer son utilisateur, mais avec cette méthode nous obtenons l’ensemble des utilisateurs comme visible ci-dessous.

low_all_users

Un autre manière de faire un commentaire en SQL est #. On obtient le même résultat que ci-dessus avec l’expression ‘ or 1=1 #. On a vu qu’on a un SELECT avec 2 champs dans la requête avec le First name et la Surname, on peut demander à notre base de données d’autres informations comme l’utilisateur de la base et le nom de la base avec l’expression ‘ or 1=1 union select user(),database() #. Le résultat est

low_expression_user_database

Selon l’information que l’on souhaite avoir, nous allons construite notre expression. On va chercher le couple utilisateur et mot de passe.

Written by olivier

9 juin 2014 à 12:00

Laisser un commentaire