首页 > 漏洞预警和分析 > 蝉知getshell

蝉知getshell

[2018.01.19]

每个漏洞自然是少不了故事情节,这个漏洞是源于90以及小密圈出来的。首先是90乐清小俊杰发了一篇蝉知的注入然后紧接着小密圈一个不认识的大师傅也发了一篇关于蝉知的pdf审计总结文于是我也准备来一发

漏洞文件:

/system/module/file/model.php

public function pasteImage($data, $uid)

    {


        $data = str_replace('"', '"', $data);


        if(!$this->checkSavePath()) return false;

        ini_set('pcre.backtrack_limit', strlen($data));

        preg_match_all('//U', $data, $out);

        foreach($out[3] as $key => $base64Image)

        {

            $imageData = base64_decode($base64Image);

            $imageSize = array('width' => 0, 'height' => 0);

            $file['id']        = $key;

            $file['extension'] = $out[2][$key];

            $file['size']      = strlen($imageData);

            $file['addedBy']   = $this->app->user->account;

            $file['addedDate'] = helper::today();

            $file['title']     = basename($file['pathname']);

            $file['pathname']  = $this->setPathName($file);

            $file['editor']    = 1;

            file_put_contents($this->savePath . $file['pathname'], $imageData);

            $this->compressImage($this->savePath . $file['pathname']);


            $imageSize      = $this->getImageSize($this->savePath . $file['pathname']);

            $file['width']  = $imageSize['width'];

            $file['height'] = $imageSize['height'];

            $file['lang']   = 'all';


            $this->dao->insert(TABLE_FILE)->data($file)->exec();

            $_SESSION['album'][$uid][] = $this->dao->lastInsertID();


            $data = str_replace($out[1][$key], $this->webPath . $file['pathname'], $data);

        }


      return $data;

    }

主要观察的地方是file_put这里,我们看看哪里可控。$imageData是由穿入的内容经过正则匹配然后遍历经过base64解码出来的内容。

$this->savePath . $file['pathname']

$this->savePath 不可控,$file['pathname']目前不知道


先看看这个函数从哪里调用过来的


关联文件:/system/module/file/control.php


public function ajaxPasteImage($uid)

    {

        if($_POST)

        {

            echo $this->file->pasteImage($this->post->editor, $uid);

        }

}



Uid就不多说了,首先肯定是当post请求的时候才能够进入我们发现隐患的函数,这个不困难

data是由editor参数传入的,uid不确定是否能够控制但目前的条件来说无关紧要,继续回到原来的地方

foreach($out[3] as $key => $base64Image)

        {

            $imageData = base64_decode($base64Image);

            $imageSize = array('width' => 0, 'height' => 0);

            $file['id']        = $key;

            $file['extension'] = $out[2][$key];

            $file['size']      = strlen($imageData);

            $file['addedBy']   = $this->app->user->account;

            $file['addedDate'] = helper::today();

            $file['title']     = basename($file['pathname']);

            $file['pathname']  = $this->setPathName($file);

            $file['editor']    = 1;

Data既然是可控的,那么自然out[3]也是可控内容,这里的      $file['extension'] = $out[2][$key];是赋值后缀,$key可控的。但这里重点关注的是file['pathname']  = $this->setPathName($file);我们唯一不能控值的pathname是从这里赋出来的,先跟入函数看看

   public function setPathName($file, $objectType = 'upload')

    {

        if(strpos('slide,source,themePackage', $objectType) === false)

        {

            $sessionID  = session_id();

            $randString = substr($sessionID, mt_rand(0, strlen($sessionID) - 5), 3);

            $pathName   = date('Ym/dHis', $this->now) . $file['id'] . mt_rand(0, 10000) . $randString;

        }

        elseif($objectType == 'source')

        {

            /* Process file path if objectType is source. */

            $template = $this->config->template->{$this->app->clientDevice}->name;

            $theme    = $this->config->template->{$this->app->clientDevice}->theme;

            return "source/{$template}/{$theme}/{$file['title']}.{$file['extension']}";

        }

        elseif($objectType == 'themePackage')

        {

            return "{$file['title']}.{$file['extension']}";

        }


        /* rand file name more */

        list($path, $fileName) = explode('/', $pathName);

        $fileName = md5(mt_rand(0, 10000) . str_shuffle(md5($fileName)) . mt_rand(0, 10000));

        return $path . '/f_' . $fileName . '.' . $file['extension'];

    }



前面的if都是不具备条件的自然是执行最后的操作,但这里看见没$file['extension']是后缀,是我们可以控制的,那么就是可以getshell了。。。。




本地复现下试试:


 

确定可以执行


北京通和实益电信科学技术研究所有限公司 版权所有 京ICP备15030238号-1