堆叠查询——sqli-labs第38/39关:StackedQueryInjection通关解析

admin 2026-01-27 14:39:16 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文解析sqli-labs第38/39关的堆叠查询注入。关卡核心在于利用分号执行多条SQL语句,源于PHP未限制多语句执行。相比受限于SELECT上下文的普通注入,堆叠查询能执行INSERT、UPDATE等任意操作,无需回显或列数匹配,危险性显著提升。文章演示了数据插入与更新的Payload,强调从注入数据到获取数据库控制权的认知转变,指出了堆叠查询在实战中的攻击优势。 综合评分: 86 文章分类: 渗透测试,WEB安全,实战经验


cover_image

堆叠查询——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 通关解析》

评论:0   参与:  0