某cms后台文件上传

写在前面

上网中无意碰到一个cms,故从官网上拉了源码,本地看了一个下午,发现个上传,cnvd没有相关记载,就提交了。

应用

后台的上传,实践没太大作用,全当锻炼一下看代码才能。。。。。先说怎样应用吧:

后台存在\application\admin\controller\Weapp.php 控制器

但是后台管理界面未找到对应功用点,于是经过抓包访问:

修正标红局部:

抵达插件上传界面:

然后上传插件weapp.zip(文件名就叫weapp)
其内部格式如下:

其中.htaccess 文件内容为空;
ssss.php 为shell 文件;
config.php 的文件内容需求和\data\weapp\Sample\weapp\Sample\config.php 中的内容格式坚持分歧,其中键不变,值能够修正;
例如:

然后上传,上传后会显现插件不存在,但是网站根目录下的weapp文件中曾经保管了上传的文件:

访问ssss.php getshell

剖析

总体来说不难,就是绕来绕去。。。
首先这个插件上传功用点就找了很久没找到,由于主要还是黑盒为主测试,后来还是看源码的发现有这么个东西。
路由什么的就不说了,根本上就那样,admin下面Weapp.php中存在upload办法:

这个上传并解压看上去就很有搞头

public function upload() 
    {
        //避免php超时
        function_exists('set_time_limit') && set_time_limit(0);

        if (IS_AJAX_POST) {

            $admin_info = session('admin_info');

            /*只限于开创人装置*/
            if (empty($admin_info) || -1 != $admin_info['role_id']) {
                $this->error('没有装置权限!');
            }
            /*--end*/

            if (empty($admin_info['weapp_info']['firstInstallpwd'])) {
                $pwd = input('post.pwd/s');
                $installpwd = func_encrypt($pwd);
                if (empty($installpwd)) {
                    $this->error('请录入插件装置密码!');
                } else {
                    $weapp_installpwd = tpCache('weapp.weapp_installpwd');
                    if ($weapp_installpwd != $installpwd) {
                        $this->error('插件装置密码不正确!');
                    }
                }
                $admin_info['weapp_info']['firstInstallpwd'] = $installpwd;
                session('admin_info', $admin_info);
            }

            $fileExt = 'zip';
            $savePath = UPLOAD_PATH.'tmp'.DS;
            $image_upload_limit_size = intval(tpCache('basic.file_size') * 1024 * 1024);
            $file = request()->file('weappfile');
            if(empty($file)){
                $this->error('请先上传zip文件');
            }
            $error = $file->getError();
            if(!empty($error)){
                $this->error($error);
            }
            $result = $this->validate(
                ['file' => $file], 
                ['file'=>'fileSize:'.$image_upload_limit_size.'|fileExt:'.$fileExt],
                ['file.fileSize' => '上传文件过大','file.fileExt'=>'上传文件后缀名必需为'.$fileExt]
            );
            if (true !== $result || empty($file)) {
                $this->error($result);
            }
            // 挪动到框架应用根目录/public/upload/tmp/ 目录下
            $folderName = session('admin_id').'-'.dd2char(date("ymdHis").mt_rand(100,999));  // 文件名,不带扩展名
            $fileName = $folderName.'.'.$fileExt; // 上传之后的文件全名
            /*运用自定义的文件保管规则*/
            $info = $file->rule(function ($file) {
                return  $folderName;
            })->move($savePath, $folderName);
            /*--end*/
            if ($info) {
                $filepath = $savePath.$fileName;
                if (file_exists($filepath)) {
                    /*解压之前,删除存在的文件夹*/
                    delFile($savePath.$folderName);
                    /*--end*/

                    /*解压文件*/
                    $zip = new \ZipArchive();//新建一个ZipArchive的对象
                    if ($zip->open($savePath.$fileName) != true) {
                        $this->error("插件紧缩包读取失败!", url('Weapp/index'));
                    }
                    $zip->extractTo($savePath.$folderName.DS);//假定解紧缩到在当前途径下插件称号文件夹内
                    $zip->close();//关闭处置的zip文件
                    /*--end*/

                    /*获取插件目录称号*/
                    $dirList = glob($savePath.$folderName.DS.WEAPP_DIR_NAME.DS.'*');
                    $weappPath = !empty($dirList) ? $dirList[0] : '';
                    if (empty($weappPath)) {
                        @unlink(realpath($savePath.$fileName));
                        delFile($savePath.$folderName, true);
                        $this->error('插件紧缩包短少目录文件', url('Weapp/index'));
                    }

                    $weappPath = str_replace("\\", DS, $weappPath);
                    $weappPathArr = explode(DS, $weappPath);
                    $weappName = $weappPathArr[count($weappPathArr) - 1];
                    // if (is_dir(ROOT_PATH.WEAPP_DIR_NAME.DS.$weappName)) {
                    //     $this->error("已存在同名插件{$weappName},请手工移除".WEAPP_DIR_NAME.DS.$weappName."目录");
                    // }
                    /*--end*/

                    /*修复非法插件上传,招致恣意文件上传的破绽*/
                    $configfile = $savePath.$folderName.DS.WEAPP_DIR_NAME.DS.$weappName.'/config.php';
                    if (!file_exists($configfile)) {
                        @unlink(realpath($savePath.$fileName));
                        delFile($savePath.$folderName, true);
                        $this->error('插件不契合规范!', url('Weapp/index'));
                    } else {
                        $configdata = include($configfile);
                        if (empty($configdata) || !is_array($configdata)) {
                            @unlink(realpath($savePath.$fileName));
                            delFile($savePath.$folderName, true);
                            $this->error('插件不契合规范!', url('Weapp/index'));
                        } else {
                            $sampleConfig = include(DATA_NAME.DS.'weapp'.DS.'Sample'.DS.'weapp'.DS.'Sample'.DS.'config.php');
                            foreach ($configdata as $key => $val) {
                                if ('permission' != $key && !isset($sampleConfig[$key])) {
                                    @unlink(realpath($savePath.$fileName));
                                    delFile($savePath.$folderName, true);
                                    $this->error('插件不契合规范!', url('Weapp/index'));
                                }
                            }
                        }
                    }
                    /*--end*/

                    // 递归复制文件夹            
                    $copy_bool = recurse_copy($savePath.$folderName, rtrim(ROOT_PATH, DS));
                    if (true !== $copy_bool) {
                        $this->error($copy_bool);
                    }

                    /*删除上传的插件包*/
                    @unlink(realpath($savePath.$fileName));
                    @delFile($savePath.$folderName, true);
                    /*--end*/

                    /*装置插件*/
                    $configfile = WEAPP_DIR_NAME.DS.$weappName.'/config.php';
                    if (file_exists($configfile)) {
                        $configdata = include($configfile);
                        $code = isset($configdata['code']) ? $configdata['code'] : 'error_'.date('Ymd');
                        Db::name('weapp')->where(['code'=>$code])->delete();

                        $addData = [
                            'code'          => $code,
                            'name'          => isset($configdata['name']) ? $configdata['name'] : '配置信息不完善',
                            'config'        => empty($configdata) ? '' : json_encode($configdata),
                            'data'        => '',
                            'add_time'      => getTime(),
                        ];
                        $weapp_id = Db::name('weapp')->insertGetId($addData);
                        if (!empty($weapp_id)) {
                            $this->install($weapp_id);
                        }
                    }
                    /*--end*/
                }
            }else{
                //上传错误提示错误信息
                $this->error($info->getError());
            }
        }
    }
------本页内容已结束,喜欢请分享------

感谢您的来访,获取更多精彩文章请收藏本站。

© 版权声明
THE END
喜欢就支持一下吧
点赞8赞赏 分享
评论 共1条
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片
    • 头像出市0