文章总结: 本文解析sqli-labs第38/39关的堆叠查询注入。关卡核心在于利用分号执行多条SQL语句,源于PHP未限制多语句执行。相比受限于SELECT上下文的普通注入,堆叠查询能执行INSERT、UPDATE等任意操作,无需回显或列数匹配,危险性显著提升。文章演示了数据插入与更新的Payload,强调从注入数据到获取数据库控制权的认知转变,指出了堆叠查询在实战中的攻击优势。 综合评分: 86 文章分类: 渗透测试,WEB安全,实战经验
堆叠查询——sqli-labs 第 38 / 39 关:Stacked Query Injection 通关解析
原创
武文学网安 武文学网安
武文学网安
2026年1月27日 03:17 中国香港
大家好,我是武文。 在做第 38 / 39 关的时候,我一开始其实有点“被误导”—— 因为我发现 UNION select、updatexml 都可以非常轻松地注入成功,一度以为这关只是个普通的显错 / 联合查询关卡。
但继续往下看关卡标题和行为后才意识到: 这两关真正要讲的,并不是 UNION,而是一个新的能力:Stacked Query(堆叠查询)。
一、第 38 / 39 关整体说明
官方标题:
-
38:GET – Stacked Query Injection-string
-
39:GET – Stacked Query Injection-Intiger based
两关核心完全一致,仅请求方式不同,因此合并讲解。
| 项目 | 说明 | | — | — | | 请求方式 | GET / | | 页面回显 | 有正常回显,有报错 | | 注入类型 | Stacked Query(多语句执行) | | 常见利用 | UNION / Error-based / INSERT / UPDATE / DROP,其中 UNION / Error-based 并非 stacked query 本身,而是关卡同时存在的普通注入方式 | | 核心前提 | 数据库接口允许多语句执行 |
一句话概括:这是 sqli-labs 第一次,明确允许你在一次请求中执行多条 SQL 语句。
二、什么是 Stacked Query Injection(核心概念)
2.1 什么叫 Stacked Query?
Stacked Query(堆叠查询)指的是:在一个 SQL 执行请求中,通过分号‘ ;’,让数据库执行多条独立的 SQL 语句
例如:
SELECT * FROM users WHERE id=1;SELECT database();
在正常、安全的应用中:
- ❌ 只允许执行一条 SQL
- ❌ 分号后的语句会被禁止或忽略
而在第 38 / 39 关:
- ✅ 分号 被 MySQL 接受
- ✅ 后面的 SQL 会被真实执行
2.2 为什么这件事很危险?
因为这意味着:
- 注入不再局限于 “改查询结果”
- 而是可以 直接执行任意 SQL 语句
比如:
; INSERT INTO users VALUES(…); UPDATE users SET password=…; DROP TABLE users;
👉 这已经从「注入」升级为 “数据库命令执行能力”
三、第 38 / 39 关为什么能 Stacked Query?
3.1 根本原因(不是 SQL 语法)
不是因为 MySQL 支持多语句,MySQL 一直支持。
而是因为:PHP 使用的数据库接口,“没有刻意关闭 / 限制”多语句执行能力。这并不是一个“刻意为之”的危险操作,而是开发者没有意识到 multi_query 的风险。
我们通过查看关卡源码可以发现:
使用了mysqli_multi_query方法,mysqli_multi_query()函数接受表示查询的字符串值作为参数之一,并在数据库上执行/执行给定的查询。执行一个 SQL 语句,或者多个使用分号分隔的 SQL 语句。
在真实环境中,以下场景会导致问题:
- 使用
mysqli_multi_query() - PDO 关闭了
ATTR_EMULATE_PREPARES - 没有限制
CLIENT_MULTI_STATEMENTS
👉 应用层允许了多语句
四、实战发现 UNION / updatexml 也“轻易通过”?
这是我在做这一关时,最先产生的疑问:
“既然是 stacked query,为什么不用分号,UNION 和 updatexml 也能打?”
答案其实很简单:
Stacked Query 是“额外能力”,不是“唯一能力”。
五、不应该把“考点”当成“唯一解”
第 38 / 39 关存在两个事实:
事实一:SQL 本身就存在注入点
原始 SQL 类似:
SELECT * FROM users WHERE id=’$id’
这意味着:
- UNION 注入 ✔
- Error-based 注入 ✔
- Boolean 注入 ✔
这是第一层漏洞
事实二:数据库接口允许多语句执行
这意味着你还可以:
1′; SELECT database(); –+
这是第二层漏洞
👉 stacked query 是 “新增能力”,而不是 “替代能力”
六、为什么 updatexml 在这里也能成功?
我用的 payload 类似:
?id=1′ and updatexml(1,concat(0x7e,database(),0x7e),1)–+
updatexml 仍然属于同一条 SQL 语句执行,并未使用分号,因此打的是普通显错注入。
但这并不矛盾,因为:
- ✔ 关卡存在普通注入
- ✔ 同时允许 stacked query
七、那 stacked query 到底“强”在哪里?
我们对比一下能力层级:
7.1 UNION / Error-based 能做什么?
- 读数据
- 构造查询结果
- 前提:必须在 SELECT 上下文
7.2 Stacked Query 能做什么?
你可以执行:
?id=1′; INSERT INTO users(id,username,password) VALUES(‘999′,’hacker’,’123′) –+
特点是:
- 不依赖 SELECT
- 不需要回显位
- 不需要列数匹配
这意味着,即使没有任何回显,stacked query 依然可能完成攻击。
👉 在真实攻击中,stacked query 的危险性 远高于 UNION
八、第 38 / 39 关示例 Stacked Query
38和39并无本质区别,仅闭合方式差异,第38关为单引号闭合,第39关为整数型。
以下示例仅用于靶场环境。
8.1 基础验证
?id=1′; INSERT INTO users(id,username,password) VALUES(‘999′,’hacker’,’123′) –+
然后我们可以查看我们输入的数据是否被成功插入。
可以看到我们的数据被成功插入,且能在前端进行显示。 8.3 更新数据 ?id=1'; UPDATE users SET password='hahaha' WHERE username='hacker' --+
小结
第 38 / 39 关很容易被“打通就走”,但真正的价值在于一个认知转变:从“我能不能查到数据”,变成“我现在能让数据库执行什么命令”。
UNION 和 updatexml 能成功,只是说明:
- 这里存在注入
而 stacked query 的出现,说明:
- 我们已经开始拥有“数据库控制权”的雏形了。
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:武文学网安 武文学网安 武文学网安《堆叠查询——sqli-labs 第 38 / 39 关:Stacked Query Injection 通关解析》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。










评论