安全矩阵

 找回密码
 立即注册
搜索
查看: 6233|回复: 0

一段困扰许久的防注入代码

[复制链接]

991

主题

1063

帖子

4315

积分

论坛元老

Rank: 8Rank: 8

积分
4315
发表于 2020-12-18 17:09:41 | 显示全部楼层 |阅读模式
原文链接:一段困扰许久的防注入代码

有段时间一直热衷于研究各种waf绕过,一般来说,云WAF可以通过找到网站真实IP来绕过,硬件waf也常因为HTTP协议解析差异导致绕过,但是,代码层的防护往往只能从代码逻辑里寻找绕过思路。
在一些网站通常会在公用文件引入全局防护代码,因此,我收集了网络上常见的PHP全局防护代码进行分析。第一次看到safe3的防注入代码,花了不少时间去研究如何绕过,我在笔记里记下了一句话:如果正面怼正则,实在想不到绕过的方式。
直到前几天,我在T00LS论坛里看到有人也问起了同一段防注入代码的绕过方式,在这个帖子的回复了看到了一个绕过姿势。这也正是安全社区最大的魅力,你总会在别人的回复里找到很有意思的思路或技巧。

绕过思路
利用preg_match函数正则匹配的字符串长度限制绕过,PHP5.3之前preg_match函数阈值默认为10w,PHP5.3开始默认值为100w。
测试情况
(1)safe3 防注入代码
  1. <?php
  2. //Code By Safe3
  3. ini_set('date.timezone','Asia/Shanghai');
  4. function customError($errno, $errstr, $errfile, $errline)
  5. {
  6.     echo "<b>Error number:</b> [$errno],error on line $errline in $errfile<br />";
  7.     die();
  8. }
  9. set_error_handler("customError",E_ERROR);
  10. $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)";
  11. $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)";
  12. $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)";
  13. function StopAttack($StrFiltKey,$StrFiltValue,$ArrFiltReq){

  14.     if(is_array($StrFiltValue))
  15.     {
  16.         $StrFiltValue=implode($StrFiltValue);
  17.     }
  18.     if (preg_match("/".$ArrFiltReq."/is",$StrFiltValue)==1){
  19.         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);
  20.         @header("http/1.1 404 not found");
  21.         print "<html><title>404: Not Found</title>";
  22.         //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);
  23.         print "<body>Url里含有非法字符串,属于有误操作!... <a href='/'>您还可以返回首页</a></body></html>";
  24.   ;exit();
  25.     }
  26. }
  27. //$ArrPGC=array_merge($_GET,$_POST,$_COOKIE);
  28. foreach($_GET as $key=>$value){
  29.     StopAttack($key,$value,$getfilter);
  30. }
  31. foreach($_POST as $key=>$value){
  32.     StopAttack($key,$value,$postfilter);
  33. }
  34. foreach($_COOKIE as $key=>$value){
  35.     StopAttack($key,$value,$cookiefilter);
  36. }
  37. function slog($logs)
  38. {
  39.     $toppath=$_SERVER["DOCUMENT_ROOT"]."/log.htm";
  40.     $Ts=fopen($toppath,"a+");
  41.     fputs($Ts,$logs."\r\n");
  42.     fclose($Ts);
  43. }
  44. ?>
复制代码

(2)构建一个sql注入点
在页面中引入防注入代码:
  1. require_once('360_safe3.php');
复制代码

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


(3)绕过姿势
PHP测试版本:5.2.17
当填充字符串超过10w的时候,可以绕过防注入代码,获取数据库信息。

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

参考文章:
https://www.t00ls.net/viewthread.php?tid=58865
















回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|安全矩阵

GMT+8, 2024-11-28 13:41 , Processed in 0.014683 second(s), 18 queries .

Powered by Discuz! X4.0

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表