C/C++教程

【SQLi-Labs】Less-5 GET - Double Injection - Single Quotes - String

本文主要是介绍【SQLi-Labs】Less-5 GET - Double Injection - Single Quotes - String,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

 本节练习涉及到了一个新的概念:双注入。

双注入简单理解为一个select查询里嵌套一个select查询,如果要利用双注入需要人为构造特定的能够造成报错的查询,从而在报错信息里返回我们需要的数据。需要用到的函数和语句有:

1.concat() 作用为连接括号里的参数。例concat(1,~,2) 结果为 1~2

2.floor() 作用为对括号里的非整数进行取整 如1.9取为1,2.1取为2

3.count() 作用为针对查询结果条数进行计数

4.rand() 作用为生成0-1范围内的随机数 (1.括号内如果填写一个固定参数,则每次生成的随机数固定;2.使用* 运算符,可以使取值范围扩大,如 rand()*2 的取值范围为0-2)

5.group by [key]对查询结果进行分组,针对每一个key 列出一条结果。

6.group by [key]和 conut(*)联用,作用为列出所有可能的key和key的查询结果条数。

最后再介绍一种错误类型:Duplicate entry

       这种错误一般发生于数据库对某一个字段有UNIQUE限制的情况下,例如某员工信息表里对身份证号字段设置的UNIQUE限制,即不能出现重复的身份证号,当我们插入一条新员工信息时,输入表中已存在的身份证号时就会报Duplicate entry错误,即重复录入。

双重注入构造报错查询的原理就大致基于以上的函数、方法和错误类型,下面是构造查询的思路:

1.首先,rand([整数]) from [x表] ,会基于x表的记录条数,生成数量与x表记录条数相同的随机数序列,又因为指定了rand的参数,根据上面第4条,每次生成的随机数序列都是相同的。

2.接着,rand([整数])*2 from [x表],使得生成的随机数序列的范围从0-1变成了0-2

3.然后 floor(rand([整数])*2 from [x表]), 使得结果变成了非0即1(因为随机数结果范围为0.000000...1到1.999999...9)。

4.再然后,使用payload和非0即1的查询作concat连接,例如

select concat((select database()),floor(rand(14)*2))
from information_schema.tables

  得出的结果长得像这样

 5.把这个结果利用group by 进行计数

select
concat((select database()),floor(rand(14)*2)) as a,
count(*) 
from information_schema.tables 
group by a

6.出现报错

且某些信息也通过报错信息显示出来了。

发生这个报错的原因如下:

1.使用count(*)和group by 进行计数时,系统会自动生成一张临时表,这里称它为 T

2.T里有两个字段,一个叫group_key,内容为"group by x" 中的x,另一个字段叫tally,内容是根据x分组而重复的记录数。

3.当我们使用

select
concat((select database()),floor(rand(14)*2)) as a,
count(*) 
from information_schema.tables 
group by a

 这个查询的时候,内层查询首先查询出来的是这个结果序列,然后再对这个序列进行分组计数。

分组计数的时候,会遍历临时表T,查看即将要插入的key值是否在T表中存在。

1.系统在先临时表T中查找concat((select database()),floor(rand(14)*2)))这个关键词,发现没有这个关键词,于是准备要把它填入第一行的group_key字段里。

2.但不巧的是是这句查询本应作为一个字符串被填入,其实它经过了执行才被填入,因此临时表T第一行的group_key被填上security1,tally填1。

3.接着系统又在临时表T中查找concat((select database()),floor(rand(14)*2)))这个关键词,发现还是没有这个关键词,于是准备要把它填入第二行的group_key字段。

4.它又被执行后填入,临时表T的第二行group_key被填上security0,tally填1

5.继续遍历,发现又没有,又填,这次执行后的值是security1,等到执行插入的时候发现这个在第一行已经填过了,而group_key这个字段使UNIQUE的所以报二次输入的错误,并暴露出相关信息。

根据以上所有理论,可以构造payload

?id=-1' union select 1,concat((select table_name from information_schema.tables where table_schema='security' limit 1,1),floor(rand(14)*2)) as a,count(*) from information_schema.tables group by a--+

结果如下:

 

修改limit限制可以爆本库下所有表名

同理利用payload可以爆更多数据

至此,本节结束。

这篇关于【SQLi-Labs】Less-5 GET - Double Injection - Single Quotes - String的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!