企业网站建设费用 珠海,高校文明建设网站,微信公众平台申请入口,深圳规模较大的网站建设公司简介
对于SQL注入的报错注入通常有三个函数需要我们掌握#xff1a;
extractValue(xml_frag, xpath_expr)updateXML(xml_target, xpath_expr,new_xml)floor()
对于extractValue和updateXML函数来说比较好理解#xff0c;就不做解释了#xff0c;这里只对floor函数的报错注…简介
对于SQL注入的报错注入通常有三个函数需要我们掌握
extractValue(xml_frag, xpath_expr)updateXML(xml_target, xpath_expr,new_xml)floor()
对于extractValue和updateXML函数来说比较好理解就不做解释了这里只对floor函数的报错注入进行讲解。首先我们先要知道floor()报错注入的形式 floor报错注入是利用:
select count(*),(floor(rand(0)*2)) as x from 表名 group by x这个相对固定的语句格式导致的数据库报错。实际利用中通过 concat 函数连接注入语句与 floor(rand(0)*2)函数就实现了注入结果与报错信息回显的注入方式。所以我们如果想要理解floor()报错注入的原理我们首先需要明白rand(),floor(),group by, count()这几个的意思。
rand()函数
rand() 是一个随机函数产生01的小数
通过一个固定的随机数的种子0之后可以形成固定的伪随机序列 这样我们加上种子之后这个数据就出现了可预测性。
floor()函数
那么floor报错注入利用的时候rand(0)*2为什么要乘以 2 呢这就要配合floor 函数来说了 floor()函数和JavaScript中的Math.floor()函数的作用是一样的也就是向下取整。 rand(0) 0~1 rand(0)*2 0~2 那么floor(rand(0)*2) 要么0 要么1 这个时候我们再来看看之前的查询
group by
这个就是分组相同的数据会分到同一组。 分组的原理很简单就是会产生一张临时表插入临时表之前会先判断临时表中是否有对应的key 如果没有就插入临时表有就不插入大概原理就是这样。 分组后
count(*)
统计数量如果结合group by 就是统计分组的数量。
报错分析
我们了解了几个函数的作用之后我们来看看到底是怎么报错的。 先报个错看看 从报错信息看这个地方group_key冲突了。 这个group_key为什么会冲突呢我们分析分析 从前面floor(rand(0)*2) 得知当我们执行查询
select floor(rand(0)*2) from user_rule的时候会产生固定的序列 011011011 这个时候再结合group by 会产生一个虚拟表我们来探讨过程 1.虚表写入第一条记录执行floor(rand(0)*2)发现结果为0(此时为第一次计算)
操作keyfloor(rand(0)*2)count(*)取第一条记录0
2.查询虚拟表发现0的键值不存在则插入新的键值的时候floor(rand(0)*2)会被再计算一次结果为1(此时为第二次计算)插入虚表第一条记录插入完毕结果为1。
操作keyfloor(rand(0)*2)count(*)取第一条记录0插入记录111
3.虚表写入第二条记录再次计算floor(rand(0)*2)发现结果为1(此时为第三次计算)此时结算结果为1所以floor(rand(0)*2)不会被计算直接count(*)加1第二条记录写入完毕。查询虚表发现1的键值存在所以floor(rand(0)*2)不会被计算第二次第二条记录查询完毕
操作keyfloor(rand(0)*2)count(*)取第一条记录0插入记录111取第二条记录不用插入112
4.虚表写入第三条记录再次计算floor(rand(0)*2)发现结果为0(此时为第4次计算)计算结果为0此时虚表中没有0的数据记录则执行插入该数据插入时会再次计算floor(rand(0)*2)此时为第5次计算计算结果为1。然而1这个主键已经存在于虚拟表中而新计算的值也为1(主键键值必须唯一)所以就产生了主键冲突的错误也就是Duplicate entry 的报错。
操作keyfloor(rand(0)*2)count(*)取第一条记录0插入记录111取第二条记录不用插入112取第三条0插入记录1 冲突1
总结 在虚表中写入第三条记录是时产生了报错。此时floor(rand(0)*2)一共被计算了5次所以数据表中需要最少3条数据才会报错。 另外要注意加入随机数种子的问题如果没加入随机数种子或者加入其他的数那么floor(rand()*2)产生的序列是不可测的这样可能会出现正常插入无法报错的情况。最重要的是前面几条记录查询后不能让虚表存在0,1键值如果存在了那无论多少条记录也都没办法报错因为floor(rand()*2)不会再被计算做为虚表的键值这也就是为什么不加随机数种子有时候会报错有时候不会报错的原因。
执行报错语句获取数据
爆库
SELECT * FROM user_rule WHERE id 1 AND (SELECT 1 from
(SELECT count(*),concat(0x23,(SELECT schema_name from information_schema.schemata LIMIT 0,1),0x23,floor(rand(0)*2)) as x
from information_schema.COLUMNS GROUP BY x)
as y)爆表
SELECT * FROM user_rule WHERE id 1 AND (SELECT 1 from
(SELECT count(*),concat(0x23,
(SELECT table_name from information_schema.TABLES WHERE table_schema database() LIMIT 0,1),
0x23,floor(rand(0)*2)) as x
from information_schema.COLUMNS GROUP BY x)
as y)爆列
SELECT * FROM user_rule WHERE id 1 AND (SELECT 1 from
(SELECT count(*),concat(0x23,(SELECT column_name from information_schema.COLUMNS where table_name members LIMIT 0,1),
0x23,floor(rand(0)*2)) as x
from information_schema.COLUMNS GROUP BY x)
as y)