WooYun-2014-70353:qibocms多个系统绕过补丁继续注入2

漏洞作者: ′雨。认证白帽子

来源:http://www.wooyun.org/bugs/wooyun-2014-070353

简要描述

之前发了补丁被绕过了, 现在又发布了补丁。 今天上午的时候看了看补丁。 第一眼觉得很牛逼。 然后觉得这补丁很吊,就放下了。 下午的时候又继续看了看补丁 原来还是可以绕过。

依旧是通杀多个系统。

由于是通用的函数, 所以能造成注入的点不止一处。

用v7整站系统 再随便找一个点来说就行啦。

详细说明

再来看看一下 qibocms的全局过滤函数

$_POST=Add_S($_POST);

$_GET=Add_S($_GET);

$_COOKIE=Add_S($_COOKIE);
function Add_S($array){

    foreach($array as $key=>$value){

        if(!is_array($value)){

            @eregi("['\\\"&]+",$key) && die('ERROR KEY!');

            $value=str_replace("&#x","& # x",$value);    //过滤一些不安全字符

            $value=preg_replace("/eval/i","eva l",$value);    //过滤不安全函数

            !get_magic_quotes_gpc() && $value=addslashes($value);

            $array[$key]=$value;

        }else{

            $array[$key]=Add_S($array[$key]); 

        }

    }

    return $array;

}

这里把数组中的value addslashes 转义了

但是没有对key addslashes (这里应该也不能做addslashes 因为会像上次那样绕过)

可以看到是把过滤key的代码换了 之前是replace 可以绕过

现在是 @eregi("['\\"&]+",$key) && die('ERROR KEY!');

我擦, 看起来很叼的样子。 匹配到' 或者 " 或者\ 就直接退出。

当我第一眼看到的时候 觉得很叼 就放下了qibo。 睡觉去了。


到了下午 精神倍棒

依旧 我们自己来写一个文件测试一下

再调用一下qibo的这函数

<?php  

$_GET=Add_S($_GET[a]);

function Add_S($array){

    foreach($array as $key=>$value){

        if(!is_array($value)){

            @eregi("['\\\"&]+",$key) && die('ERROR KEY!');

            $value=str_replace("&#x","& # x",$value);    //过滤一些不安全字符

            $value=preg_replace("/eval/i","eva l",$value);    //过滤不安全函数

            !get_magic_quotes_gpc() && $value=addslashes($value);

            $array[$key]=$value;

        }else{

            $array[$key]=Add_S($array[$key]); 

        }

    }

    return $array;

}

碉堡 key中的单引号被匹配到了 被退出了

但是换一种方式呢 这里我输出一下$key

可以看到提交.../yu.php?a[a'][asd]=a 的时候 那么进入过滤函数的时候的key是asd

那么就不会被匹配到 就不会被过滤了。

那么我们不就是绕过了这个过滤了?


绕过了这个随便找个点来说

在member/post.php中

elseif($job=='manage')

{

    if(!$atc_power)showerr("你没权限");

    if($rsdb[pages]<2){

        header("location:post.php?job=edit&aid=$aid&mid=$mid&only=$only");exit;

    }

    $erp=get_id_table($aid);

    if($step==2){

        asort($orderDB);

        $i=0;

        foreach( $orderDB AS $key=>$value){

            $i++;

            $db->query("UPDATE {$pre}reply$erp SET orderid=$i WHERE aid='$aid' AND rid='$key'");

        }

        refreshto("$FROMURL","排序成功",1);

    }

foreach 出来的key没有过滤 直接带入到了查询当中

直接提交key被匹配出 像刚才那样绕过一下

这样进行检测的key 是asd 但是 带入查询的 而是那段含单引号的key。

造成了注入。

漏洞证明

修复方案

这个我真心也不知道怎么过滤了。。

还是看你们把。