SQL注入之floor()报错注入
FSRC经验分享”系列文章,旨在分享焦点安全工作过程中的经验和成果,包括但不限于漏洞分析、运营技巧、SDL推行、等保合规、自研工具等。
欢迎各位安全从业者持续关注!
全文约1980字 推荐阅读时间 5分钟
SQL注入利用的是页面反馈数据库报错的内容,最常见的类型就是回显注入。而当回显注入无法使用时,通常我们会使用报错注入、bool盲注、延迟注入甚至http头注入等方法。本文为报错注入中常见的 floor() 报错相关复现及分析。
floor()报错注入是利用下方这个相对固定的语句格式,导致的数据库报错。
select count(*),(floor(rand(0)*2)) x from users group by x
实际利用中通过 concat 函数,连接注入语句与floor(rand(0)*2) 函数,就实现了注入结果与报错信息回显的注入方式。
本文以一个有6行数据的表【user】为例进行说明,注入涉及到几个关键函数的作用:count() 、group by 、floor()、rand() 。
floor(rand(0)*2)函数
floor() 函数的作用就是返回小于等于括号内该值的最大整数,也就是取整。
floor(rand(0)*2) 就是对 rand(0) 产生的随机序列乘以2后的结果,再进行取整。
得到伪随机序列为如下图所示:
group by 函数
group by 主要用来对数据进行分组(相同的分为一组)。
例如建立如下表进行实验:
count(*)函数
count(*) 统计结果的记录数。这里与group by结合使用看一下:
这里就是对a中的重复性的数据进行了整合,然后计数,后面的x就是每一类的数量。也就是lisi有2个,wangwu有1个,zhangsan有3个。注意显示同样是按照ascii排序。
语句:
select count(*),floor(rand(0)*2) x from users group by x;
group by在执行时,会依次取出查询表中的记录并创建一个临时表,group by的对象便是该临时表的主键。如果临时表中已经存在该主键,则将值加1,如果不存在,则将该主键插入到临时表中。mysql执行结果,会产生 011011 这个序列,group by时,会建立空虚拟表(如图),然后从sql语句执行结果序列(011011)读取数据并插入虚表:
虚表写入第一条记录,执行floor(rand(0)*2) ,发现结果为0(此时为第一次计算)。查询虚拟表,发现0的键值不存在,则插入新的键值的时候 floor(rand(0)*2)会被再计算一次,结果为1(此时为第二次计算),插入虚表,第一条记录插入完毕,结果为1。如下图:
虚表写入第二条记录,再次计算floor(rand(0)*2),发现结果为1(此时为第三次计算),结算结果为1,查询虚表,发现1的键值存在,所以floor(rand(0)*2)不会被计算第二次,直接count(*)加1,第二条记录查询完毕,结果如下:
虚表写入第三条记录,再次计算floor(rand(0)*2),发现结果为0(此时为第4次计算),计算结果为0,此时虚表中没有0的数据记录,则执行插入该数据,插入时会再次计算floor(rand(0)*2)(此时为第5次计算),计算结果为1。然而1这个主键已经存在于虚拟表中,而新计算的值也为1(主键键值必须唯一),所以就产生了主键冲突的错误,也就是:Duplicate entry 的报错。
虚表中写入第三条记录时,产生了报错。此时floor(rand(0)*2)一共被计算了5次,这也解释了为什么数据表中需要最少3条数据才会报错的原因。
tips:rand的种子可以不一定是0,但是如果是其他的数值,何时重复不确定,所需的数据条数也需要更多(因为要一直到重复才可以)。
关于floor()报错注入,你真的懂了吗?(by 酒仙桥六号部队)
https://www.freebuf.com/articles/web/257881.html
本文中提到的相关资源已在网络公布,仅供研究学习使用,请遵守《网络安全法》等相关法律法规。
本文编辑:小错