Redian新闻
>
悟空crm漏洞新用

悟空crm漏洞新用

科技




概述

悟空软件长期为企业提供企业管理软件(CRM/HRM/OA/ERP等)的研发、实施、营销、咨询、培训、服务于一体的信息化服务。悟空软件以高科技为起点,以技术为核心、以完善的售后服务为后盾,秉承稳固与发展、求实与创新的精神,已为国内外上千家企业提供服务。

听说很厉害,搜索了下存在的旧版本漏洞,看看是否还存在这样的漏洞,旧漏洞如下:


按照已有的方向先排查一波。

安装

下载路径:
https://gitee.com/wukongcrm/crm_php
下载完包后,解压放到环境的根目录。
访问url:
www.wk.com/index.php/admin/install/index.html


点击同意,进行下一步安装。


安装完成,使用安装过程功的账号密码,登录到工作台。


sql注入

进入到管理操作区,找到项目管理,在所有请求中有一个myTask请求,


使用burpsuite抓取到改请求,发送到重放模块,接着修改构建传递的参数,第一个将url部分mytask修改成dateList,将body部分的{"search":"","sort_field":2,"completed_task":true,"owner_user_id":[],"time_type":"","label_id":[]}修改改成{"start_time":"123","stop_time":"12"} 此时点击一次go,看是否有正确相应。


接着,将请求保存到一个文本中,命名为post.txt。
接着上sqlmap跑一下这个请求包。


代码分析:

    public function dateList()
    {
        $param = $this->param;
        $taskModel = model('Task');
        $userInfo = $this->userInfo;
        $param['user_id'] = $userInfo['id'];
        $data = $taskModel->getDateList($param);
        return resultArray(['data' => $data]);
    }

此方法中的getDateList读取数据库,看方法逻辑:

public function getDateList($param)
    {
        $start_time = $param['start_time'];
        $stop_time = $param['stop_time'];
        $user_id = $param['user_id'];
        // $date_list = dateList($start_time, $stop_time, 1);
        $where = [];
        $where['ishidden'] = 0;
        $where['is_archive'] = 0;
        $where['status'] = 1;
        $where['pid'] = 0;
        $str = ',' . $user_id . ',';
        $whereStr = ' ( create_user_id = ' . $user_id . ' or ( owner_user_id like "%' . $str . '%") or ( main_user_id = ' . $user_id . ' ) )';
        $whereDate = '( stop_time > 0 and stop_time between ' . $start_time . ' and ' . $stop_time . ' ) or ( update_time between ' . $start_time . ' and ' . $stop_time . ' )';
        $list = db('task')
            ->where($where)
            ->where($whereStr)
            ->where($whereDate)
            ->field('task_id,name,priority,start_time,stop_time,priority,update_time')
            ->select();
        return $list ?: [];
    }

再此方法中接受的参数有start_time、stop_time、user_id三个参数,其实这三个参数都没有加过滤,直接字符串拼接。所以都存在SQL注入点,只不过sqlmap在start_time的时候,就跑出结果了,后面不验证罢了。需要提醒的是,再最新版本中,这个url需要构造出来,而不是点解控制台中哪个url。项目方把这个功能模块去掉了,但是代码并没有删除。简单验证如下图:


所以,前台的vue打包程序中,没有这个路由了。只能通过后期的构建,才能复现出这个漏洞。

任意文件上传

在平台所有文件上传点上,选取上传用户图像的功能点。


使用burpsuite抓包,如下:


将用户名和图片内容分别替换成php后缀的文件,和PHP代码如:此时返回的数据是错误的,不过没关系,文件已经生成了。如下图所示:


尝试了很多次,生的文件比较多。此时从浏览器上访问任意一个文件路径,效果如下:


当写入一句话的时候,也是可以用蚁剑连接的。





代码分析:通过抓包,访问的url
/index.php/admin/users/updateImg可以看到该方法如下:
    public function updateImg()
    {
        $fileModel = model('File');
        $param = $this->param;
        $userInfo = $this->userInfo;
        //处理图片
        header('Access-Control-Allow-Origin: *');
        header('Access-Control-Allow-Methods: POST');
        header("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept");
        $param['file'] = request()->file('file');
        
        $resImg = $fileModel->updateByField($param['file'], 'User', $param['id'], 'img', 'thumb_img', 150, 150);
        if (!$resImg) {
            return resultArray(['error' => $fileModel->getError()]);
        }
        return resultArray(['data' => '上传成功']);
    }

在方法里,有个updateByField的方法,这个是上传文件的调用,方法体如下:

public function updateByField($file, $module, $module_id, $field, $thumb_field = '', $x = '150', $y = '150')
    {
        if (empty($module) || empty($module_id) || empty($field)) {
            $this->error = '参数错误';
            return false;
        }
        
        $info = $file->move(FILE_PATH . 'public' . DS . 'uploads'); //验证规则
        $fileInfo = $info->getInfo(); //附件数据

在这个方法中,有个文件管理类file,其中的move方法做了文件的上传操作,如下:

public function move($path, $savename = true, $replace = true)
    {
        // 文件上传失败,捕获错误代码
        if (!empty($this->info['error'])) {
            $this->error($this->info['error']);
            return false;
        }

        // 检测合法性
        if (!$this->isValid()) {
            $this->error = 'upload illegal files';
            return false;
        }

        // 验证上传
        if (!$this->check()) {
            return false;
        }

        $path = rtrim($path, DS) . DS;
        // 文件保存命名规则
        $saveName = $this->buildSaveName($savename);
        $filename = $path . $saveName;

        // 检测目录
        if (false === $this->checkPath(dirname($filename))) {
            return false;
        }

        // 不覆盖同名文件
        if (!$replace && is_file($filename)) {
            $this->error = ['has the same filename: {:filename}', ['filename' => $filename]];
            return false;
        }

        /* 移动文件 */
        if ($this->isTest) {
            rename($this->filename, $filename);
        } elseif (!move_uploaded_file($this->filename, $filename)) {
            $this->error = 'upload write error';
            return false;
        }

        // 返回 File 对象实例
        $file = new self($filename);
        $file->setSaveName($saveName)->setUploadInfo($this->info);

        return $file;
    }

到此,方法体中的move_uploaded_file算是保存完了构建的PHP文件,需要注意的是,这里的命名规则,代码里用了时间的随机数,

   switch ($this->rule) {
                    case 'date':
                        $savename = date('Ymd') . DS . md5(microtime(true));
                        break;

也就是说,前端可以猜到具体的文件夹,但是具体的文件名,需要后期做个碰撞的脚本,才可以获取到。因为是白盒审计,这一步就暂时省略掉了。

总结

老版本种存在的问题,最新版本也是存在的,只不过需要后期数据的加工,没有之前版本来的那么容易。所以做程序要用心,做安全更是如此。


E

N

D



Tide安全团队正式成立于2019年1月,是新潮信息旗下以互联网攻防技术研究为目标的安全团队,团队致力于分享高质量原创文章、开源安全工具、交流安全技术,研究方向覆盖网络攻防、系统安全、Web安全、移动终端、安全开发、物联网/工控安全/AI安全等多个领域。

团队作为“省级等保关键技术实验室”先后与哈工大、齐鲁银行、聊城大学、交通学院等多个高校名企建立联合技术实验室,近三年来在网络安全技术方面开展研发项目60余项,获得各类自主知识产权30余项,省市级科技项目立项20余项,研究成果应用于产品核心技术研究、国家重点科技项目攻关、专业安全服务等。对安全感兴趣的小伙伴可以加入或关注我们。


微信扫码关注该文公众号作者

戳这里提交新闻线索和高质量文章给我们。
相关阅读
​KDD 2022 | kgTransformer:基于知识图谱与Transformer的复杂逻辑查询破纪录100度高温,Revere Beach洗海澡看沙雕我的爱好之一是“狗仔”我的孩儿和孙儿-:)Moomoo/富途牛牛投资账户【新用户抽10支股票;老用户充值奖励】大话西游16:围困花果山的神秘力量?为什么只有孙悟空能学艺?使用 External Secrets Operator 安全管理 Kubernetes Secrets祝允明《五云裘歌》卷Arm还是x86?分析师预测Arm笔记本电脑2023年将占据13.9%的市场份额橘朵官宣欧阳娜娜;字节推出“悟空搜索”;怡宝上新气泡苏打水... | 刀法品牌热讯大话西游10:孙悟空出生后到底有多狂,居然敢向天庭打手电筒?Zhihu Accused of Using Watermarks in Screenshots to Locate Users刚刚,《黑神话:悟空》最新预告发布!“女妖精”终于来了!大话西游15:花果山真正的猴王是谁?隐藏在孙悟空身后的黑手?新用户收到的商品质量远低于老用户,大数据还能“杀生”?加拿大4日游系列:卡尔加里接机/温哥华出发+班芙公园+强斯顿峡谷+哥伦比亚冰原+优鹤公园WVC4、WVCR4A、WVCR4B-D孙悟空的悲伤,朋友越多越孤独Collins词典公布2022年度十大词汇,"permacrisis "很简洁地概括了这一年实时榜一,我没见过这样的「孙悟空」世界首创!澳洲大学想出这个好办法:废弃的口罩、隔离服都还有新用!第二届海外博主节,今年OSSC悟空传媒又集齐了哪些大咖?!大话西游22:须菩提为什么要偷偷夜会孙悟空?孙悟空最神秘的法术是什么?Salesforce调整中国区业务,阿里云接手,国产CRM的机会?| 甲子光年大话西游20:菩提祖师到底属于那一派?为什么说孙悟空上当了?大话西游17:孙悟空的第一堂课,他为什么没有善心?洞洞鞋和Jibbitz™ Charms最高50%折扣!@ Crocs在美国183.精神专家,在哪找大话西游27:孙悟空黑化之始,他杀的第一个妖怪是谁?希望故事是在这样的:孙悟空为什么不阻拦妖怪抓唐僧?年少偏爱孙悟空,打工才知八戒香大话西游9:辟谣,孙悟空的父母不是石头,而是另有其人?大话西游24:菩提祖师教给孙悟空本领,就是教唆犯罪Arm急了?高通爆料ARM架构SoC将不允许外部GPU等设计,三星联发科等芯片厂商“被连坐”大话西游14:孙悟空为什么要学艺?隐藏在猴群中的真正老大是谁?柯林斯词典2022年度词汇“Permacrisis”是什么意思?零嘴
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。