文章作者:rebeyond
受影响版本:v6~v7
漏洞说明:
JEECMS是国内Java版开源网站内容管理系统(java cms、jsp cms)的简称。该系统基于java技术开发,继承其强大、稳定、安全、高效、跨平台等多方面的优点;采用SpringMVC3+Spring3+Hibernate3+Freemarker主流技术架构。广泛应用于政府(部委和省级政府部门、市、县、乡及委办局)、教育科研(大、中、小学及各地方教育局)、电信运营商、金融(证券、保险及银行)、企业(矿业、煤炭、旅游、石油集团及大中型制造类企业)、新闻媒体(报社、网媒)等数字化信息平台建设领域。
该系统提供swfAttach文件上传功能,其中对用户提交的上传文件没有进行充分的检查,导致任意注册用户在前台即可上传任意格式的文件。
利用场景:前台注册用户。默认注册地址:http://www.xxx.com/register.jspx。
漏洞分析:
调用入口代码如下:
@RequestMapping(value = "/member/o_swfAttachsUpload.jspx", method = RequestMethod.POST) public void swfAttachsUpload( String root, Integer uploadNum, @RequestParam(value = "Filedata", required = false) MultipartFile file, HttpServletRequest request, HttpServletResponse response, ModelMap model) throws Exception{ super.swfAttachsUpload(root, uploadNum, file, request, response, model); }
跟进swfAttachsUpload:
protected void swfAttachsUpload( String root, Integer uploadNum, @RequestParam(value = "Filedata", required = false) MultipartFile file, HttpServletRequest request, HttpServletResponse response, ModelMap model) throws Exception { JSONObject data=new JSONObject(); WebCoreErrors errors = validateUpload( file, request); if (errors.hasErrors()) { data.put("error", errors.getErrors().get(0)); ResponseUtils.renderJson(response, data.toString()); }else{ CmsSite site = CmsUtils.getSite(request); String ctx = request.getContextPath(); String origName = file.getOriginalFilename(); String ext = FilenameUtils.getExtension(origName).toLowerCase( Locale.ENGLISH); String fileUrl=""; try { if (site.getConfig().getUploadToDb()) { String dbFilePath = site.getConfig().getDbFileUri(); fileUrl = dbFileMng.storeByExt(site.getUploadPath(), ext, file .getInputStream()); fileUrl = request.getContextPath() + dbFilePath + fileUrl; } else if (site.getUploadFtp() != null) { Ftp ftp = site.getUploadFtp(); String ftpUrl = ftp.getUrl(); fileUrl = ftp.storeByExt(site.getUploadPath(), ext, file .getInputStream()); fileUrl = ftpUrl + fileUrl; } else { fileUrl = fileRepository.storeByExt(site.getUploadPath(), ext, file); //没有进行合法文件后缀检查。 fileUrl = ctx + fileUrl; } cmsUserMng.updateUploadSize(CmsUtils.getUserId(request), Integer.parseInt(String.valueOf(file.getSize()/1024))); fileMng.saveFileByPath(fileUrl, origName, false); //没有进行合法文件后缀检查 model.addAttribute("attachmentPath", fileUrl); } catch (IllegalStateException e) { model.addAttribute("error", e.getMessage()); } catch (IOException e) { model.addAttribute("error", e.getMessage()); } data.put("attachUrl", fileUrl); data.put("attachName", origName); ResponseUtils.renderJson(response, data.toString()); } }
通过构造以下表单,就可以进行测试:
下面是拿官方演示站测试的结果: