**堆叠注入(Stacked Query Injection)**是一种 SQL 注入攻击技术,攻击者通过注入多个 SQL 语句到一个查询中,利用数据库支持堆叠查询的特性(即在同一条查询中执行多个 SQL 语句)来执行恶意操作。这类攻击利用了某些数据库管理系统(DBMS)允许多个 SQL 语句在一个查询中堆叠执行的特性,通常通过分号(;
)分隔不同的 SQL 语句。
堆叠注入的目的是让攻击者在一个请求中执行多个 SQL 语句,从而绕过应用程序的某些限制,进行信息泄露、数据删除、数据修改或其他恶意操作。
注入多个 SQL 语句: 攻击者通过 SQL 注入漏洞,将多个 SQL 语句连接在一起。每个 SQL 语句由分号(;
)隔开。攻击者可以将第二个 SQL 查询插入到第一个查询后,以执行多个操作。
通过分号分隔多个查询: SQL 查询中的分号(;
)通常用于分隔不同的 SQL 语句。若目标数据库支持堆叠查询,攻击者可以利用这个特性注入多个 SQL 语句。
执行恶意操作: 攻击者通过堆叠注入可以执行如:
数据库信息泄露(例如,查询系统表、用户信息、密码等)。
数据修改或删除(例如,更新用户密码或删除数据)。
提权操作(例如,通过操作权限表提取管理员权限等)。
假设某个 Web 应用程序的用户登录系统中存在 SQL 注入漏洞,攻击者可以注入多个 SQL 语句,通过分号 ;
来连接注入的恶意 SQL 查询。
假设应用程序的 SQL 查询如下:
SELECT * FROM users WHERE username = '[user_input]' AND password = '[password_input]';
攻击者通过 SQL 注入进行堆叠注入,输入如下:
' OR 1=1; DROP TABLE users; --
第一个查询 OR 1=1
使得条件 1=1
成立,通常用于绕过验证,返回所有数据或正确的结果。
第二个查询 DROP TABLE users
会删除 users
表。
注释符 --
用于注释掉后续的 SQL 代码,避免影响查询的正确执行。
最终执行的 SQL 查询变为:
SELECT * FROM users WHERE username = '' OR 1=1; DROP TABLE users; --' AND password = '[password_input]';
如果数据库允许堆叠查询,执行顺序为:
执行 SELECT * FROM users WHERE username = '' OR 1=1
,通常返回所有用户数据或跳过用户名验证。
执行 DROP TABLE users
,删除整个 users
表。
攻击者可以通过堆叠注入来获取敏感信息并删除数据。例如,输入:
' OR 1=1; SELECT * FROM information_schema.tables; --
这将使 SQL 查询变为:
SELECT * FROM users WHERE username = '' OR 1=1; SELECT * FROM information_schema.tables; --' AND password = '[password_input]';
此查询的执行顺序是:
第一个查询 SELECT * FROM users WHERE username = '' OR 1=1
仍然绕过身份验证。
第二个查询 SELECT * FROM information_schema.tables
会返回数据库中的所有表名(信息架构表的内容)。
攻击者还可以执行更新操作,如更改用户密码。假设注入如下:
' OR 1=1; UPDATE users SET password = 'newpassword' WHERE username = 'admin'; --
执行的 SQL 查询将变为:
SELECT * FROM users WHERE username = '' OR 1=1; UPDATE users SET password = 'newpassword' WHERE username = 'admin'; --' AND password = '[password_input]';
此时数据库执行的操作是:
SELECT * FROM users WHERE username = '' OR 1=1
成功绕过验证。
UPDATE users SET password = 'newpassword' WHERE username = 'admin'
会将管理员账户的密码修改为 'newpassword'
。
防止堆叠注入的关键是确保应用程序能正确过滤和处理用户输入,并遵循最佳的数据库安全实践。以下是一些防御措施:
使用参数化查询是防止 SQL 注入攻击的最有效方法之一。通过使用数据库驱动的参数化查询接口,可以避免动态构造 SQL 查询,从而避免注入攻击。比如,在 PHP 中使用 PDO 或 MySQLi,或在 Java 中使用 JDBC。
例如,使用 PDO 进行安全查询:
$stmt = $pdo->prepare('SELECT * FROM users WHERE username = :username AND password = :password');
$stmt->execute([':username' => $username, ':password' => $password]);
对于支持堆叠查询的数据库(如 MySQL、MariaDB),可以通过禁用多语句执行来防止堆叠注入。例如,禁用 MySQL 的 multi_statements
选项:
SET SESSION sql_mode = 'NO_BACKSLASH_ESCAPES';
确保数据库用户只具有执行特定查询所需的最小权限。如果数据库用户没有删除表或更新表的权限,即使攻击者能够注入查询,操作的影响也会受到限制。
对用户输入进行严格的过滤和验证,确保输入的内容符合预期格式。可以使用白名单方式过滤掉危险字符(如 ;
、--
、/*
等)。
配置 Web 应用防火墙(WAF)来监控并过滤 SQL 注入攻击,检测并拦截堆叠注入等恶意行为。
不要将详细的数据库错误信息暴露给用户。攻击者通过错误信息可以了解数据库结构并精确构造注入攻击。
堆叠注入是 SQL 注入攻击的一种形式,攻击者通过注入多个 SQL 语句来执行多个操作。通过分号 ;
连接的多个查询可能包括数据泄露、数据删除、数据修改等恶意操作。为了防范堆叠注入,开发者应使用参数化查询、禁用堆叠查询、限制数据库权限、进行输入验证,并使用 Web 应用防火墙等安全措施。
知识点 |
核心内容 |
考试重点/易混淆点 |
难度系数 |
堆叠注入定义 |
堆叠注入是通过在SQL语句结尾后继续添加新的SQL语句,实现多条SQL语句一次执行。 |
堆叠注入与联合注入的区别,堆叠注入的执行条件和局限性。 |
★★★ |
堆叠注入演示 |
演示了如何通过分号闭合前一条SQL语句,并在其后添加新的SQL语句进行注入。 |
堆叠注入的实际操作步骤和注入点的识别。 |
★★★★ |
堆叠注入条件 |
堆叠注入需要数据库支持堆叠执行,如MySQL,而Oracle等数据库则不支持。 |
不同数据库对堆叠注入的支持情况。 |
★★ |
堆叠注入与联合注入对比 |
堆叠注入可以执行多种类型的SQL语句(如INSERT、DELETE、UPDATE),而联合注入只能执行SELECT语句。 |
堆叠注入和联合注入的适用场景和限制。 |
★★★ |
堆叠注入实战应用 |
在实际环境中,通过堆叠注入可以插入、删除或修改数据库中的数据。 |
堆叠注入的实战技巧和防御方法。 |
★★★★ |
WIFI绕过与防御篇章预告 |
预告了下节课将学习WIFI绕过和防御相关的内容。 |
- |
★ |