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

安全 网站安全
第一次看到safe3的防注入代码,花了不少时间去研究如何绕过,我在笔记里记下了一句话:如果正面怼正则,实在想不到绕过的方式。

本文转载自微信公众号「Bypass」,作者Bypass。转载本文请联系Bypass公众号。

有段时间一直热衷于研究各种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."\r\n"); 
    fclose($Ts); 

?> 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.

(2) 构建一个sql注入点

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

require_once('360_safe3.php'); 
  • 1.

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

 

(3) 绕过姿势

PHP测试版本:5.2.17

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

PHP测试版本:5.3.29

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

 

责任编辑:赵宁宁 来源: Bypass
相关推荐

2010-09-14 19:50:55

2022-06-21 12:27:12

JavaScript前端

2014-07-08 09:21:10

死代码创意歌曲

2018-06-19 08:02:00

统计程序微信

2018-11-02 16:16:41

程序硬盘存储

2021-02-04 07:55:28

代码离职互联网

2018-06-23 08:02:31

程序员代码故事

2015-03-27 11:34:59

JavaJava编写引发内存泄露

2020-04-03 10:14:57

内存蠕虫代码web安全

2021-10-28 19:35:02

代码main方法

2020-10-26 10:11:45

Jupyter Not早起Python开发

2020-02-07 08:00:29

代码Java8Bug

2020-11-24 06:17:57

微信代码移动应用

2020-12-16 07:42:03

JS基础代码

2021-07-26 23:39:20

Java变量代码

2019-06-19 10:57:48

新人入职代码

2022-09-09 09:33:14

支付宝代码性能

2014-03-21 09:58:08

比特币

2020-05-29 08:14:49

代码Try-Catch程序员

2014-09-09 14:47:20

点赞
收藏

51CTO技术栈公众号