実際の悪用が確認されているvBulletinの事前認証リモートコード実行(RCE)脆弱性CVE-2020-17496のエクスプロイト

This image illustrates the concept of a vulnerability.

This post is also available in: English (英語)

概要

2019年9月に、人気フォーラムソフトウェアvBulletinに見つかったリモートコード実行(RCE)脆弱性CVE-2019-16759が公表されました。当時のUnit 42のリサーチャーは当該vBulletin脆弱性に関するブログ記事を公開し、脆弱性の根本的要因と実際にインターネット上で見つかったエクスプロイトについて分析しました。この脆弱性が悪用されると、バージョン5.0.0から5.5.4までのvBulletinをを実行しているサーバーで攻撃者に特権アクセスと制御を取得され、組織が自社サイトから締め出されてしまう可能性があります。

最近、Unit 42のリサーチャーは、vBulletinの事前認証リモートコード実行(RCE)脆弱性CVE-2020-17496を利用したエクスプロイトを発見しました。当該のエクスプロイトは、以前の脆弱性CVE-2019-16759の修正を回避するもので、攻撃者が指定されたテンプレート名と悪意のあるPHPコードを使い、巧妙に細工したHTTPリクエストを送信することで、リモートからコードを実行できる可能性があります。著名企業・組織のフォーラムを含め10万件以上のサイトがvBulletinベースで構築されていることから、ただちにパッチを適用することが不可欠です。

本稿では、同脆弱性のパッチ回避に関する詳細、脆弱性を実証する概念実証コード(PoC)、実際に確認されている攻撃に関する情報を提供します。

パロアルトネットワークス製品をご利用中のお客様は、脅威防御のシグネチャと関連C2トラフィックをブロックするURLフィルタリングの各サービス、製品により保護されています。

脆弱性の根本原因分析(CVE-2020-17496)

テンプレート レンダリングは、XMLテンプレートをPHPコードに変換して実行できるようにするvBulletinの機能で、バージョン5.0以降のvBulletinは、このテンプレートレンダリングとしてAjaxリクエストを受け入れるようになりました。レンダリングを行うのはstaticRenderAjaxという関数で、図1に示すように、staticRenderAjax関数のパラメータの値は$_REQUESTS$_GET$_POSTとなっています。したがって、これらのパラメータから取得されたテンプレート名と、関連の設定内容はユーザーの制御下にあります。これがリモートコード実行脆弱性CVE-2019-16759につながります。

staticRenderAjax関数の値とパラメータは、赤い矢印で示すように、$_ REQUESTS、$_ GET、$_POSTからのものです。
図 1 vBulletin 5.5.5 未満の callRender()

ここで攻撃者がテンプレート名widget_phpを含むAjaxリクエストに細工をし、 widgetConfig['code'] パラメータ内に悪意のあるコードを配置した場合、レンダリング エンジンはそのwidget_php XMLテンプレートをPHPコードの文字列に変換します(図2参照)。その後変換されたコードはeval関数(図3にハイライト表示)を介して実行されます。生成されたコードには vB5_Template_Runtime::evalPhp(" . $widgetConfig['code'] . ") という行があることから、これでリクエスト内の悪意のあるコードが実行されてしまうことになります。

テンプレート名widget_phpとパラメータwidgetConfig ['code']に配置された悪意のあるコードを含むAjaxリクエストを攻撃者が操作すると、レンダリングエンジンはXMLテンプレートwidget_phpをPHPコードの文字列に変換します。
図 2 widget_phpテンプレート

 

赤いボックスで関数eval($templateCode)をハイライト表示しています
図 3 XMLテンプレートからレンダリングされたPHPコードをeval関数で評価している

バージョン5.5.5以降、CVE-2019-16759の修正がcallRender()関数に導入されました(図4参照)。この修正ではテンプレート名をチェックするのに禁止リストのしくみを利用していて、名前がwidget_phpであればXMLエンジンはリクエストされたテンプレートをレンダリングしません。

バージョン5.5.5以降、CVE-2019-16759の修正が<s0>callRender()</s0>関数に導入されました(図4参照)。
図 4 vBulletin 5.5.5 以降の callRender()

これとは別の修正もあり、そちらの修正ではevalPhp関数が現在のテンプレート名をチェックするようにしています。こちらの修正で、widget_phpがPHPコード実行に使用できる唯一のテンプレートになりました(図5参照)。

赤いボックス内のコードは、if (self::currentTemplate() != 'widget_php') を評価することでevalPhp関数が現在のテンプレート名をチェックしているようすを示しています。
図 5 evalPhp() がコードを実行するのはテンプレートが widget_php の場合のみ

先のwidget_phpテンプレートへのユーザーアクセス制限にくわえ、この修正では同テンプレートをPHPコード実行に利用できる唯一のテンプレートにしています。ところが、直近で見つかった修正回避方法では、別のテンプレートを使用すればこのwidget_phpテンプレートをロードできてしまうことがわかりました。その別のテンプレートというのがwidget_tabbedcontainer_tab_panelです。

This shows code from the template widget_tabbedcontainer_tab_panel, which can be utilitzed to load widget_php
図 6 widget_tabbedcontainer_tab_panel テンプレート

上の図6に示すテンプレートwidget_tabbedcontainer_tab_panelを使えば、複数の子テンプレートをレンダリングすることができます。テンプレート自体をレンダリングしても直接リモートコード実行につながるわけではありませんが、このテンプレートをレンダリングすると、子テンプレートのレンダリングがトリガーされます。

以下のコードはXML内のwidget_tabbedcontainer_tab_panelテンプレートからレンダリングされたPHPコードです。コードは生成後に実行されます。

このPHPコードでは、レンダリングエンジンが$subWidgetsから「subWidget」とその設定をトラバースして新しいテンプレートオブジェクトを作成します。その後、レンダリングによりPHPコードが生成されます。この例では文字列widget_phpsubWidget変数に割り当てられ、悪意のあるコードが $widgetConfig['code'] に配置されていて、これがCVE-2019-16759と同様に実行されます。

PoC(概念実証コード)

以上の分析から、実際に機能することを証明するエクスプロイト コードを作成できます。callRender関数の呼び出しには、POST HTTPメソッドが必要です(図7参照)。

赤いボックスで強調表示されているコードは、関数callRenderを呼び出すためにPOST HTTPメソッドがどのように必要かを示しています。これはCVE-2020-17496のエクスプロイトの概念実証の一部です。
図 7 callRender()の呼び出し

図8はphpinfo()コードの実行結果を含む侵害されたページを示しています(リクエスト情報あり)。図9と図10もそれとはまた別の細工済みリクエストを実行した場合に同じ効果が得られることを示しています。

URLでは、子テンプレート名widget_phpと悪意のあるコード phpinfo();exit(); は配列subWidgetの最初の要素として存在しています。バックエンドがこのURLを処理すると悪意のあるコードが実行されます。

この侵害されたページは、CVE-2020-17496のエクスプロイトの概念実証の一部で、phpinfo()コードの結果が含まれています(リクエスト情報付き)。
図 8 エクスプロイトの再現検証 1
これも、CVE-2020-17496のエクスプロイトの概念実証の一部で、また別の細工されたリクエストを示しています。
図 9 エクスプロイトの再現検証 2
これは、CVE-2020-17496のエクスプロイトの概念実証の一部で、3番目の細工されたリクエストを示しています。
図 10. エクスプロイトの再現検証 3

実際に確認されているCVE-2020-17496のエクスプロイト

私たちは2020年8月10日にCVE-2020-17496をエクスプロイトする最初のインシデントを検出しました。その後も異なるIPアドレスからのエクスプロイトの試みが進行中であることが確認されています。ただしこれらはそれぞれ別個の攻撃であって特定攻撃者による協調的取り組みではない点にご注意ください。

スキャン活動

私たちがキャプチャした悪意のあるトラフィックからは、スキャン活動を行うソースが複数あることがわかっています。これらのスキャンは、脆弱なサイトを見つけて関連情報を収集しようとしており、サイバー攻撃の初期段階にあたります。そのトラフィックを図11から図15に示します。これらのペイロードは、システムコマンドのechoidを実行しようとします。これらコマンドの結果から攻撃者はターゲットが脆弱かどうかを知ることができます。

これは、CVE-2020-17496のエクスプロイトに関連した悪意のあるトラフィックのサンプルです。私たちがキャプチャしたトラフィックからは、スキャンを実行しているソースIPが複数確認されました。これらの活動では、脆弱なサイトを見つけ、それらサイトに関する情報を収集しようとしています。
図 11 実際に確認されたエクスプロイト 1
これは、CVE-2020-17496のエクスプロイトに関連した悪意のあるトラフィックの2番目のサンプルです。私たちがキャプチャしたトラフィックからは、スキャンを実行しているソースIPが複数確認されました。これらの活動では、脆弱なサイトを見つけ、それらサイトに関する情報を収集しようとしています。
図 12. 実際に確認されたエクスプロイト 2
これは、CVE-2020-17496のエクスプロイトに関連した悪意のあるトラフィックの3番目のサンプルです。私たちがキャプチャしたトラフィックからは、スキャンを実行しているソースIPが複数確認されました。これらの活動では、脆弱なサイトを見つけ、それらサイトに関する情報を収集しようとしています。
図 13 実際に確認されたエクスプロイト 3
これは、CVE-2020-17496のエクスプロイトに関連した悪意のあるトラフィックの4番目のサンプルです。私たちがキャプチャしたトラフィックからは、スキャンを実行しているソースIPが複数確認されました。これらの活動では、脆弱なサイトを見つけ、それらサイトに関する情報を収集しようとしています。
図 14 実際に確認されたエクスプロイト 4

機微なファイルの読み取り

一部の攻撃者は、この脆弱性を悪用してサーバー側のファイルを読み取ろうとします。このペイロードにはPHP関数shell_exec()が含まれていて、これが任意のシステムコマンドを実行します。システムコマンド cat ../../../../../../../../../../etc/passwd は/etc/passwdの内容を読み取ります。このトラフィックを図15に示します。攻撃が成功すると、ターゲットからの機密情報が漏えいする可能性があります。

このCVE-2020-17496のエクスプロイト関連の悪意のあるトラフィックのサンプルは、システムコマンド実行用のPHP関数shell_exec()を含むペイロードを示しています。
図 15 実際に確認されたエクスプロイト 5

Webシェルの作成

一部の攻撃者はこの脆弱性を悪用してWebシェルをインストールします。

図16は、PHP関数file_put_content()を使い、webホストディレクトリ上のファイル、conf.php内に、エクスプロイトがPHPベースのWebシェルを作成しようとしている様子を示しています。攻撃が成功すると、攻撃者はパラメータxを指定したHTTP POSTリクエストを介してコマンドをWebシェルに送信し、サーバーサイドでコマンドを実行することができます。

これは、エクスプロイトがPHPベースのWebシェルをWebホストディレクトリのconf.phpファイルに書き込もうとしている様子を示しています。攻撃が成功すると、攻撃者はパラメータxを指定したHTTP POSTリクエストを介してコマンドをWebシェルに送信し、サーバーサイドでコマンドを実行することができます。
図 16 実際に確認されたエクスプロイト 6

図17は、エクスプロイトが被害者のサーバーにPHPスクリプトをダウンロードしようとしている様子を示しています。webシェルコードは以下のとおりで、このコードによりアップロード用ページが提供されます。これを使って攻撃者はファイルをアップロードし、サイバー攻撃のフォローアップ処理を実行できます。

 

これはCVE-2020-17496のエクスプロイトが被害者のサーバーにPHPスクリプトをダウンロードしようとする様子を示しています。
図 17 実際に確認されたエクスプロイト 7

図18は、エクスプロイトがbase64でエンコードされたPHPコードをWebホストディレクトリのファイルに書き込もうとしている様子を示しています。この新しいページが任意のファイルをアップロードする入口となり、攻撃者がサイバー攻撃のフォローアップ処理を実行できるようにします。

これは、CVE-2020-17496のエクスプロイトがbase64エンコードされたPHPコードをWebホストディレクトリのファイルに書き込もうとしている様子を示しています。
図 18 実際に確認されたエクスプロイト 8

Shellbotのダウンロード

一部の攻撃者はこの脆弱性を利用してPHP関数shell_exec()でシステムコマンドwgetを実行し、 http://178[.]170[.]117[.]50/bot1 というアドレスからPerlベースのスクリプト マルウェア(Shellbot)をダウンロードして実行しています。そのペイロードを図19に示します。

これは、CVE-2020-17496のエクスプロイトのペイロードを示しています
図 19 実際に確認されたエクスプロイト 9

スクリプトが実行されると、66[.]7[.]149[.]161:6667というアドレスでIRCベースのコマンド&コントロール(C2)サーバーに接続し、IRCチャネル#afkに参加して、サーバーからのPINGに応答し続けます(図20のトラフィックを参照)。チャットチャネルからコマンドを受信すると、ポートスキャンの関連コードの実行、ファイルのダウンロード、システムコマンドの実行、フラッド攻撃の開始、攻撃者へのシェルの提供などを行います。

前図の悪意のあるスクリプトが実行されると、IRCベースのコマンド&コントロールサーバーに接続し、IRCチャネル#afkに参加し、サーバーからのPINGに応答します(トラフィック参照)。
図 20 ShellBotスクリプト実行中のトラフィック

Soraのダウンロード

あるエクスプロイトは、攻撃者のサーバーからMiraiの亜種(Sora)をダウンロードすることが判明しています。ただしこのペイロードは間違ったHTTPメソッドを使用しているため無効です。

このCVE-2020-17496のエクスプロイトは、攻撃者のサーバーからMiraiの亜種(Sora)をダウンロードしようとします。
図 21 実際に確認されたエクスプロイト 10

これらのサンプルを分析した結果、これらはさまざまなエクスプロイトを組み合わせて拡散していることがわかりました。たとえばCVE-2020-5902(この場合のペイロードはbashコマンドを使用しているので無効。このエクスプロイトは挿入されるコマンドが特定CLI互換コマンドでなければならない)、CVE-2020-1937CVE-2020-10173CVE-2020-10987、Netgear R700のリモートコード実行脆弱性、Netlink GPONルーター1.0.11のリモートコード実行脆弱性、そして本稿で説明した脆弱性CVE-2020-17496などです。

結論

弊社の脅威プラットフォームでは、vBulletinの事前認証リモートコード実行脆弱性CVE-2020-17496に対するさまざまなエクスプロイトの試みが検出されています。vBulletinはマーケットで長年実行され、利用者数の多いフォーラムソフトウェアパッケージであることから、攻撃者にとって貴重なターゲットと認識されています。

vBulletinは、2020年8月10日のパッチで本脆弱性を修正済みです。最新バージョンにあげることでリスクは軽減されますので、ぜひ本パッチを適用することを強くお勧めします。

パロアルトネットワークス製品をご利用中のお客様は、次の各サービス、製品によってこの脅威から保護されています。

追加資料

IoC

Shellbotのハッシュ値

  • 88DDD8A1B77477AAFFD1BB163B9770D72A77BF29BFCA226E79C28D15BEF983ED

Mirai 亜種 (Sora) のハッシュ値

  • 03bfec4e039805091fe30fa978d5ec7f28431bb0fca4b137e075257b3e1c0dd4
  • b4cb04709f613b5363514e75984084ef1d3eaba7c50638b2a5a284680831b992
  • 94f02ea10b4546da71bd46916f0fe260b40c8ed4deccf0588687e62ca3819ad7
  • bd72be4f7d64795b902f352e47b1654eaee6b5a71cddfaf2c245dba1b2d602eb
  • 77b4f7f0d66a0333d756116eaae567a8540392f558c49d507bf6da10bd047fe3
  • 051baaabf205c7c0f5fd455ac5775447f9f3df0cc9bc5f66f6d386f368520581
  • fd63b9c7e9dce51348d9600f67139ea8959fdbbca84d505b5e9317bbdca74016
  • 8b5810e07cf21ebb1c2ff23c13ce88022c1dd5bc2df32f4d7e5480b4ddb82de2
  • ded23c3f5f2950257d8cfb215c40d5f54b28fde23c02f61ce1eb746843f43397
  • 80fb66c6b1191954c31734355a236b7342dc3fd074ead47f9c1ed465561c6e8c
  • f30bb52c0e32dfe524fc0dfda1724a1ffb88647c39c33a66dfd66109fecceec7
  • 1900e09983acf7ddc658b860be7875a527bc914cbffcf0aaff0b4182ecef047b
  • fa7575bd0cd2a83995ea34d8d008eb07c2062a843e5e155e2e0d8b35a0cf7901
  • 68132010d9a543a6a2a9ea61e771cf2c041cea259cc76affdfe663e20c130a45
  • ab671fc0c68ed1c249c2bb52b28ae3d70df8bd1614d86f6d6a3f4c21d7841d72
  • 4ff21e69b11566336f4fd56ac2829cdcf215182e8ff807f8e744c0a2b08f726f
  • a7373fa18b367edbcd4462345a5da087821e34734bdf05d1c4060a7694868c5e
  • dec56b06e03665d2c656b530d3b6f90ca0ec2925bec4559d8a2cec5da3a7700b
  • c379139347470254f19041f05e19f5454750e052f04f6d377ec8df19ce959519
  • fed0f0d3e9d990f8a83b86d29e586d46e7cac54efb0eae2f07112d61afb9b885
  • 84448ee487010d6fed918febe230b71a8ec1266e300f85933014db2566645857
  • 994889422b24a5b4759eda30265f1b933a458e15927b4f7949d4a3ba79eb43ca
  • 39b6d72101adae2b71815328599f8e67ee27955849dfb3825c5b2731d504696b
  • 0747988a77c89c1267a882b663fbd4168e25aed239fb1553e65bb4ac74ecda67
  • 99d06d1c82af244b1533c1173ca10da7f29bfbf753073f20f5dc7a0016152a4c
  • 372ab5c1c23d198b594353239a96d6cf620cc56588f5fdf5dfb32919dd019020
  • ef2a6b37568e14dacd5d8894ce2e4bbc593ffd58e197827a052d2c2f0a756949
  • 1cf9ac9150d59de25ca5ac1f855fadf1b03f13b4e9ced63a12acef9c8292a648
  • cf172b4629e321e4c78a1d0717130bbb693392712a86d3d85d035bae1f377dbd
  • 1a0293d4863ccef36e138e4f6c65ad013a403db0ffc69ebaf04b43b61b4ba798
  • 2a14b9b01ec78a332be40339a782a2cf2bf9a237eee9cc5fcd40fa3385b1d4fb
  • f56150ff764328ee59eeaafe5e2d63574b475a69386c9ac4978006070807edc9
  • 9572a532c08f81d7957ffd4639f95c34a2085f119fa426d8ea911af72bfd0b4a
  • 113ad91a1aab3abcd704fe8670fbc043f049586462a4c58dabdd44c14519ea66
  • f9d7d9b11c60bd52625e7d9a33516c2bac96ac542a22696d0da3a9c536dae11b
  • 6f01ef6670ecd79f9b322dd8521bc13a73037e7f84fa9aad35d11d964d8f9e60
  • 2960748648bc2cd1b3db5e1e1ce9931a6588d65ae91c6d09e6b8bf2d78b00263

IPアドレス

  • 66[.]7[.]149[.]161
  • 178[.]170[.]117[.]50