Outils d'utilisateurs

Outils du Site


failles_web:sql_injection

Ceci est une ancienne révision du document !


Injection SQL

Introduction

Pour dynamiser un site on est très souvent amené à utiliser des bases de données afin de stocker des informations. Par exemple, un site d'information stockera ses news dans sa base de donnée. Pour parler avec cette base de données le développeur va utiliser un langage spécial : le SQL.

-- Exemple d'une requête simple
SELECT titre,auteur,contenu FROM news WHERE id = 1337

Maintenant, imaginons que chaque news est chargé dynamiquement à partir d'un paramètre de l'URL

<?php
 
mysql_connect("localhost","root","root");
mysql_select_db("sqli");
 
$news = mysql_query("SELECT titre,auteur,contenu FROM news WHERE id = ".$_GET['id']);
$news = mysql_fetch_assoc($news);
 
echo "<h1>".$news['titre']."</h1> par <i>".$news['auteur']."</i><br/>";
echo "<p>".$news['contenu']."</p>";

La sélection de la news se fait en fonction de la variable GET id. Par exemple, news.php?id=1 affichera la première news, et ainsi de suite …

Le soucis dans ce code c'est que la variable GET est utilisée directement dans la requête SQL. Le client malveillant contrôle parfaitement cette variable et peu donc à tout moment modifier le comportement de la requête afin de sélectionner ce que bon lui semble dans la base de donnée. C'est le principe de l'injection SQL.

Exploitation basique (UNION)

Contexte

On va étudier le cas d'une page qui affiche des news stockées dans une base de donnée. Notre but va être de récupérer le mot de passe de l'administrateur qui est stocké dans la base de donnée. Afin que vous puissiez reproduire ce scénario chez vous, si vous le souhaitez, voici les différentes requêtes pour créer les tables ainsi que le script PHP.

--
-- Structure de la table `news`
--
 
CREATE TABLE `news` (
  `id` INT(11) NOT NULL AUTO_INCREMENT,
  `titre` VARCHAR(255) NOT NULL,
  `auteur` VARCHAR(255) NOT NULL,
  `contenu` text NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
 
--
-- Contenu de la table `news`
--
 
INSERT INTO `news` VALUES(1, 'Première news', 'tlk', 'Contenu première news');
INSERT INTO `news` VALUES(2, 'Seconde news', 'tlk', 'Contenu seconde news');
 
-- --------------------------------------------------------
 
--
-- Structure de la table `users`
--
 
CREATE TABLE `users` (
  `id` INT(11) NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(255) NOT NULL,
  `password` VARCHAR(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;
 
--
-- Contenu de la table `users`
--
 
INSERT INTO `users` VALUES(1, 'administrateur', 'SuperPass');
<?php
 
mysql_connect("localhost","root","root");
mysql_select_db("sqli");
 
$news = mysql_query("SELECT titre,auteur,contenu FROM news WHERE id = ".$_GET['id']);
$news = mysql_fetch_assoc($news);
 
echo "<h1>".$news['titre']."</h1> par <i>".$news['auteur']."</i><br/>";
echo "<p>".$news['contenu']."</p>";
failles_web/sql_injection.1339755452.txt.gz · Dernière modification: 2017/04/09 15:33 (modification externe)