在一些网站常日会在公用文件引入全局防护代码,因此,我网络了网络上常见的PHP全局防护代码进行剖析。第一次看到safe3的防注入代码,花了不少韶光去研究如何绕过,我在条记里记下了一句话:如果正面怼正则,实在想不到绕过的办法。
直到前几天,我在T00LS论坛里看到有人也问起了同一段防注入代码的绕过办法,在这个帖子的回答了看到了一个绕过姿势。这也正是安全社区最大的魅力,你总会在别人的回答里找到很故意思的思路或技巧。
绕过思路

利用preg_match函数正则匹配的字符串长度限定绕过,PHP5.3之前preg_match函数阈值默认为10w,PHP5.3开始默认值为100w。
测试情形
safe3 防注入代码
//Code By Safe3 ini_set('date.timezone','Asia/Shanghai'); function customError($errno, $errstr, $errfile, $errline) { echo "Error number: [$errno],error on line $errline in $errfile"; die(); } set_error_handler("customError",E_ERROR); $getfilter="'|select|from|(and|or)\\b.+?(>|<|=|in|like)|\\/\\.+?\\\\/|<\\sscript\\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)|\\/\\.+?\\\\/|<\\sscript\\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)|\\/\\.+?\\\\/|<\\sscript\\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("操作IP: ".$_SERVER["REMOTE_ADDR"]."操作韶光: ".strftime("%Y-%m-%d %H:%M:%S")."操作页面:".$_SERVER["PHP_SELF"]."提交办法: ".$_SERVER["REQUEST_METHOD"]."提交参数: ".$StrFiltKey."提交数据: ".$StrFiltValue); @header("http/1.1 404 not found"); print ""; //slog("操作IP: ".$_SERVER["REMOTE_ADDR"]."操作韶光: ".strftime("%Y-%m-%d %H:%M:%S")."操作页面:".$_SERVER["PHP_SELF"]."提交办法: ".$_SERVER["REQUEST_METHOD"]."提交参数: ".$StrFiltKey."提交数据: ".$StrFiltValue); print "Url里含有造孽字符串,属于有误操作!... 您还可以返回顾页"; ;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."\r\n"); fclose($Ts); }
构建一个sql注入点
在页面中引入防注入代码:
require_once('360_safe3.php');
当参数中拼接sql语句时,触发关键字正则匹配导致拦截
绕过姿势
PHP测试版本:5.2.17
当添补字符串超过10w的时候,可以绕过防注入代码,获取数据库信息。
当添补字符串超过100w的时候,可以绕过防注入代码,获取数据库信息。
https://www.linuxprobe.com/code-insert.html