finecms 最新版v2.3.3前台getshell

基本字段

漏洞编号:
SSV-94793
披露/发现时间:
2014-07-05
提交时间:
2014-07-05
漏洞等级:
漏洞类别:
其他类型
影响组件:
FineCMS
漏洞作者:
phith0n
提交者:
Knownsec
CVE-ID:
补充
CNNVD-ID:
补充
CNVD-ID:
补充
ZoomEye Dork:
补充

来源

漏洞详情

贡献者 Knownsec 共获得  0KB

简要描述:

不指望厂商确认,我就是要打脸。官方认为自己已经修复的很干净了,在我看来还是一点用处都没有。wooyun官方能不能给我都补个rank,毕竟找了好几个getshell了。 'DR_NAME' => '海豚大众版', 'DR_UPDATE' => '2014.6.21', 'DR_VERSION' => '2.3.3', 'DR_VERSION_ID' => 20

详细说明:

还是头像上传的地方,官方认为自己已经修复的很干净了,在我看来还是一点用处都没有。 不过demo站直接把头像上传的功能给阉割了,正常头像都没法上传了,所以我就不在demo上测试了,下载最新的v2.3.3,本地测试。 版本号:

02.jpg

看到头像上传的代码:

public function upload() {
    if (!isset($GLOBALS['HTTP_RAW_POST_DATA'])) {
        exit('环境不支持');
    }
    // 创建图片存储文件夹
    $dir = FCPATH.'member/uploadfile/member/'.$this->uid.'/';
    if (!file_exists($dir)) {
        mkdir($dir, 0777, true);
    }
    // 创建图片存储的临时文件夹
    $temp = FCPATH.'cache/attach/'.md5(uniqid().rand(0, 9999)).'/';
    if (!file_exists($temp)) {
        mkdir($temp, 0777);
    }
    $filename = $temp.'avatar.zip'; // 存储flashpost图片
    file_put_contents($filename, $GLOBALS['HTTP_RAW_POST_DATA']);

    // 解压缩文件
    $this->load->library('Pclzip');
    $this->pclzip->PclFile($filename);
    if ($this->pclzip->extract(PCLZIP_OPT_PATH, $temp, PCLZIP_OPT_REPLACE_NEWER) == 0) {
        @dr_dir_delete($temp);
        exit($this->pclzip->zip(true));
    }
    @unlink($filename);

    // 限制文件名称
    $avatararr = array('45x45.jpg', '90x90.jpg', '180x180.jpg');

    // 删除多余目录
    $files = glob($temp.'*');
    foreach($files as $_files) {
        if (is_dir($_files)) {
            dr_dir_delete($_files);
        }
        if (!in_array(basename($_files), $avatararr)) {
            @unlink($_files);
        }
    }

    // 判断文件安全,删除压缩包和非jpg图片
    if($handle = opendir($temp)) {
        while (false !== ($file = readdir($handle))) {
            if ($file !== '.' && $file !== '..') {
                if (!in_array($file, $avatararr)) {
                    @unlink($temp.$file);
                } else {
                    $info = @getimagesize($temp.$file);
                    if (!$info || $info[2] !=2) {
                        @unlink($temp.$file);
                    } else {
                        copy($temp.$file, $dir.$file);
                        @unlink($temp.$file);
                    }
                }
            }
        }
        closedir($handle);    
    }
    @rmdir($temp);

我曾经用的一个方法是,构造一个部分出错的压缩包,在解压时出现错误,导致exit,但已有部分文件已解压成功,这样就能不被后面的unlink删除。另一个方法是竞争型,再php没来得及删除我们解压出来的文件时,先访问它,让它生成一个shell。 我们看finecms里是怎么修复的: 1.用一个随机目录来保存图片,这样就算我成功解压出来,猜不到目录名也访问不了,也无法产生竞争:

$temp = FCPATH.'cache/attach/'.md5(uniqid().rand(0, 9999)).'/';

2.删除以后再exit出去,这样就算出错,也会删除残留的文件后再退出:

if ($this->pclzip->extract(PCLZIP_OPT_PATH, $temp, PCLZIP_OPT_REPLACE_NEWER) == 0) {
    @dr_dir_delete($temp);
    exit($this->pclzip->zip(true));
}

看似已经万无一失。 但finecms没想到的是,我们可以构造一个“特别”的压缩包,这个压缩包里我的shell的文件名是“../../../shell.php”,这时我们就能够把shell直接解压到根目录下,我不用猜测目录名,不用惧怕被删除,直接拿下shell。 那么,请看我怎么构造这个压缩包。

漏洞证明:

先把自己的shell改名字成aaaaaaaaaaaaaaaaaaaa.php 之所以起这个名字,就是预留一些空间,方便我之后将文件名改成../../../aaaaaaaaaaa.php而不用怕字符串长度不对。 把文件直接打包成zip,用notepad++打开:

03.jpg

将我画框的俩文件名的前9个字符改成../../../

04.jpg

然后就大功告成。 注册用户,来到头像上传处,上传头像:

01.jpg

抓包将刚才构造的压缩包贴进去:

05.jpg

然后,网站根目录下就会有你的shell了:aaaaaaaaaaa.php

06.jpg

共 0  兑换了

PoC

暂无 PoC

参考链接

解决方案

临时解决方案

暂无临时解决方案

官方解决方案

暂无官方解决方案

防护方案

暂无防护方案

人气 925
评论前需绑定手机 现在绑定

暂无评论

※本站提供的任何内容、代码与服务仅供学习,请勿用于非法用途,否则后果自负