1

CVE-2022-27925 Zimbra Collaboration 存在路径穿越漏洞最终导致RCE

 1 year ago
source link: https://paper.seebug.org/1924/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

作者:且听安全
原文链接:https://mp.weixin.qq.com/s/2pUW4H1v6mnXtMqTlxZCMA

漏洞信息

前段时间 Zimbra 官方通报了一个 RCE 漏洞 CVE-2022-27925 ,也有小伙伴在漏洞空间站谈到了这个漏洞,上周末在家有时间完成了漏洞的分析与复现。漏洞原理并不复杂,但在搭建环境的过程中遇到了一些坑,下面将分析过程分享给大家。

图片

从描述来看,这是一个 ZIP 压缩包解析导致路径穿越类型的漏洞。

环境搭建

由于直接安装 v9.0.0 或 v8.8.15 默认就是最新版,因此选择安装 v8.8.12。安装过程非常曲折,环境搭建有疑惑的小伙伴可以加入漏洞空间站进行交流

最终完成安装并启动成功:

图片

通过配置 mailboxd_java_options 加入调试信息:

图片

重启 Zimbra 服务即可打开远程调试:

图片

寻找调用链

漏洞出现在 mboximport 相关的功能中,全盘搜索定位到位于 zimbrabackup.jar 中的 MailboxImportServlet :

图片

从命名规则和存在的成员函数 doPost 来看, MailboxImportServlet 应该对应一个 Servlet 对象,但是 MailboxImportServlet 继承于 ExtensionHttpHandler 而非 HttpServlet

图片

所以还需要寻找某种相互之间的转换关系。我们知道 Zimbra 自定义了 Servlet 对象的基类 ZimbraServlet ,搜索其子类:

图片

定位 ExtensionDispatcherServlet

图片

可以找到相关配置:

图片

图片

所以 ExtensionDispatcherServlet 对应的 URL 规则为 /service/extension/* ,回到 ExtensionDispatcherServlet#service 函数:

图片

通过 getHandler 函数来寻找对应的 ExtensionHttpHandler 对象 handler (前面定位的 MailboxImportServlet 正好继承于 ExtensionHttpHandler),进入 getHandler 函数:

图片

提取 URL 中 /service/extension 之后的字符串并赋值给 extPath ,带入 getHandler 函数:

图片

返回的 ExtensionHttpHandler 对象来自于 sHandlers 键值对,其中的 key 来自于 ExtensionHttpHandler#getPath 函数,查看定义:

图片

ExtensionHttpHandler#getPath

图片

图片

mExtensionZimbraExtension 类型,并且在 init 函数中完成初始化,搜索 ZimbraExtension 子类:

图片

定位 BackupExtension ,里面刚好注册了 MailboxImportServlet 类型:

图片

所以构造特定 URL 将调用 MailboxImportServlet ,测试如下:

图片

成功进入 MailboxImportServlet#doPost 函数处理逻辑。

权限认证分析

下面分析一下 doPost 函数的处理逻辑,首先通过 getAuthTokenFromCookie 从 Cookie 中提取 token 认证信息,并检查是否为管理员权限:

AuthToken authToken = ZimbraServlet.getAuthTokenFromCookie(req, resp);
if (authToken == null || !authToken.isAdmin()) {
    Log.mboxmove.warn("Auth failed");
    this.sendError(resp, 403, "Auth failed");
}

进入 getAuthTokenFromCookie

图片

因为这里 isAdminReq 默认为 false ,因此认证后需要携带 ZM_AUTH_TOKEN 的 Cookie 值,而非 ZM_ADMIN_AUTH_TOKEN

图片

漏洞点定位

通过权限检查后,将会进行一系列参数提取与判断,当提供的 account-name 等参数通过验证后,将进入第 152 行 importFrom 函数:

图片

其中 in 来自于 POST 请求数据包,进入 importFrom 函数:

图片

提取 ZIP 压缩包,调用 restore 函数:

图片

进入 getAccountSession 函数:

图片

实例化 ZipBackupTarget.RestoreAcctSession 对象,进入构造函数:

图片

跟进 unzipToTempFiles 函数:

图片

ZIP 压缩包解压过程存在路径穿越漏洞,导致可以向任意路径写入 shell 。

漏洞复现

通过上述分析,我们可以构造一个存在路径穿越的 ZIP 压缩包,并发送特定 POST 请求实现压缩包解压路径穿越:

图片

最终写入 shell :

图片

Paper 本文由 Seebug Paper 发布,如需转载请注明来源。本文地址:https://paper.seebug.org/1924/


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK