
Oracle WebLogic ADF Faces用の事前認証リモートコード実行エクスプロイト(CVE-2022-21445、CVSS 9.8)。ペネトレーションテスト用の詳細な環境設定、ペイロード生成、リモートデバッグ手順を含む。
CVE-2022-21445(CVSSスコア9.8)は、信頼できないデータのデシリアライズの脆弱性であり、ADF Facesコンポーネントに存在することが確認されており、攻撃者が事前認証なしでリモートから悪用してRCEを実行できる可能性があります。
この脆弱性は、VNG CorporationのPeterJson氏とVNPTのNguyen Jang氏という2人のサイバーセキュリティ専門家によって発見されました。その後、Oracleは2021年10月にこの報告を受け、パッチのリリースまでに6か月、つまり2022年4月までかかりました。
この記事では、Oracle Business Intelligenceバージョン12.2.1.4.0への悪用に焦点を当てます。
条件: ライセンスがアクティブなWindows 10+ ProまたはWindows Home(x64)をインストールするか、Windows Serverを使用します(できればOracle製品を推奨)。
手順1: Javaをインストールします。バージョンはjdk 8u112以上(8Ux)、ダウンロードリンク: JDKv8U112

手順2: Oracle Database 19cをインストールします。ダウンロードリンク: Oracle 19c
データベースをインストールするためのフォルダを準備し、以下のようなパスを作成して、ダウンロードしたデータベースのzipファイルをここに解凍します: C:\app\oracle\product\19c\db_home1
setup.applicationファイルを管理者権限で実行します。

の指示に従ってステップバイステップで実行します。
非常に重要:
ステップ8/17で、今後のFusion Middlewareインストールプロセスに備えて、Create as Container database にチェックを入れて、プラガブルDBを開くことを忘れないでください。

ステップ9/17で、文字セットとしてUnicode (AL32UTF8) を選択します。



手順3: SQL Developerをインストールします。バージョンはno-jre、ダウンロードリンク: SQLDev-NoJRE

sqldeveloper.applicationファイルを管理者権限で実行します。

下図のように新しい接続のパラメータを設定します。UsernameとPassword(上の例では___hr___)、Hostname(デフォルトは___localhost___)、Port(デフォルトは___1521___)、SID(手順2でインストールしたグローバルデータベース名)を変更することに注意してください。

__Test__を選択したときに__Success__というメッセージが表示されたら接続成功です。__Connect__を選択します。
手順4: Fusion Middleware Infrastructure (FMW) バージョン12.2.1.3.0をインストールします。ダウンロードリンク: FMW_ver_12.2.1.3.0

手順5: Oracle Business Intelligence (OBIEE) バージョン12.2.1.4.0をインストールします。ダウンロードリンク: OBIEE_ver_12.2.1.4.0
__setup_bi_platform-12.2.1.4.0_win64.exe__ファイルを管理者権限で実行します。

OBIEEインストールガイド に従ってステップバイステップでインストールします。
注意: BIのパスはFWMをインストールしたパスと同じでなければなりません。ここでは Oracle/Middleware/Oracle_Home です。

手順6: Repository Creation Utility (RCU) を使用してBI Schemaを設定します。
パス C:\Oracle\Middleware\Oracle_Home\oracle_common\bin で、___rcu.bat___ファイルを管理者権限で実行します。
以下の手順を順番に実行します。




手順7: OBIEEの環境変数を設定します。

手順8: BIドメインの作成





ステップ4でシステムがfail to logonと表示した場合は、ドメインのパスワードが正しいか再確認してください。
ステップ8でシステムが下図のようなエラーを表示した場合は、Windowsのライセンスがアクティブ化されているかどうか、またお使いのWindowsが「条件」セクションに記載されている内容と一致しているかを確認してください。
![]()
手順9: セットアップが完了したら、先ほど作成したBIドメインのパス $Oracle_Home\user_projects\domains\bi\servers\AdminServer\tmp_WL_user\adf.oracle.domain.webapp\i83uao にアクセスします。
ここにあるすべてのjarファイルを別のフォルダにコピーし、攻撃マシンに共有します(ラボ環境ではこのようにします。実際の攻撃では、攻撃マシンにもターゲットマシンと同じ環境をインストールしてソースコードを入手する必要があります)。
パス $Oracle_Home\coherence\lib にあるcoherence.jarライブラリもこのフォルダに追加します。
これはペイロードの成否を左右する重要なフォルダです。FMWやBIのバージョン、各マシンのインストール環境は通常異なるため、ペイロード送信中に例外やリスクが発生しないよう、バージョンを正確に一致させる必要があります。
手順10(リモートデバッグが必要な場合のみ実行します。繰り返しますが、実際の環境外でテストする場合は、被害者マシンを自由にセットアップできないため、攻撃者は自分のマシンでもターゲットマシンのセットアップを行い、リモートデバッグでエラーを確認する必要があります)
Mozillaをインストールし、ポート8181でBurp Proxyを追加します。
BIサーバー側でリモートデバッグを有効にします。
localhost:9500/console にアクセスします。
Domain Structure -> biを選択 -> Environment -> Servers の順に選択します。

2つのサーバーが表示されます。WebLogicのAdminServerとBIのbi_server1です。
画像 10.2: 表示されるサーバー一覧
左上隅のLock & Editを選択し、bi_server1にチェックを入れて設定を編集します。ここで、Configuration -> Server start の順に選択し、一番下までスクロールして、Advance(あれば)を選択し、Argumentsに入力を選択して、以下のデバッグパラメータを入力します:
-Xdebug -Xnoagent – Xrunjdwp:transport=dt_socket,address=5005,server=y,suspend=n
(後で再起動できないエラーが発生した場合は、0.0.0.0:5005を試してもよいです bi_server1)
WebLogicパスワードを入力します(先ほどConfig BI Domainセクションで設定したもの)-> Apply change & Restart
管理者ターミナルを起動し、パス $Oracle_Home\user_projects\domains\bi\bitools\bin に移動して ./stop.cmd と ./start.cmd を実行してbi_server1を再起動します。再起動中にエラーが発生しなければ、上記のようにデバッグが有効になり、ポート5005で待ち受けます。エラーが発生した場合は、上記のデバッグパラメータに余分なスペースがないか、addressの部分が間違っていないか確認してください。
手順1: IntelliJ IDEA Ultimateをダウンロードし、GitHubで見つけたコードでアクティベートします。
手順2(攻撃プロセス中に__500 Server Error, ...__などのエラーが発生した場合のみ実行します。これはペイロード内の例外が原因です)
プロジェクトのjdk – sdkのバージョンをターゲットマシンと同じバージョンに変更します(インストール方法は__ターゲットマシン側 - 手順1__を参照)。
ソースコードを解析してリモートデバッグを行うための空のProjectを作成します。3. ターゲットマシンから受け取ったフォルダ内のすべてのjarファイルをこのプロジェクトに追加します。
Project Structure -> Modules -> +記号を選択 -> 1 JARS or Directories -> jarフォルダ全体をAddします。


リモートデバッグの設定
Run -> Edit Configurations -> + -> Remote JVM Debug

リモートデバッグを実行し、コンソールに「Connected …」というメッセージが表示されれば成功です。

手順3:
このリポジトリのコードをマシンにクローンし、libフォルダ内の古いcoherence.jarファイルを削除して、前の手順でターゲットマシンから受け取ったファイルに置き換えます。
次に、IntelliJで実行するプロジェクトに追加し、__lib__内のjarファイルを__Add as library__オプションで追加します。
LambdaIdentity$....クラスの名前がWebLogicのバージョンと一致しているか確認します。変更があった場合は、ファイルをリファクタリングしてそのファイル名を修正します。
Weblogic 12.2.1.3: LambdaIdentity$E12ECA49F06D0401A9D406B2DCC7463A
Weblogic 12.2.1.4: LambdaIdentity$423B02C050017B24DB10DFF759AA56BF
Main.java ファイル内のLambdaIdentity$....classファイルへのパスを修正します。正確なパスを取得するには2つの方法があります: __javac__を実行してjarファイルから.classファイルを生成する方法。もう1つの方法は、main関数のコードをコメントアウトし、その後プロジェクトを通常どおり実行すると、クラスファイルのパスがtargetディレクトリで見つかります。
プロジェクトのjdkとsdkがターゲットマシン側と一致しているかを再確認します。
web.xmlファイルがあります。このファイルはservlet-mappingに関連するマッピング関係を記述しています。「resources」はシステムリソースに関連するサーブレットで、重要なデータと情報を含んでいるため、攻撃者によく狙われる場所です。






RemoteApplicationResourceLoader.classのfindResource()関数の分析

この関数は、カスタムプロトコルRAStreamHandler()を含むメソッドを返します。RAStreamHandlerは、new RAURLConnectionという値でURLConnectionオブジェクトを作成します。

RAURLConnection関数は_getPathBean関数を呼び出します。

_getPathBean関数には、getInstanceFromString()関数を呼び出して作成されたbeanオブジェクトが含まれており、受け取った文字列を処理して対応するキー(フィルタ)を取得します。

入力されたbean文字列は、SerializationUtilsクラスを通じてURLエンコード形式からURLEncoderPathBeanオブジェクトに変換されます。すべてが正常であれば、後続の入力はfromURLEncodeString()関数に渡され続けます。


入力文字列にエラーがある場合は例外がスローされます。例外は主に、ペイロードで使用されるライブラリのバージョン不一致、またはLambdaファイルへのパスが間違っていることが原因です。
fromURLEncodedString()関数では、urlパラメータを持つfromString関数が返され、そのコードは次のとおりです:

fromString関数では、データはreadObject()で読み取られて返されます。入力は一切フィルタリングされていないことがわかります。複数の関数を通過し、最終的にfromString()でデシリアライズされます。これが悪用に使われるシンクです。シンクが判明したので、次はソースを見つければ完了です。
したがって、前述のクラスを呼び出すには、“/.*/remote/(.*)” という形式の正規表現が必要です。そのため、ルーターや入力パスが /em/afr/foo/remote/payload の形式である場合、このファイルで定義された構造を満たすことになり、doGet では RemoteApplicationResourceLoader がローダーとして使用され、対応するクラスファイル oracle.adfinternal.view.resource.rich.RemoteApplicationResourceLoader がそこでオーバーライドされた findResource() 関数を呼び出します。したがって、ペイロードを正しいアドレスに送信すれば、フィルターに引っかかることなくデータを簡単に送信できます。
これはエクスプロイトに使用する最終的な URL です:
__hostname:port/contextApp/afr/foo/remote/payload/__
- ここで contextApp は、OBIEE のインストール直後に存在するパスの 1 つ(/em、/bicomposer など)です。
- Foo は任意の文字列です。
- Payload は、準備した攻撃プロジェクトの Main 関数を実行したときに生成される文字列です。
### ペイロードを作成するコードの分析
このプロジェクトは、CVE-2020-14644 のガジェットチェーンに従っています。

Class LambdaIdentity$E12ECA49F06D0401A9D406B2DCC7463A は AbstractRemotable から継承され、リモートシステムと対話するために使用されます。
Java Reflection API を使用することで、攻撃者は現在の実行スレッドから WorkAdapter を簡単に取得できます。
次に、WorkAdapter の connectionHandler フィールドを取得し、クエリを実行して connectionHandler から ServletRequest と ServletResponse を取得します。
次に、リクエスト (ServletRequest) から "cmd" ヘッダーの値を取得し、"cmd" が空でない場合は、現在実行中のオペレーティングシステム (Windows または Linux/Unix) に対応するシェルコマンドを実行します。
シェルコマンドの出力を読み取り、その結果をレスポンス (ServletResponse) に送信します。
実行中にエラーが発生した場合、それらは printStackTrace() メソッドによってコンソール画面に出力されます。
LamdaIdentity クラス名の後ろにある Id は WebLogic Server のバージョンに依存し、com.tangosol.internal.util.invoke.ClassIdentity クラスの MD5 ハッシュ値に基づいてエンコードされた文字列です。各バージョンでこのクラスは異なるため、前述のとおり、ペイロードがエラーにならないようにこれを注意深く確認する必要があります。
ここでは、cmd 変数が受信リクエストのヘッダーから取得され、その後、下の Runtime.getRumtime.exec() ステートメントに追加され、MD5 の 16 進コード形式でエンコードおよびデコードされます。OBIEE システムに送信された後、デシリアライズされた値が返されます。
最後に、Main 関数で RemoteConstructor オブジェクトが作成され、SerializationUtils ライブラリを通じて URL エンコードされた文字列に変換されます。この文字列はソース URL に直接渡されるため、攻撃者は任意の __cmd__ コマンドを挿入する機会を得ます。

## エクスプロイトの再現


## 参照
1. https://peterjson.medium.com/miracle-one-vulnerability-to-rule-them-all-c3aed9edeea2
2. https://testbnull.medium.com/oracle-access-manager-pre-auth-rce-cve-2021-35587-analysis-1302a4542316
## 脆弱性の作者: Jang Nguyen & Duc PeterJson