mysql set语句_从强网杯随便注浅析mysql存储过程
从强网杯随便注浅析mysql存储过程
Author: Smity
去年的强网杯,出了一道mysql堆叠注入叫随便注,这道题被好多比赛玩了一整年,直到现在还是有各种新姿势,但是今天我忽然想到似乎没有对这个题目有一个很认真的分析,因此这里总结一下这个题目的出题用意和原本的预期做法:
堆叠注入
Stacked injections:堆叠注入。从名词的含义就可以看到应该是一堆sql语句(多条)一起执行。而在真实的运用中也是这样的,我们知道在mysql中,主要是命令行中,每一条语句结尾加 ; 表示语句结束。这样我们就想到了是不是可以多句一起使用。这个叫做stacked injection。代码中和一般查询不同的是,使用了multi_query函数
在SQL中,分号(;)是用来表示一条sql语句的结束。试想一下我们在 ; 结束一个sql语句后继续构造下一条语句,会不会一起执行?因此这个想法也就造就了堆叠注入。而union injection(联合注入)也是将两条语句合并在一起,两者之间有什么区别么?区别就在于union 或者union all执行的语句类型是有限的,可以用来执行查询语句,而堆叠注入可以执行的是任意的语句。
源码分析
<?php
$inject = $_GET['inject'] ?? false;
if ($inject) {
$preg_match = 'return 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 (eval($preg_match)) {
echo "您输入了敏感字符!";
exit();
}
if(stristr($inject, "set") && stristr($inject, "prepare")){
echo "请不要同时输入set和prepare";
exit();
}
当时的强网杯似乎在stristr这个函数上漏写了i导致大家用大小写绕过,但是没事这个不是重点(逃)
这里过滤了很多查询关键字,比如select,比如盲注用的函数,基本上是没有办法的,但是这里是堆叠注入,就给了我们以执行多条sql语句的机会。
很多同学自然就想到了set+prepare的预处理语句,但是这里规定了不能够同时输入set和prepaere,又被堵死了,但是mysql还有一个可以让语句分开执行且达到等同于一起执行的效果,这里介绍一下正解,mysql的存储过程。
存储过程
存储过程(Stored Procedure)是一种在数据库中存储复杂程序,以便外部程序调用的一种数据库对象。
存储过程是为了完成特定功能的SQL语句集,经编译创建并保存在数据库中,用户可通过指定存储过程的名字并给定参数(需要时)来调用执行。
存储过程思想上很简单,就是数据库 SQL 语言层面的代码封装与重用。类比面向对象编程的类。说白了,存储过程就是具有名字的一段代码,用来完成一个特定的功能。
大家看下面这个很熟悉的例子,这个例子在网络上是教程范例,给大家熟悉一下。无非就是in和out。
create 存储过程,然后call调用。
鉴于很多人不太理解这个in和out的区别,我们再简单提一提。
in——传入参数(只索取,不给予)
调用者可以给"过程"一个值,但是过程不会把这个值返回给你。
比如:
mysql> delimiter $$
mysql> set @p_in=1;
mysql> create procedure in_param(in p_in int)-> begin-> select p_in;-> set p_in=2;-> select p_in;-> end$$
mysql> delimiter ;
mysql> call in_param(@p_in);
+------+
| p_in |
+------+
| 1 |
+------+
1 row in set (0.00 sec)#因为这里先set了p_in=1,所以存储过程里select p_in的值为1+------+
| p_in |
+------+
| 2 |
+------+
1 row in set (0.00 sec)#然后set p_in=2,所以存储过程里第二个select p_in的值为2Query OK, 0 rows affected (0.00 sec)mysql> select @ p_in;
+------+
| p_in |
+------+
| NULL |
+------+
1 row in set (0.00 sec)#存储过程执行完,他不会把这个值调用者,调用者在过程外是不能够使用这个变化后的值的
in参数就是只能输入,不能够输出,执行完过程,in参数是不会改变的。
out——传出参数(不索取,只给予)
mysql> delimiter //
mysql> create procedure out_param(out p_out int)-> begin-> select p_out;-> set p_out=2;-> select p_out;-> end-> //
mysql> delimiter ;
mysql> set @p_out=1;
Query OK, 0 rows affected (0.00 sec)mysql> call out_param(@p_out);
+-------+
| p_out |
+-------+
| NULL |
+-------+
1 row in set (0.00 sec)+-------+
| p_out |
+-------+
| 2 |
+-------+
1 row in set (0.00 sec)Query OK, 0 rows affected (0.00 sec)
out这个参数刚好就是反过来,调用者无论怎么给参数赋初始值,"过程"里都是当作空值开始处理,然后将处理好的值返回给调用者。
分离预处理语句
好了说了这么多,我们还是要结合题目来看看,题目这里明显是要用预处理set 和 prepare来做,但是不能够同时输入。经过上面的讲解,我们可以想到,虽然set和prepare不能够同时输入,但是我只要把set给封装到一个"过程"中去,是不是就可以利用存储过程来代替set呢?
再理一遍大家很熟悉的set preare的注入poc怎么写:
114514';set @string = hex;prepare stmt from @string;EXECUTE stmt;#
这个地方的string就是我们要执行的sql语句的16进制表示,stmt则是预处理语句的别名。
然后我们把他分为两个部分:
set @string = hex;
和
prepare stmt from @string;EXECUTE stmt;
首先我们需要创建一个将set包含进去的存储过程,然后分析输入和输出参数: 1. in参数是sql注入语句的16进制,因为需要绕过敏感字符过滤,并且我们需要输入这个hex给过程拿去利用; 2. out参数则是我们的set里的@string——预处理语句,在"过程"中赋值好以后,拿出来给我们的prepare使用。
因此我们的poc可以这么写:下面的uuid代表php代码生成的随机数。 第一次输入存储过程的定义:
114514';create procedure `{$uuid}`(out string text(1024), in hex text(1024))BEGINSET string = hex;END;;--
第二次用call调用这个存储过程(@decoded其实就是传参,传到上一个poc的string位置,为了和string区分开,就用了另一个名词):
114514';call `{$uuid}`(@decoded, 0x{$sql});prepare payload from @decoded;execute payload;;--
之后就会正常的执行set+prepare的注入了。
总结
其实大家如果实在不清楚这个in和out,可以使用inout来代替,inout参数是既可以输入,又可以输出。
说白了存储过程就是sql语句里的函数,可以封装代码,所以比赛中如果遇到了不能一起使用的关键字,可以尝试着使用存储过程将其分割开。
声明:笔者初衷用于分享与普及网络知识,若读者因此作出任何危害网络安全行为后果自负,与合天智汇及原作者无关!
mysql set语句_从强网杯随便注浅析mysql存储过程相关推荐
- 获取mysql存储过程返回值_从强网杯随便注浅析mysql存储过程
作者:Smity 合天智汇 去年的强网杯,出了一道mysql堆叠注入叫随便注,这道题被好多比赛玩了一整年,直到现在还是有各种新姿势,但是今天我忽然想到似乎没有对这个题目有一个很认真的分析,因此这里总结 ...
- mysql打印语句_最全总结 | 聊聊 Python 数据处理全家桶(Mysql 篇)
点击上方"AirPython",选择"加为星标" 第一时间关注 Python 技术干货! 1. 前言 在爬虫.自动化.数据分析.软件测试.Web 等日常操作中, ...
- mysql死锁语句_记一次神奇的Mysql死锁排查
背景 说起Mysql死锁,之前写过一次有关Mysql加锁的基本介绍,对于一些基本的Mysql锁或者死锁都有一个简单的认识,可以看下这篇文章为什么开发人员需要了解数据库锁.有了上面的经验之后,本以为对于 ...
- mysql执行语句_实时查看MySQL执行的语句
我们在追查MySQL问题和性能调优时,有时希望看到当前都有哪些命令正在被执行,让我们迅速找到热点命令.下面我们就来介绍下如何查看当前正在执行的MySQL语句. 日志LOG 我们之前在 用service ...
- mysql修改语句_序言:MySQL与Navicat安装Tips
一.数据库相关的基础知识 1.1 数据分析师主要集中在select高效查找上,纯粹的底层运维就不需要太关注: 1.2 数据库与表 类比sheet是表,整个Excel文件是一个数据库: 1.3 行与列 ...
- mysql 预处理语句_预处理语句
MySQL 8.0支持服务器端预处理语句.这种支持利用了有效的客户端/服务器二进制协议.对参数值使用带占位符的预处理语句具有以下好处:每次执行语句时解析语句的开销都较小.通常,数据库应用程序处理大量几 ...
- mysql 使用表 语句_【mysql】mysql 经常使用建表语句
[1]创建员工档案表 要求字段:员工员工编号,员工姓名,性别,工资,email,入职时间,部门. [2]合理选择数据类型及字段修饰符,要求有NOT NULL,auto_increment, prima ...
- php返回mysql错误语句_[已解决]php查询mysql返回了错误的结果
大约是不支持中文字符的原因:将mysql的所有属性都改成英文字符之后,使用mysql好了. 但是! 用mysqli写 还是会返回空(又测了下,密码框不输入或输入0都会得到登录成功的提示) 都明白了 r ...
- 360 mysql读写分离_基于360的Atlas中间件实现MySQL的读写分离
Atlas配置 下载Atlas会有两个版本,其中有个分表的版本,但是这个需要其他的依赖,我这边不需要分表这种需求,所以安装普通的版本 首先进入Linux的Home目录下,下载非分表的安装包 下载好了之 ...
最新文章
- 基于车体约束的INS辅助定位
- linux 内核参数 杨,Linux 内核参数
- Pwn环境配置(三)——ubuntu环境搭建
- mlflow_使用MLflow跟踪进行超参数调整
- Java的子类可以继承父类的私有变量和私有方法吗?
- linux文件存储管理,深入探讨Linux文件系统管理小结
- 为什么 Web 前端开发不抛弃 HTML 和 CSS,用纯 JavaScript 开发?
- python数据结构剑指offer-替换空格
- opencv 实现图像时钟
- bootstrap 模态框modal
- java删除文件夹的方法
- 粒子群课设,粒子群算法(基础精讲)ppt课件
- python解二元方程组_Python 解线性方程组
- PSP自制程序打包ISO方法及注意事项
- ABB机器人模块加密软件,代模块加密,加密之后别人就看不见你 写的程序,也无法打开,但是可以正常运行
- 38岁女儿不恋爱没有稳定工作老母亲愁哭
- 百度细雨算法2.0正式上线
- VS2017初学者如何打开右侧的解决方案资源管理器
- hpux oracle INS-06006 PRVF-7546
- 【ubuntu20.04】安装百度输入法和搜狗输入法之后,有登陆界面,登陆之后黑屏,只有鼠标可以移动,点击无效,长时间等待提示“连接失败,请注销后重试”
热门文章
- php生成随机不重复的数字_PHP生成不重复随机数的几种方法
- java script 环境搭建_TypeScript环境搭建
- linux 串口 字符 间隔,嵌入式linux编程过成中模块从串口读数需要特定的字符段并且需要每两位字符数组元素转换成一个16进制数(提取特定字符串+字符串转16进制)...
- python安装与使用Ta-Lib,获取金融技术面特征
- pandas聚合dataframe某一列的值中的所有元素
- wpf 图片绝对路径引用_Python Pillow 图片处理
- linux内核启用64位除法,关于内核中的乘法和除法。
- c# npoi 公式不计算_建筑行业计算公式大全,钢筋重量计算公式,不收藏吃亏的是你自己...
- html图片滚动浏览,ul结合CSS制作网页相册滑动浏览效果
- WPF TreeView 相关技巧