CVE-2020-10189 Zoho ManageEngi
漏洞描述
在3月6日,@steventseeley 在twitter上发布了关于 Zoho 企业产品 Zoho ManageEngine Desktop Central 中的反序列化远程代码执行漏洞。该产品是一款基于 Web 的企业级服务器、桌面机及移动设备管理软件,可对桌面机以及移动设备管理的整个生命周期提供完全的支持,提供软件分发、补丁管理、资产管理、系统配置、远程控制、USB 外设管理、移动设备及应用管理等功能模块,帮助 IT 管理员集中远程管理大量的 PC 和 IOS/Android/Windows 移动设备。
影响版本
Zoho ManageEngine Desktop Central < 10.0.474
漏洞分析
本文使用10.0.465 x64复现分析,历史版本下载移步。
寻找反序列化点
首先反序列化漏洞,肯定需要先找到反序列化的点。
查看 DesktopCentral_Server\webapps\DesktopCentral\WEB-INF\web. 发现了名为 CewolfServlet 的servlet,对应的类为 DesktopCentral_Server\lib\cewolf-1.2.4.jar 中的 de.laures.cewolf.CewolfRenderer,对应的url为/cewolf/*


CewolfRenderer 类继承 HttpServlet 是一个 servlet,在其 doGet 方法中

imgKey 可控,然后调用 storage.getChartImage(imgKey, request) 。Storage 类是一个接口,在这个jar包中,FileStorage 类实现了 Storage 接口的 getChartImage 方法。

很明显的看到直接将之前传入的 img 当作 imgKey 参数,然后通过 getFileName() 获取文件名然后进行 ObjectInputStream 的 readObject(),再看 getFileName()。

进行了一个简单的拼接,无伤大雅。
捋一下,通过img传入参数触发读文件进而反序列化,现在的问题就是这个恶意的序列化文件我们怎么传上去,并且路径要有_chart。
寻找上传点
web.中寻找上传的servlet

跟进之后发现udid、filename可控,并且udid被拼接到文件保存目录中。

String localDirToStore = Dir + File.separator + "mdm-logs" + File.separator + this.customerID + File.separator + this.deviceName + "_" + udid;
那么我们可以跨目录上传,在上文中我们传入文件名触发反序列化时会拼接 this.Path + "_chart" + id 到路径中,所以我们需要构造一个 _chart 的路径 aaa\..\..\..\webapps\DesktopCentral\_chart。
再来看对文件名的处理

然后文件名转小写之后进行了 FileUploadUtil.hasVulnerabilityInFileName(fileName "log|txt|zip|7z") 的校验,然后拼接为完整的文件路径,看下校验了什么。

然后进行 isContainDirectoryTraversal() 、 isCompletePath() 、 isValidFileExtension() 的校验。
private static boolean isContainDirectoryTraversal(String fileName) { return fileName.contains("/") || fileName.contains("\\"); } private static boolean isCompletePath(String fileName) { String regexFileExtensionPattern = "([a-zA-Z]:[\\ \\\\ / //].*)"; Pattern pattern = Pattern.compile(regexFileExtensionPattern); Matcher matcher = pattern.matcher(fileName); return matcher.matches(); } private static boolean isContainExecutableFileExt(String fileName) { if (fileName.indexOf("\u0000") != -1) { fileName = fileName.substring(0 fileName.indexOf("\u0000")); } String fileExtension = FilenameUtils.getExtension(fileName).trim(); if (!fileExtension.trim().equals("")) { fileExtension = fileExtension.toLowerCase(); ArrayList executableFileExts = new ArrayList(Arrays.asList("jsp" "js" "html" "htm" "shtml" "shtm" "hta" "asp")); if (executableFileExts.contains(fileExtension)) { return true; } } return false; }
判断是否文件名进行了目录穿越、是否是合法后缀等,但是因为之前的目录是由udid控制的,并不影响我们的文件上传。而在web.中引入了security-mdm-agent.

在 security-mdm-agent. 中有一个校验,只允许文件名为 logger.txt|logger.zip|mdmlogs.zip|managedprofile_mdmlogs.zip

所以构造如下请求,即可上传文件

寻找gadgets
DesktopCentral_Server\lib 中有 commons-collections.jar(3.1)、commons-beanutils-1.8.0.jar,完美。使用ysoserial生成序列化文件,先上传然后触发反序列化就完事了。注意ysoserial的pom.要和目标的jar版本一样。

漏洞修复
截至2020/03/20 9.34分,官网版本为10.0.515,已经修复了漏洞,请更新。
参考链接
- https://srcincite.io/pocs/src-2020-0011.py.txt
- https://www.anquanke.com/post/id/200474
- https://www.manageengine.com/products/desktop-central/remote-code-execution-vulnerability.html
内容浅显,操作生疏。不足之处欢迎大师傅们指点和纠正,感激不尽。







