[月次配信] Oracle WebLogic RCE脆弱性(CVE-2019-2890)の分析及び対応方法

#概要
Oracle社が提供しているOracle Fusion MiddlewareのWebLogic Serverから逆直列化(Deserialization)を迂回し、特定の権限で悪意的なT3プロトコルの要請を通じてリモートコマンドが実行できる脆弱性(CVE-2019-2890)が発見された。脆弱性はWebLogic Severがデータを受信する際にバイナリタイプに変換されたデータを元のタイプに変換する逆直列化の過程で入力値の有効性検証が不足しているため発生する。
CVEリストには2019年10月16日に公開され、同月にOracleの緊急パッチアップデートのリストに含まれ、セキュリティパッチが完了された。
今回はこの脆弱性の動作仕組み及び分析、対処について紹介する。

#脆弱性分析
##影響を受けるソフトウェア

|      CVE      |                   脆弱バージョン                   | 危険度 |
|:-------------:|:--------------------------------------------------:|--------|
| CVE-2019-2890 | WebLogic Server 10.3.6.0.0, 12.1.3.0.0, 12.2.1.3.0 | High   |

##CVE-2019-2890脆弱性のメカニズム
 
WebLogicのコンソールを実行するとRMI(Remote Method Invocation)通信の際に使用されるT3プロトコルがDefault Port 7001で通常有効化され、T3プロトコルを介してWebLogic SeverとClientの間にデート送信が可能になる。CVE-2019-2890はT3プロトコルを利用して改ざんされたコマンドをサーバに送信後、JAVAプログラムで各オブジェクの間、パソコンの間にメソッドを呼び出されるようにする技術であるRMI(Remote Method Invocation)通信を通じてリモートで任意のコマンドを送信して実行される脆弱性である。

T3プロトコルはデータを安全に送信するためにデータをバイナリタイプで返還する直列化(Serialization)を実施し、デートを受信した場合、バイナリタイプに変換されたデータを元のデータに変換する逆直列化(Deserialization)を実施する。脆弱性が発生される時点は逆直列化過程で入力されたデータの検証不足で発生する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570011/bd6579a8-9c7e-bbf6-3ec0-7adb2ad38d8d.png)
【▲ CVE-2019-2890攻撃シナリオ】

##CVE-2019-2890脆弱性の詳細分析
CVE-2019-2890の逆直列化の脆弱性を理解するためにはWebLogic Serverの直列化の過程に対しての理解が必要である。WebLogic Serverのちょくるつかはweblogic.jarファイル内の「weblogic.wsee.jaxws.persistence.PersistentContext.class」で具現される。

WebLogic Serverから直列化をするために下記のソースコードのようにwriteSubjectメソッド内に「EncryptionUtil.encrypt()」を利用して暗号化が実施される。この際に、暗号化・復号化に利用するキーを管理するファイルである「SerializedSystemIni.dat」を利用する。そのため、CVE-2019-2809は「認証が必要な脆弱性」とOracleは分類した。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570011/a1e26a1d-f929-f7be-9691-3b22462e251f.png)
【▲ Oracle公式発表資料 - 認証が必要な脆弱性 CVE-2019-2890】

```java
private void writeSubject (ObjectOutputStream var1) throws IOException(
    ByteArrayOutputStream var2 = new ByteArrayOutputStream();
    ObjectOutputStream var3 = new ObjectOutputStream(var2);
/*直列化開始*/
    if (Subjectmanager.getSubjectManager().isKernelIdentity(this._subject)) {
        AuthenticatedSubject var4 = (AuthenticatedSubject)SubjectManager.
        getSubjectManager().getAnonymousSubject();
        var3.writeObject(var4);
    } else {
        var3.writeObject(this._subject);
    }
/*直列化終了*/
    var3.flush();
    byte[] var5 = var2.toByteArray();
/*暗号化開始*/
    if (KernelStatus.isServer()) {
        var5 = EncryptionUtil.encrypt(var5);
    }
    var 5 = EncryptionUtil.encrypt(var5);
/*暗号化終了*/
    var1.writeInt(var5.length);
    var1.write(var5);
}
```

WriteSubjectメソッドから作成された直列化コードはT3プロトコルを通じてWebLogic Serveに送信され、readobjectメソッドを利用して逆直列化過程を行い、任意のコマンドが実行できるようになる。

````java
private void ReadSubject (ObjectInputStream var1) {
    try {
        /*データの読み込み+復号化開始*/
        int var2 = vaf1.readInt();
        byte[] var3 = new byte[var2];
        var1.readFully(var3);
        if (KernelStatus.isServer()) {
            var3 = EncryptionUtil.Decrypt(var3);
        }
        /*データの読み込み+復号化終了*/
        /*逆直列化開始*/
        ByteArrayInputStream var4 = new ByteArrayInputStream(var3);
        ObjectInputStream var5 = new ObjectInputStream(var4);
        this._subject = (AuthenticatedSubject)var5.readObject();
        /*逆直列化終了*/
    } catech (Exception var6) {
        WseeCoreLogger.logUnexpectedException("Couldn't completely read PersistentContext subject", var6);
    }

}
````
##PoC分析

前述したようにPoCを実行するとT3サービスと通信後、リモートコマンド実行の通路となるRMI Connectionポートをオープンする内容のペイロードを送信する。当該のペイロードはRMI関連クラスを参照し、作成しており、サーバ側のRMIオブジェクトを起動後、RemoteObjectInvocationHandlerを直列化し、UnicasfRefを使用してリモートendとTCP連携の設定を含んでいる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570011/b38640f2-28ec-4c1f-2d94-80045c28e988.png)
【▲ RMI Connectionポートをオープンするためのペイロード】

|                                               |                                                                                                    |
|:---------------------------------------------:|:--------------------------------------------------------------------------------------------------:|
|                     Class                     |                                                説明                                                |
|              java.rmi.activation              |                                   RMIオブジェクトの起動をサポート                                  |
|            java.lang.reflect.Proxy            |                          動的プロキシクラスを作るための静的メソッドを提供                          |
|      java/lang/reflect/InvocationHandler      |              Javaリモートメソッドの呼び出し(Java RMI)として使用されるインターフェース              |
| java.rmi.server.RemoteObjectInvocationHandler |    Javaリモートメソッドの呼び出し(Java RMI)として使用されるInvocationHandlerインターフェース具現   |
|          java.rmi.server.RemoteObject         | リモートオブジェクトをJRMPを使用てしてexportし、リモートオブジェクトと通信するStubを獲得ために使用 |
|                   UnicastRef                  |                              相手のIPアドレスを送信先とする1:1通信方式                             |

##CVE-2019-2890攻撃テスト

分析及びテストのための環境情報は下記になる。

|        Attacker        |                        Victim                       |
|:----------------------:|:---------------------------------------------------:|
| Windows 10192.168.0.97 | Windows 7 (WebLogic 10.3.6.0)192.168.116.138 : 7001 |

①AttaekrはREC攻撃のためにYsoserialのJRMPListenrライブラリを利用してRMI Connectionポート(1099)をオープンする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570011/6b406bb1-466e-1a76-60cc-493d4accf39d.png)

②PoCからはT3プロトコルを利用し、ソケット通信を通じてWebLogic ServerのRMI Connectionポートをオープンするペイロードを送信する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570011/4ddc1b9e-d42a-7927-2adc-a82889620753.png)

T3プロトコルの接続に成功するとWebLogic ServerのRMI Connectionに使用されるペイロードに含まれているConstantTransformer, InvokerTransformerなどの送信履歴を下記のようにネットワークパケットで確認できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570011/7c9af191-4dd4-047e-8b69-3948e8e742ac.png)

③RMI Connectionポート(1099)を通じてリモートコマンドの実行のためにペイロードを送信する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570011/3ab75391-6337-73eb-4e20-5647884995de.png)

④リモートコマンドの実行確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570011/9b9371f3-2ffc-1bcb-6b1a-3bbbdffd701e.png)

Attakerが入力した攻撃のペイロードでRMI Connectionの逆直列化が成功するとWebLogic Server側のRMI Connectionポートがオープンされる。JVMに存在するオブジェクトが他のJVMないでどう朝するオブジェクトのメソッドを呼び出せるJRMP(Java Remote method Protocol)を利用してAttackerに応答コードを送信することでAttakerがVictimに任意のリモートコマンド送信ができるようになる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570011/7584e51d-4452-4ebd-bbc3-10da983b5519.png)

#対応方法
##WebLogicのセキュリティパッチ適用
|      脆弱バージョン      |  安定バージョン(最新バージョン) |
|:------------------------:|:-------------------------------:|
| WebLogic Server 10.3.6.0 | WebLogic Server 10.3.6.0.191015 |
| WebLogic Server 12.1.3.0 | WebLogic Server 12.1.3.0.191015 |
| WebLogic Server 12.2.1.3 |     WebLogic Server 12.2.1.4    |

WebLogic Serverの12.1.1.0以下のバージョンの場合、「bsu, print version」コマンド及び、「WebLogic Server」のAdmin Console画面からバージョンの確認ができる。

脆弱性パッチ前・後ソースコードを確認してみると「readSubject」メソッドに問題になった逆直列化コードが「WSFilteringObjectInputStream」メソッドを利用して検証されていることが確認できる。当該のメソッドは逆直列化するオブジェクトがsubjectのサブクラスであるかを検証し、違う場合、エラーを出した後、逆直列化過程を終了させる。

```java
ByteArrayInputStream var4 = new ByteArrayInputStream(var3);
ObjectInputStream var5 = new ObjectInputstream(var4);
this._subject = (Authenticatedsubject)var5.readObject();
```
【▲ BEFORE (WebLogic Server 10.3.6.0)】

```java
ByteArrayInputStream var4 = new ByteArrayInputStream(var3);
ObjectInputStream var5 = new PersistenctContext.WSFileteringObjectInputStream(var4);
this._subject = (Authenticatedsubject)var5.readObject()
```
【▲ AFTER (WebLogic Server 10.3.6.0.191015)】

##T3プロトコルの無効化
Oracle WebLogicはHTTP通信を除いた全てのコネクションにT3プロトコルを使用するため、システムの影響度が高いが、臨時的にT3プロトコルを無効化して対応可能(システムへの影響も必ず確認)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570011/32625a52-9159-da2a-0cb4-a73460456090.png)
1) WebLogicコンソール起動
2) Base_domain構成ページから「Security」タブの「Filter」をクリックしてフィルタを構成
　- Connection Filter項目：weblogic.security.net.ConnectionFilterlmpl
　- Connection Filter rules項目：127.0.0.1 ** allow t3 t3s, 0.0.0.0/0 * * deny t3 t3s
3)保存(再起動は不要)

#まとめ
今回はOracle WebLogic RCE脆弱性(CVE-2019-2890)ついて調べてみた。
2019年、つい最近に公開された脆弱性であり、Oracleのデータベースは品番に使われているため、この分析レポートを参考し、適切な対処を行うことを推奨する。

#参考資料
[1] Oracle WebLogic Serverリモートコマンド実効セキュリティアップデート勧告(2019.12.09.)
https://www.boho.or.kr/data/secNoticeView.do?bulletin_writing_sequence=35222
https://www.oracle.com/security-alerts/cpuoct2019.html
[2] CVE-2019-2890 PoC
https://github.com/ZO1RO/CVE-2019-2890
https://github.com/SukaraLin/CVE-2019-2890
[3] WebLogic RCE (CVE-2019-2890) Debug Diary
https://paper.seebug.org/1069/
[4] WebLogic t3逆直列化脆弱性(CVE-2019-2890)分析
http://gv7.me/articles/2019/cve-2019-2890-vulnerability-analysis/
[5] 安全ではないJavaオブジェクトdeserializationを利用したペイロードを作成するための概念証明ツール
https://github.com/frohoff/ysoserial
[6] JAVAメソッドのまとめ
http://cris.joongbu.ac.kr/course/java/api/java/rmi/activation/Activator.html
http://cris.joongbu.ac.kr/course/2018-1/jcp/api/java/rmi/server/class-use/RemoteObject.html
[7] Oracle最新バージョン
https://blogs.oracle.com/fusionmiddlewaresupport/october-2019-oracle-weblogic-server-patch-set-update-have-been-released