SQL的Limit注入

Limit

Limit 偏移量,行数
位置偏移量是指MySQL查询分析器要从哪一行开始显示,索引值从0开始,即第一条记录位置偏移量是0,第二条记录的位置偏移量是1,依此类推...,第二个参数为“行数”即指示返回的记录条数。

benchmark

benchmark函数有两个参数,第一个是执行次数,第二个是要测试的函数或者表达式
比如 benchmark(10000000,sha1(1))
意思是执行sha1函数10000000次

extractvalue()

extractvalue() :对XML文档进行查询的函数
语法:extractvalue(目标xml文档,xml路径)
第二个参数 xml中的位置是可操作的地方,xml文档中查找字符位置是用/xxx/xxx/xxx/…这种格式,如果我们写入其他格式,就会报错,并且会返回我们写入的非法格式内容,而这个非法的内容就是我们想要查询的内容。

updatexml()

updatexml()函数与extractvalue()类似,是更新xml文档的函数。
语法updatexml(目标xml文档,xml路径,更新的内容)
和extractvalue()一样,在路径处写入非法格式内容

注入

limit后面能够拼接的函数只有into和procedure,into可以用来写文件,我们不考虑。在Limit后面 可以用 procedure analyse()这个子查询来调用extractvalue()或者updatexml(),如果报错被关闭了,用benchmark产生时延就可以做盲注。

floor报错注入

使用函数

  • count():统计个数
  • rand():产生随机数
  • floor():向下取整
  • group by:排序

注入及原理粗解

一个典型payload:

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

简单的说floor报错注入的原理,floor(rand(0)*2)的值是定性的,前几位的顺序为011011,当使用group by的时候,floor(rand(0)*2)会执行一次,如果虚表中不存在floor(rand(0)*2)的结果的key值,则值插入虚表,而插入虚表的时候floor(rand(0)*2)会再执行一次,报错的产生实际上就是因为floor(rand(0)*2)的多次执行导致的
查询第一条记录,floor(rand(0)*2)执行,结果为0(第一次计算),虚表中key值无0,floor(rand(0)*2)再被执行一次,此时结果为1(第二次计算),插入虚表

keycount(*)
1(第二次计算)1

查询第二条记录,floor(rand(0)*2)执行,结果为1(第三次计算),虚表中key值有1,count(*)+1,floor(rand(0)*2)并不再次执行

keycount(*)
1(第二次计算)2

查询第三条记录,floor(rand(0)*2)执行,结果为0(第四次计算),虚表中key值无0,尝试插入数据到虚表,此时floor(rand(0)*2)再次执行,结果为1(第五次计算),而1在虚表的key值中已经存在,主键key值必须唯一,插入时产生报错

rand(0)*2与rand()*2报错的区别

rand(0)*2得到的结果顺序是固定的,而rand()*2是随机的,但是在上面的解释中我们已经知道了只要查询计算出现这样的情况就能产生报错

查询计算
第一次计算
第三次计算(与二四次不同)
插入计算
第二次计算(两者相等)
第四次计算(两者相等)

如果出现这种情况就无法报错

keycount(*)
11
01

所以rand()*2的报错方式有的时候能报错有的时候不能

sql注入中的一些绕过方式

内联注释绕过

内联注释就是把一些特有的仅在MYSQL上的语句放在/* */中,这样这些语句如果在其它数据库中是不会被执行,但在MYSQL中会执行。

空格过滤绕过

一般绕过空格过滤的方法有以下几种方法来取代空格

  • /**/
  • ()
  • 回车(url编码中的%0a)
  • `(tap键上面的按钮)
  • 两个空格

过滤等号=绕过

  • 不加通配符的like执行的效果和=一致
  • regexp:MySQL中使用 REGEXP 操作符来进行正则表达式匹配
  • <> 等价于 !=,所以在前面再加一个!结果就是等号了

过滤引号绕过

  • 使用十六进制
  • 宽字节,常用在web应用使用的字符集为GBK时,并且过滤了引号