zoukankan      html  css  js  c++  java
  • 一段困扰许久的防注入代码

    有段时间一直热衷于研究各种waf绕过,一般来说,云WAF可以通过找到网站真实IP来绕过,硬件waf也常因为HTTP协议解析差异导致绕过,但是,代码层的防护往往只能从代码逻辑里寻找绕过思路。

    在一些网站通常会在公用文件引入全局防护代码,因此,我收集了网络上常见的PHP全局防护代码进行分析。第一次看到safe3的防注入代码,花了不少时间去研究如何绕过,我在笔记里记下了一句话:如果正面怼正则,实在想不到绕过的方式。

    直到前几天,我在T00LS论坛里看到有人也问起了同一段防注入代码的绕过方式,在这个帖子的回复了看到了一个绕过姿势。这也正是安全社区最大的魅力,你总会在别人的回复里找到很有意思的思路或技巧。


    绕过思路

    利用preg_match函数正则匹配的字符串长度限制绕过,PHP5.3之前preg_match函数阈值默认为10w,PHP5.3开始默认值为100w。

    测试情况

    (1)safe3 防注入代码

    <?php
    //Code By Safe3 
    ini_set('date.timezone','Asia/Shanghai');
    function customError($errno, $errstr, $errfile, $errline)
    {
        echo "<b>Error number:</b> [$errno],error on line $errline in $errfile<br />";
        die();
    }
    set_error_handler("customError",E_ERROR);
    $getfilter="'|select|from|(and|or)\b.+?(>|<|=|in|like)|\/\*.+?\*\/|<\s*script\b|\bEXEC\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\s+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\s+(TABLE|DATABASE)";
    $postfilter="\b(and|or)\b.{1,6}?(=|>|<|\bin\b|\blike\b)|\/\*.+?\*\/|<\s*script\b|\bEXEC\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\s+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\s+(TABLE|DATABASE)";
    $cookiefilter="\b(and|or)\b.{1,6}?(=|>|<|\bin\b|\blike\b)|\/\*.+?\*\/|<\s*script\b|\bEXEC\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\s+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\s+(TABLE|DATABASE)";
    function StopAttack($StrFiltKey,$StrFiltValue,$ArrFiltReq){
    
        if(is_array($StrFiltValue))
        {
            $StrFiltValue=implode($StrFiltValue);
        }
        if (preg_match("/".$ArrFiltReq."/is",$StrFiltValue)==1){
            slog("<br><br>操作IP: ".$_SERVER["REMOTE_ADDR"]."<br>操作时间: ".strftime("%Y-%m-%d %H:%M:%S")."<br>操作页面:".$_SERVER["PHP_SELF"]."<br>提交方式: ".$_SERVER["REQUEST_METHOD"]."<br>提交参数: ".$StrFiltKey."<br>提交数据: ".$StrFiltValue);
            @header("http/1.1 404 not found"); 
            print "<html><title>404: Not Found</title>";
            //slog("<br><br>操作IP: ".$_SERVER["REMOTE_ADDR"]."<br>操作时间: ".strftime("%Y-%m-%d %H:%M:%S")."<br>操作页面:".$_SERVER["PHP_SELF"]."<br>提交方式: ".$_SERVER["REQUEST_METHOD"]."<br>提交参数: ".$StrFiltKey."<br>提交数据: ".$StrFiltValue);
            print "<body>Url里含有非法字符串,属于有误操作!... <a href='/'>您还可以返回首页</a></body></html>";
      ;exit();
        }
    }
    //$ArrPGC=array_merge($_GET,$_POST,$_COOKIE);
    foreach($_GET as $key=>$value){
        StopAttack($key,$value,$getfilter);
    }
    foreach($_POST as $key=>$value){
        StopAttack($key,$value,$postfilter);
    }
    foreach($_COOKIE as $key=>$value){
        StopAttack($key,$value,$cookiefilter);
    }
    function slog($logs)
    {
        $toppath=$_SERVER["DOCUMENT_ROOT"]."/log.htm";
        $Ts=fopen($toppath,"a+");
        fputs($Ts,$logs."
    ");
        fclose($Ts);
    }
    ?>

    (2)构建一个sql注入点

    在页面中引入防注入代码:

    require_once('360_safe3.php');

    当参数中拼接sql语句时,触发关键字正则匹配导致拦截。

    (3)绕过姿势

    PHP测试版本:5.2.17

    当填充字符串超过10w的时候,可以绕过防注入代码,获取数据库信息。

    PHP测试版本:5.3.29

    当填充字符串超过100w的时候,可以绕过防注入代码,获取数据库信息。

  • 相关阅读:
    python内置函数
    conda和anaconda的区别
    闭包,装饰器,property
    【模板】大数乘法(51nod 1027)
    51nod 1791 合法括号子段
    51nod 1419 最小公倍数挑战
    51nod 1241 特殊的排序
    51nod 1090 3个数和为0
    【模板】51nod 1051 最大子矩阵和
    51nod 1267 4个数和为0
  • 原文地址:https://www.cnblogs.com/xiaozi/p/14263969.html
Copyright © 2011-2022 走看看