zoukankan      html  css  js  c++  java
  • preg_replace 中修正符 e 的解析

    参考 http://www.jb51.net/article/38714.htm

    文档 http://cn2.php.net/manual/zh/function.preg-replace.php

    当使用被弃用的 e 修饰符时, 这个函数会转义一些字符(即:'、"、 和 NULL) 然后进行后向引用替换。当这些完成后请确保后向引用解析完后没有单引号或 双引号引起的语法错误(比如: 'strlen('$1')+strlen("$2")')。确保符合PHP的 字符串语法,并且符合eval语法。因为在完成替换后, 引擎会将结果字符串作为php代码使用eval方式进行评估并将返回值作为最终参与替换的字符串。

    下面查看一些例子

    /e 通俗一点 就是将 replacement 参数当作 PHP 代码这个就略微有点尴尬

    #html.txt
    <div>HELO</div>
    <p>ww</p>
    
    $str = file_get_contents("errors/html.txt"); 
    $rep = preg_replace ('/(</?)([^>]*)(>)/e', 
    	'"$1".strtoupper("$2")."$3"',
    	$str); 
    
    file_put_contents("errors/output_html.txt", print_r($rep,true));
    
    # 需要注意的事 replacement 就变成 	'"$1".strtoupper("$2")."$3"' 去掉最外层的单引号,里面的语句就被当成php语句

    除了上面的语句之外 需要注意的 确实会引起一漏洞 查看下面demo

    echo preg_replace("/[php](.+?)[/php]/e", '"$1"', $_GET["h"]); 
    
    运行的时候
    http://localhost:8000/regex_demo.php?h=[php]{${phpinfo()}}[/php]
    
    上面被当成php 语句的将会是 "{${phpinfo()}}"

    上面的phpinfo() 函数会直接运行

    避免上面出现的方式是

    "'$1'" 替换原来的 '"$1"'
    $1 等同于 \1  为啥有两个 是因为要被引号转义一次

    修整好的demo:

    echo preg_replace("/[php](.+?)[/php]/e", "'\1'", $_GET["h"]); 
    
    #http://localhost:8000/regex_demo.php?h=[php]${phpinfo()}[/php]
    就会看到 ${phpinfo()}
    慢慢沉淀自己
  • 相关阅读:
    plusOne
    lengthOfLastWord
    maxSubArray
    countAndSay
    学生会管理系统-后端个人总结
    基于图结构实现地铁乘坐线路查询
    地铁线路项目简要分析
    Spring Boot 路由
    Spring Boot 项目配置的使用方法
    IDEA搭建Spring Boot项目
  • 原文地址:https://www.cnblogs.com/martinding/p/7655703.html
Copyright © 2011-2022 走看看