CVE-2022-22954
代码分析
http://file.xipudata.com/?dir=/2_software/Vmware/Horizon8
下载好ova,使用vmware安装搭建,导入时添加下域名。
根据官方提供的临时修复脚本可以知道漏洞存在于
/opt/vmware/horizon/workspace/webapps/catalog-portal/WEB-INF/lib/endusercatalog-ui-1.0-SNAPSHOT-classes.jar
修复脚本中还提到了这个文件
查看该文件后发现存在eval,这是java freemarker的写法,用来把字符串当作ftl代码,所以我们只需要控制errorObj即可实现代码执行
所以我们知道漏洞来源于customError,我们需要找到可以到达customError的路由,并且可以控制errorObj
在UiErrorController.class中可以找到handleGenericError,可以传递errorObj,最后return到customError
private String handleGenericError(final HttpServletRequest request, final HttpServletResponse response, final Map<String, Object> model, final boolean isAWJade, final boolean garnetAndAbove, final String excpClass, final int errorCode, final String errorMessage) {
final String localizedMessageHeader = this.messages.getLocalizedErrorMessage("errorPage.errorHeading", request.getLocale(), (Object[])null);
final String localizedMessage = this.messages.getLocalizedErrorMessage(this.getLocalizedMessageKey(excpClass), request.getLocale(), (Object[])null);
if (errorCode != -1) {
response.setStatus(errorCode);
}
model.put("errorObj", errorMessage);
model.put("messageHeader", localizedMessageHeader);
model.put("genericErrorMsg", localizedMessage);
model.put("contextPath", request.getContextPath());
if (isAWJade) {
WebUtils.markCookiesForDeletion(request, response, new String[] { "USER_CATALOG_CONTEXT" });
WebUtils.markCookiesForDeletionWithPath(request, response, "/catalog-portal", new String[] { "EUC_XSRF_TOKEN" });
model.put("logoutPath", retrieveServerInitiatedLogoutPath(garnetAndAbove).getName());
}
else {
final StringBuilder logoutUrl = new StringBuilder(request.getContextPath()).append("/ui").append("/logout");
String queryStr = request.getQueryString();
if (StringUtils.isNotBlank((CharSequence)queryStr)) {
queryStr = UrlUtils.encodeQuery(UrlUtils.decode(queryStr));
logoutUrl.append('?').append(queryStr);
}
model.put("logoutPath", logoutUrl.toString());
}
return "customError";
}
所以我们继续往上找到getErrorPage和handleUnauthorizedError,调用了handleGenericError