欢迎来到云服务器

网络技术

preg_replace的e修饰符与PHP安详

PHP以其易用性和可移植性正被遍及应用于WEB开拓。然而,在我们利用的进程中,,也要十分小心,从到处可见的XSS(新浪微博发送大量垃圾信息事件)到前段时间爆出来的Hash斗嘴的DDOS进攻,最近,wooyun上面宣布了一个关于ThinkPHP框架的裂痕(最新版已经修复),以前也是我用过的第一个框架,昨晚花时间重现了一下,查阅了下措施的道理。本文主要来重现该裂痕,然后阐明代码,给出裂痕的原因,用这个裂痕去检讨大概对系统造成的粉碎,最后总结,防御的要领。

裂痕主要是由mixed preg_replace ( mixed pattern, mixed replacement, mixed subject [, int limit]) 这个函数引起的,我们先看官方说明:

/e 修 正符使 preg_replace() 将 replacement 参数看成 PHP 代码(在适当的逆向引用替换完之后)。提示:要确保 replacement 组成一个正当的 PHP 代码字符串,不然 PHP 会在陈诉在包括 preg_replace() 的行中呈现语法理会错 误。

我们不妨先看一下这个示例

preg_replace("/test/e",$_GET["h"],"jutst test");

假如我们提交?h=phpinfo(),phpinfo()将会被执行(利用/e修饰符,preg_replace会将 replacement 参数看成 PHP 代码执行)。这个正则被正确的匹配到,在举办替换的进程中,需要将$_GET["h"]传入的String看成函数来运行,因此phpinfo()被乐成执行。

<?php
preg_replace("/test/e",$_GET["h"],"jutst test");
?>

会见的url : ?h=phpinfo()

进而,我们进入ThinkPHP的源码,下载2.1版(2.1今后已经被修复)。在/ThinikPHP/Lib/ThinkPHP/Util/Dispatcher.class.php的dispatch函数中,找到这句话:preg_replace的e修饰符与PHP安详

在ThinkPHP的路由成果中,许多处所用到了preg_replace函数的/e参数,然而最严重的是这个文件中的这句话,因为险些影响了所有利用Thinkphp的项目。

显然,这个利用了/e函数,会导致第二个参数看成函数利用。我们来阐明一下这句话:

正则匹配的是 :字母开头,加上“/”脱离符,后头跟一个非”/”的元素,被替换成$var["脱离符前的字母"]=脱离符后的值;作者的本意是要将这么一对一对的参数/值的形式的url写入到 $var[$key] = $value的数组中。

譬喻:URL,index.php?s=/model/action/par1/value1

将被理会成 :model模块的action要领,参数的处理惩罚放在这句话中,$deprde的值是“/”,由于/par1/value1(剩余的URL参数)匹配到了正则表达式,则会用第二个参数去举办替换。那么第二个参数应该被看成一个php语句来执行,他是一个赋值语句,执行的功效为:$var["par1"] = “value1″,作者以此来到达阐明url的目标,也实现了ThinkPHP的C层。

可是在赋值的时候,利用的是双引号。危险的处所实际上在这里,在 php中,双引号内里假如包括有变量,php表明器会将其替换为变量表明后的功效;单引号中的变量不会被处理惩罚。可以先做如下测试:

$a = “{${phpinfo()}}”;   phpinfo会被乐成执行。因此,我们将第二个变量替换成我们需要的函数,结构出来的进攻url大抵如下:

http:[email protected](THINK_VERSION)}

我们利用ThinkPHP2.1_full_with_extend ,利用examlpe内里的Blog示例,快速搭建一个Thinkphp项目,然后会见http:[email protected](THINK_VERSION)},可以在左上角打印出当前的TP版本,操作这个来执行php函数,相当于开启了一个PHP的一句话后门。

详细阐明是:这句话的/par [email protected](THINK_VERSION)}将匹配到正则表达式,将会执行第二个参数,详细语句是$var['par'] = “[email protected](THINK_VERSION)} “; 问题出在双引号上面,这个会执行内里的语句,包括许多危险的语句,包括phpinfo(),读取数据库设置等等。

preg_replace的e修饰符与PHP安详

停止今朝,在Google上还可以找到很多这样的站点,许多站点都可以直接执行phpinfo(),在新版的ThinkPHP中已经修复了这个裂痕,将第二个参数的双引号改为单引号:


'$var['']='';'

在我们今后利用preg_replace的/e修饰符的时候,需要留意这个双引号和单引号,像框架类的裂痕,一般影响的范畴都很是的广。

腾讯云代理

Copyright © 2003-2021 MFISP.COM. 国外vps服务器租用 梦飞云服务器租用 版权所有 粤ICP备11019662号