1. 堆叠注入
通过;分隔并执行多条SQL语句的攻击方式。
堆叠注入(Stacked Query Injection) 是一种通过注入分号 ;
分隔并执行多条SQL语句的攻击方式。与普通注入仅修改原语句不同,堆叠注入允许攻击者“堆叠”额外SQL命令,直接执行任意数据库操作(如删库、提权),危害性极强。
!!!在非授权的情况下,属于危险操作,十分敏感,一不小心就会吃牢饭
1.1. 堆叠注入操作原理
- 利用分号分隔符:
数据库支持在单次请求中用;
分隔执行多条SQL语句(如MySQL、MSSQL),攻击者通过注入;
插入恶意命令。
SELECT * FROM users WHERE id=1; DROP TABLE users; --+
-
- 原语句:查询用户信息。
- 注入语句:删除整个用户表。
- 依赖数据库特性:
-
- 支持堆叠的数据库:MSSQL、PostgreSQL(默认支持)。
- 不支持堆叠的数据库:MySQL(PHP中
mysql
扩展默认禁用,但PDO可开启)、Oracle(需特定配置)。
1.1.1. 防御堆叠注入
- 禁用多语句执行:
-
- 配置数据库连接参数,禁止单次请求执行多条语句(如MySQL的
allowMultiQueries=false
)。
- 配置数据库连接参数,禁止单次请求执行多条语句(如MySQL的
参数化查询:
-
- 使用预编译语句(PreparedStatement)严格绑定参数,阻止语句拼接。
// PHP PDO示例(禁用多语句)
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$stmt = $pdo->prepare("SELECT * FROM users WHERE id=?");
$stmt->execute([$input_id]);
- 输入过滤与白名单:
-
- 过滤分号
;
、注释符--
等危险字符(仅对非必需场景有效,不可依赖)。
- 过滤分号
- 最小数据库权限:
-
- 应用使用的数据库账号禁用高危操作(如
DROP
、GRANT
)。
- 应用使用的数据库账号禁用高危操作(如
1.1.2. 总结
堆叠注入是“SQL注入的终极形态”,可完全控制数据库。防御核心在于:
- 禁用多语句执行(数据库层)
- 强制参数化查询(代码层)
- 权限最小化(运维层)
2. 宽字节注入
- 是一种利用数据库字符编码漏洞绕过转义防护的注入攻击方式,常见于使用GBK、GB2312等多字节编码的系统中(尤其是PHP+MySQL场景)。其核心是通过构造宽字节字符(如
%df%27
),使转义符(反斜杠\
)被“吞并”导致单引号逃逸,从而闭合SQL语句。 - 通常情况下,SQL注入是通过单引号’来识别。但是当数据经过addslashes()处理时单引号会被转义成无功能字符,此时我们可以利用宽字节字符集(GBK)会将输入的特殊字节和单引号识别为汉字,通过反斜线转义机制,让单引号逃逸,从而可以实现注入。
2.1. 字符编码漏洞
- GBK编码特性:某些多字节编码(如GBK)允许两个字节组成一个汉字字符。例如:
-
%df%5c
→運
(%df5c
是GBK编码的汉字)%5c
本身代表反斜杠\
。
- 转义失效过程:
-
- 用户输入单引号
'
→ 被PHP的addslashes
或mysql_real_escape_string
转义为\'
(即%5c%27
)。 - 攻击者输入
%df%27
(即%df'
):
- 用户输入单引号
-
-
- 转义后变为
%df%5c%27
→運'
(GBK将%df%5c
解析为運
,剩余%27
即单引号'
)。 - 最终构造出未闭合的单引号
'
,触发注入。
- 转义后变为
-
2.1.1. addslashes()
函数的作用与原理
addslashes()
是 PHP 中用于对字符串进行转义的函数,主要功能是在特定字符前添加反斜杠(\
),防止这些字符破坏 SQL 语句结构。其转义规则如下:理论上,转义后的单引号会被闭合,阻止注入。
$str = "It's a test";
echo addslashes($str); // 输出:It\'s a test
- 转义目标字符:
-
- 单引号
'
→\'
- 双引号
"
→\"
- 反斜杠
\
→\\
- NULL 字符
\0
→\\0
- 单引号
2.2. 操作步骤
操作环境:PHP,MySQL,使用gbk编码,会对输入转义
目的:因为PHP代码中含有addslashes()函数 会增加转义字符,将我的?id=1'转变为?id=1\',使单引号闭合,阻止注入
- 这种情况在单引号前输入%df,通过gbk编码,使单引号逃避,让我们可以进行注入
- 构造?id=1%df ',页面有报错回显,说明单引号成功逃逸,并没有被转义掉,再
?id=1%df'--+
。
- 使用?id=-1 %df' union select 1,2,3 判断注入点,
- 使用union 联合语句爆出数据库
后续操作通过前面学习过的执行构造SQL语句进行进一步的数据获取