CVE-2020-10189_Zoho_ManageEngine反序列化RCE

# CVE-2020-10189 Zoho ManageEngine反序列化RCE

## 漏洞描述

在3月6日,[@steventseeley](https://twitter.com/steventseeley/status/1235635108498948096) 在twitter上发布了关于 Zoho 企业产品 Zoho ManageEngine Desktop Central 中的[反序列化](https://www.chabug.org/tags/反序列化)远程代码执行漏洞。该产品是一款基于 Web 的企业级服务器、桌面机及移动设备管理软件,可对桌面机以及移动设备管理的整个生命周期提供完全的支持,提供软件分发、补丁管理、资产管理、系统配置、远程控制、USB 外设管理、移动设备及应用管理等功能模块,帮助 IT 管理员集中远程管理大量的 PC 和 IOS/Android/Windows 移动设备。

## 影响版本

Zoho ManageEngine Desktop Central < 10.0.474 ## 漏洞分析 本文使用10.0.465 x64复现分析,[历史版本下载移步](http://archives.manageengine.com/desktop-central/)。 ### 寻找反序列化点 首先反序列化漏洞,肯定需要先找到反序列化的点。 查看 `DesktopCentral_ServerwebappsDesktopCentralWEB-INFweb.xml` 发现了名为 `CewolfServlet` 的`servlet`,对应的类为 `DesktopCentral_Serverlibcewolf-1.2.4.jar` 中的 `de.laures.cewolf.CewolfRenderer`,对应的url为`/cewolf/*` [![image](resource/CVE-2020-10189%20Zoho%20ManageEngine%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96RCE/media/20200321182965.png)](/static/qingy/CVE-2020-10189_Zoho_ManageEngine反序列化RCE/img/20200321182965.png) [![image](resource/CVE-2020-10189%20Zoho%20ManageEngine%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96RCE/media/20200321185502.png)](/static/qingy/CVE-2020-10189_Zoho_ManageEngine反序列化RCE/img/20200321185502.png) `CewolfRenderer` 类继承 `HttpServlet` 是一个 `servlet`,在其 `doGet` 方法中 [![image](resource/CVE-2020-10189%20Zoho%20ManageEngine%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96RCE/media/20200321182003.png)](/static/qingy/CVE-2020-10189_Zoho_ManageEngine反序列化RCE/img/20200321182003.png) `imgKey` 可控,然后调用 `storage.getChartImage(imgKey, request)` 。`Storage` 类是一个接口,在这个jar包中,`FileStorage` 类实现了 `Storage` 接口的 `getChartImage` 方法。 [![image](resource/CVE-2020-10189%20Zoho%20ManageEngine%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96RCE/media/20200321181041.png)](/static/qingy/CVE-2020-10189_Zoho_ManageEngine反序列化RCE/img/20200321181041.png) 很明显的看到直接将之前传入的 `img` 当作 `imgKey` 参数,然后通过 `getFileName()` 获取文件名然后进行 `ObjectInputStream` 的 `readObject()`,再看 `getFileName()`。 [![image](resource/CVE-2020-10189%20Zoho%20ManageEngine%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96RCE/media/20200321183565.png)](/static/qingy/CVE-2020-10189_Zoho_ManageEngine反序列化RCE/img/20200321183565.png) 进行了一个简单的拼接,无伤大雅。 捋一下,通过img传入参数触发读文件进而反序列化,现在的问题就是这个恶意的序列化文件我们怎么传上去,并且路径要有`_chart`。 ### 寻找上传点 web.xml中寻找上传的servlet [![image](resource/CVE-2020-10189%20Zoho%20ManageEngine%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96RCE/media/20200321186974.png)](/static/qingy/CVE-2020-10189_Zoho_ManageEngine反序列化RCE/img/20200321186974.png) 跟进之后发现udid、filename可控,并且udid被拼接到文件保存目录中。 [![image](resource/CVE-2020-10189%20Zoho%20ManageEngine%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96RCE/media/20200321185491.png)](/static/qingy/CVE-2020-10189_Zoho_ManageEngine反序列化RCE/img/20200321185491.png) ```java String localDirToStore = baseDir + File.separator + "mdm-logs" + File.separator + this.customerID + File.separator + this.deviceName + "_" + udid; ``` 那么我们可以跨目录上传,在上文中我们传入文件名触发反序列化时会拼接 `this.basePath + "_chart" + id` 到路径中,所以我们需要构造一个 `_chart` 的路径 `aaa......webappsDesktopCentral_chart`。 再来看对文件名的处理 [![image](resource/CVE-2020-10189%20Zoho%20ManageEngine%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96RCE/media/20200321186665.png)](/static/qingy/CVE-2020-10189_Zoho_ManageEngine反序列化RCE/img/20200321186665.png) 然后文件名转小写之后进行了 `FileUploadUtil.hasVulnerabilityInFileName(fileName, "log|txt|zip|7z")` 的校验,然后拼接为完整的文件路径,看下校验了什么。 [![image](resource/CVE-2020-10189%20Zoho%20ManageEngine%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96RCE/media/20200321184618.png)](/static/qingy/CVE-2020-10189_Zoho_ManageEngine反序列化RCE/img/20200321184618.png) 然后进行 `isContainDirectoryTraversal()` 、 `isCompletePath()` 、 `isValidFileExtension()` 的校验。 ```java 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.xml中引入了security-mdm-agent.xml [![image](resource/CVE-2020-10189%20Zoho%20ManageEngine%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96RCE/media/20200321187536.png)](/static/qingy/CVE-2020-10189_Zoho_ManageEngine反序列化RCE/img/20200321187536.png) 在 `security-mdm-agent.xml` 中有一个校验,只允许文件名为 `logger.txt|logger.zip|mdmlogs.zip|managedprofile_mdmlogs.zip` [![image](resource/CVE-2020-10189%20Zoho%20ManageEngine%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96RCE/media/20200321183022.png)](/static/qingy/CVE-2020-10189_Zoho_ManageEngine反序列化RCE/img/20200321183022.png) 所以构造如下请求,即可上传文件 [![image](resource/CVE-2020-10189%20Zoho%20ManageEngine%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96RCE/media/20200321181636.png)](/static/qingy/CVE-2020-10189_Zoho_ManageEngine反序列化RCE/img/20200321181636.png) ### 寻找gadgets `DesktopCentral_Serverlib` 中有 `commons-collections.jar(3.1)`、`commons-beanutils-1.8.0.jar`,完美。使用ysoserial生成序列化文件,先上传然后触发反序列化就完事了。注意ysoserial的pom.xml要和目标的jar版本一样。 [![image](resource/CVE-2020-10189%20Zoho%20ManageEngine%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96RCE/media/20200321181885.png)](/static/qingy/CVE-2020-10189_Zoho_ManageEngine反序列化RCE/img/20200321181885.png) ## 漏洞修复 截至2020/03/20 9.34分,官网版本为10.0.515,已经修复了漏洞,请更新。 ## 参考链接 1. https://srcincite.io/pocs/src-2020-0011.py.txt 2. https://www.anquanke.com/post/id/200474 3. https://www.manageengine.com/products/desktop-central/remote-code-execution-vulnerability.html

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    请登录后查看评论内容