文章总结: 本文解析SQLi-Labs第40/41关盲注堆叠查询注入技术。虽无回显,但利用堆叠查询可执行任意SQL。文章演示了修改数据及删表操作,强调在盲注场景下利用堆叠查询进行行为控制的巨大安全隐患,其危险性远超传统数据窃取。 综合评分: 88 文章分类: WEB安全,渗透测试,漏洞分析
Blind 注入的终极形态 —— Stacked Query,qli-labs 第 40 / 41 关通关解析
原创
武文学网安 武文学网安
武文学网安
2026年1月28日 03:00 四川 标题已修改
大家好,我是武文。今天我们来学习实践一下盲注版的堆叠查询注入。
如果只从页面表现来看,第 40 / 41 关和前面的盲注关卡几乎一模一样:
- 没有报错
- 没有数据回显
- 页面反馈极其有限
但当我真正做完这两关后才意识到: 它们并不是“又一关盲注”,而是一次能力层级的跃迁。
在前面的盲注关卡中,我们解决的问题是:
“SQL 有没有被执行?”
而在第 40 / 41 关,问题升级成了:
“既然 SQL 一定会被执行,那我能让它执行什么?”
一、第 40 / 41 关在盲注体系中的真实定位
从技术分类上看,第 40 / 41 关依然属于盲注:
- 页面不回显查询结果
- 无法通过 UNION / 显错直接拿数据
- 需要通过逻辑或行为侧面验证
但它和传统盲注有一个本质区别:
👉 数据库接口允许 stacked query(多语句执行)
这意味着:
- 我们不再局限于
and 1=1 / and 1=2 - 不再只是“判断条件真假”
- 而是可以在盲注的前提下, 直接执行第二条、第三条 SQL 语句
二、“盲注的升华”
可以用一句话概括第 40 / 41 关的变化:
盲注负责“确认存在”,stacked query 负责“扩大能力”。
对比一下能力差异就非常清晰:
| 阶段 | 你能做什么 | | — | — | | 传统布尔盲注 | 判断条件真假 | | 时间盲注 | 推断数据内容 | | 40 / 41 关 | 在盲注前提下执行任意 SQL |
也就是说:
- 盲注 → 信息确认阶段
- stacked query → 行为控制阶段
三、为什么页面“什么都不显示”,但攻击反而更危险?
这正是很多人第一次做 40 / 41 关时的错觉:
“页面没变化,是不是没注入?”
实际上恰恰相反:
- 页面不显示 ≠ SQL 没执行
- 错误被吞掉 ≠ 语句被拒绝
在这两关里:在闭合正确的前提下,SQL 主体一定会进入执行流程,只是执行结果不再可见。
而 stacked query 的出现,正好绕过了“结果不可见”这个限制:
我不需要你告诉我结果,我只需要你执行命令。
若此时谁在后面跟了一句drop table甚至是删库的命令,这将是非常严重的后果。
四、这也是为什么后端验证如此重要
由于页面不会给出任何直接反馈, 在第 40 / 41 关中,我并没有纠结于前端表现,而是:
-
通过 stacked query 修改数据库状态
-
再使用 MySQL客户端从后端直接观察:
-
数据是否被插入
-
字段是否被更新
-
行为是否真实发生
这一步,本质上已经非常接近真实攻击场景。
明确了这一点之后,接下来的实战思路就非常清晰了:
先完成闭合测试,确认盲注成立; 再验证 stacked query 是否可用; 最后通过数据库状态变化进行确认。
下面,从最基础的闭合测试开始。
五、Stacked Query 再确认
5.1 判断闭合方式
这里有个小插曲,我一开始判断闭合方式为简单的单引号,因为在?id=1’报错,使用?id=1′ and ‘1’=’1 时正常。这时由于前几关的惯性思维忘记了还有括号的方式需要验证,以至于后续浪费了很多时间。
?id=1′ 异常?id=1′) –+ 正常
可以初步推断闭合方式为单引号+括号,
?id=1′) and 1=1 –+ 正常?id=1′) and 1=2 –+ 异常
可以得出结论:
闭合方式为单引号+括号。
5.2 盲注
这一关页面无报错等显示,仅适用于盲注。具体利用盲注获取数据可参考盲注章节介绍。本关卡主要是学习理解盲注下的堆叠注入。
#
5.3 堆叠注入尝试
尝试分号
?id=1'; --
但这一步不是为了看页面, 而是为了确认:分号有没有被 SQL 接受。很明显,分号已经被接受。
构造 stacked payload
?id=1'); UPDATE users SET password='blind_test' WHERE username='admin';
此时,我们可以在mysql中查看数据信息,可以发现我们的admin密码已经被更新为blind_test。
这里之所以能够成功执行 UPDATE,并不是因为“盲注都能堆叠”,而是因为当前 payload 所在的位置,已经完成了原 SQL 语句的语法闭合, 分号真正成为了语句终止符,后续 UPDATE 才以“独立语句”的身份进入执行流程。
若我们此时要使坏,删掉这个表:
?id=1); drop table users;
此时后台数据库表格users的数据就直接被删掉了。
41 关由于参数本身为整数型,不需要额外的引号或括号闭合,其余验证逻辑与 40 关完全一致。这里就不再过多描述,节省给位读者的时间。
结语
如果只从“通关”角度看:
- 第 40 / 41 关并不复杂
但从安全理解角度看,它非常重要。
你被迫接受三个事实:
1️⃣ 页面是否回显 ≠ SQL 是否执行 2️⃣ 注入的终点不是“查数据”,而是“控制行为” 3️⃣ stacked query 在盲注场景下,危险性远超 UNION
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:武文学网安 武文学网安 武文学网安《Blind 注入的终极形态 —— Stacked Query,qli-labs 第 40 / 41 关通关解析》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。










评论