WooYun-2014-69746:qibocms V7 整站系统最新版SQL注入一枚 & 另外一处能引入转义符的地方。

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

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

简要描述

好久没看过qibo的了。 高三累成狗, 补课生活终于快要结束了。

详细说明

首先来看一下全局文件

$_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)){

            $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。

在member/post.php中

if($lfjid)

{

    if($web_admin||$lfjuid==$rsdb[uid]){

        $atc_power=1;

    }

}

这里判断了一下权限 如果是管理员的话就让这变量为1 当然我们是注册不到管理员的

看后面的 如果你的id 是和这个发布文章的id是一样的 那么这个变量也会成1

也是有权限的 所以。。

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'");

        }

这里$orderDB 结合 qibo的伪全局可以直接控制

然后把数组中的key直接带入到了查询当中 结合上面说的 数组中的key不会被转义

所以造成了注入。


0x02 能引入转义符的地方。

/inc/artic_function.php中

/*修改软件*/

function post_edit(){

    global $db,$_pre,$postdb,$fid,$fidDB,$Fid_db,$lfjuid,$rsdb,$lfjdb,$webdb,$timestamp,$aid,$FROMURL,$groupdb,$web_admin,$fu_fiddb;

    if( $rsdb[levels]&&$postdb[levels] )

    {

        $postdb[levels]=$rsdb[levels];    //处理其他级别2,3,4...以防出错

    }

    if($postdb[top])

省略一点

if($rsdb[keywords]!=$postdb[keywords]){

        keyword_del($aid,$rsdb[keywords]);

        keyword_add($aid,$postdb[keywords],$lfjdb[uid]);

    }
function keyword_del($aid,$keyword){

    global $db,$_pre;

    if(!$keyword){

        return ;

    }

    $detail2=explode(" ",$keyword);

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

        if($value){

            $db->query("UPDATE `{$_pre}keyword` SET num=num-1 WHERE `keywords`='$value'");

            $_rs=$db->get_one("SELECT * FROM `{$_pre}keyword` WHERE `keywords`='$value'");

            $id=$_rs[id];

            $db->query("DELETE FROM `{$_pre}keywordid` WHERE `id`='$id' AND aid='$aid'");        

        }

    }

}

keyword_del($aid,$rsdb[keywords]);

这里进入查询的时候是用的是出库来的 所以能引入转义符。

漏洞证明

首先注册一个会员

然后选择一个栏目投稿。

发布成功后 因为这里判断了

if($rsdb[pages]<2){

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

就是说页数不能只有一页 所以我们得点 [续发本主题] 再增加一页。

两页了。

然后这里可以直接看到id为668.

修改key为注入语句 成功注入。


0x02 引入转义符

首先注册一个会员 然后发布一个文章 这样写

关键字这样写 发完后 然后编辑一下

引入了转义符 成功报错了。

修复方案

转义一下。

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

            $i++;

                        $key=addslashes($key);

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

        }

第二个

$keyword=addslashes($keyword);