4 月 6 日和 5 月 18 日,VMware 官方发布的两则安全公告中显示,关乎旗下产品的 CVE 漏洞多达 10 个,其中不乏有 CVSSv3 评分 9.8 的高危漏洞!如此高频的出洞速率,吸引了笔者注意。笔者将对 CVE-2022-22954 VMware Workspace ONE Access SSTI RCE 漏洞进行细致分析。
根据 4 月 6 日 VMware 官方发布的安全公告,官方已更新解决了多个产品的安全问题。其中 CVE-2022-22954,CVSS 评分为 9.8,危害等级为严重。该漏洞是由于 VMware Workspace ONE Access and Identity Manager 包含一个服务器端模板注入漏洞,导致具有网络访问权限的恶意攻击者可进行远程代码执行。
VMware Workspace ONE Access 21.08.0.1, 21.08.0.0,20.10.0.1, 20.10.0.0
VMware Identity Manager(vIDM) 3.3.6, 3.3.5, 3.3.4, 3.3.3
VMware vRealize Automation(vIDM) 7.6
VMware Cloud Foundation (vIDM) 4.x
使用内置函数将字符串计算为 FTL 表达式,FTL 表达式可以访问变量,并调用 Java 方法,例如 "1+2"?eval 将返回数字 3,所以?eval
前的字符串因来自不受信任的来源,可能就会成为攻击媒介。
在 Vmware 中的 endusercatalog-ui-1.0-SNAPSHOT-classes.jar 自带的模板 customError.ftl 就调用了 freemarker 引擎的 eval 函数来渲染 errObj,这就导致了本次 SSTI 注入漏洞。
【一一帮助安全学习,所有资源获取处一一】
①网络安全学习路线
②20 份渗透测试电子书
③安全攻防 357 页笔记
④50 份安全攻防面试指南
⑤安全红队渗透工具包
⑥信息收集 80 条搜索语法
⑦100 个漏洞实战案例
⑧安全大厂内部视频资源
⑨历年 CTF 夺旗赛题解析
本次漏洞分析源码所在位置:/opt/vmware/horizon/workspace/webapps/catalog-portal/WEB-INF/lib。
已经定位到安全问题所在,接下来寻找渲染 customError.ftl 模板的相关代码。
在 com.vmware.endusercatalog.ui.web.UiErrorController#handleGenericError 函数中。
errorObj 由参数传入。
查找 handleGenericError 函数的被调用关系发现。
handleGenericError 函数受如上图所示的两个 requestMapping 所在的控制器 UiErrorController 调用。
跟进其中出现的 getErrorPage 函数,位于 com.vmware.endusercatalog.ui.web.UiErrorController#getErrorPage。
除了直接用 handleGenericError 函数拿到需要渲染的模板,还存在 handleUnauthorizedError 函数通过条件判断,只有一个分支进入 handleGenericError
如何构造参数?
在两个 requestMapping 中,其中的/ui/view/error 为 API 接口,直接访问无法从请求中提取 javax.servlet.error.message,从而无法控制 errorObj。
寻找/ui/view/error 的其他调用,位于 com.vmware.endusercatalog.ui.web.UiApplicationExceptionResolver#resolveException 函数。
存在对 javax.servlet.error.message 赋值的过程。
查看 resolveException 函数的被调用关系,受上方 handleAnyGenericException 函数调用。
其中 @ExceptionHandler 表明,该处为异常处理器,当程序直接抛出 Exception 类型的异常时会进入 handleAnyGenericException,再通过调用 resolveException 函数,进行赋值,最终都会返回/ui/view/error。
而在 handleAnyGenericException 中,进入 resolveException 时会根据异常的类型传入不同的参数,如果异常类不是 LocalizationParamValueException 子类的话则传入 uiRequest.getRequestId(),所以我们需要构造参数可控的地方还需要抛出 LocalizationParamValueException 异常类或其子类异常,这样 errorObj 所需 Attribute errorJson 来自 LocalizationParamValueException 异常的 getArgs。
在 LocalizationParamValueException 函数,如果可以控制抛出异常的参数,就可以把 payload 传入 errorObj。
在 endusercatalog-auth-1.0-SNAPSHOT.jar 中 com.vmware.endusercatalog.auth.InvalidAuthContextException,存在一个 InvalidAuthContextException 异常,继承于 LocalizationParamValueException。
在 com.vmware.endusercatalog.auth.AuthContext 构造函数中抛出异常。
生成 AuthContext 对象的地方在 AuthContextPopulationInterceptor 拦截器中,而且各项参数均是从请求中获取,这里可构造注入点。
但正常情况下,在 endusercatalog-auth-1.0-SNAPSHOT.jar 中的拦截器类无法访问到类。
但在 com.vmware.endusercatalog.ui.UiApplication,使用 @ComponentScan 注解声明自动将 com.vmware.endusercatalog.auth 包的类装配进 bean 容器。
在包中 com.endusercatalog.ui.config.WebConfig 可查找到。
可进行构造的 url。
通过如上分析,可构造 payload,进行命令执行。