Drupal の脆弱性 (CVE-2019-6340) に関して検証してみた

どうも、Drupalを一回も運用したことがないのに、インストールするのがどんどん早くなっていく、とある診断員です。 今回は先日PoCが公開されたDrupal脆弱性 (CVE-2019-6340) に関してちょこっと検証してみました。 折角なので検証した内容についてブログに記載をしておきます。

脆弱性に関する情報

脆弱性の種類

RCE(Remote Code Execution)です。リモートの攻撃者よりWebサーバの動作権限にて任意のコードを実行されてしまう危険性があります。

脆弱性の影響を受けるバージョン

  • Drupal 8.6.10 より前の 8.6 系のバージョン
  • Drupal 8.5.11 より前の 8.5 系のバージョン

脆弱性の影響を受ける条件

以下のようなREST API を利用するモジュールが有効になっている場合、影響を受けます。

  • RESTful Web Servicesモジュール
  • JSON:APIモジュール

上記モジュールについてはデフォルトでは無効です。 なお、Drupal 7系でも同様のモジュールが有効になっている場合は本脆弱性の影響を受けるようです。 また、Drupal 8.5 系より前の 8系のバージョンは、サポートが終了しており、今回のセキュリティに関する情報は提供されていません。

脆弱性の対策

脆弱性が対策されたバージョンへのアップグレード

また、該当モジュールの無効化でも対応可能です。

脆弱性が存在する原因

今回の脆弱性については以下Ambionics Security社のブログにて詳細が解説されています。

Exploiting Drupal8's REST RCE

上記ブログに書いてある通り、今回の脆弱性はOWASP Top 10 2017にもランクインしたいわゆる「安全ではないデシリアライゼーション」の問題に起因するものです。 「安全ではないデシリアライゼーション」については徳丸さんの以下の記事が参考になります。

安全でないデシリアライゼーション(Insecure Deserialization)入門 | 徳丸浩の日記

今回の脆弱性は、REST API経由にてJSON形式で定義された値にシリアライズ化されたデータを指定して送信した場合に、その値がそのままデシリアライズされてしまうこと利用して、任意のコードを実行するというものです。また、上記ブログにて記載している通り、当初はDrupal本家のSecurity advisoriesでは攻撃は「POST」や「PATCH」メソッド経由であるため、該当メソッドのリクエストを受け付けないようにすることが緩和策である旨の記載がされていましたが、それだけではなく、「GET」リクエストでも本攻撃は成立します。

参考サイト

https://www.drupal.org/sa-core-2019-003

https://www.drupal.org/psa-2019-02-22

Drupal の脆弱性 (CVE-2019-6340) に関する注意喚起

脆弱性の検証について

とりあえずPoCを試したり、攻撃リクエストなどを速攻確認したい場合には@knqyf263さんが公開してくれている素晴らしいdockerイメージがあるのでこちらを利用するのが良いと思います。

GitHub - knqyf263/CVE-2019-6340: Environment for CVE-2019-6340 (Drupal)

PoCの詳細はここには書きませんがcurlコマンドのみでお手軽に実行が可能です。 なお、自分でも環境を構築いたしましたが、今回の検証は現在のPoCが対応している8系にて実施しました。

環境構築について

脆弱性の影響を受けるバージョンのDrupalをインストール後、以下のモジュールを有効にする必要があります。

  • HAL
  • REST UI
  • RESTful Web Services
  • Serialization

f:id:tigerszk:20190228014712j:plain
モジュールのインストール

この内、REST UI モジュールはコアに組み込まれていない為、別途ダウンロードする必要があります。 モジュールを有効化すると、環境設定のウェブサービスに「REST」という項目が現れます。 そこから、「コンテンツ」の項目を有効にし、以下のように設定すればOKです。

f:id:tigerszk:20190228014324j:plain
RESTリソースの設定

なお、こちらの解説が参考になります。

RESTful Web Services と REST UIで始めるDrupal8 REST API入門 | Drupal専門の開発会社 Studio Umi

また、検証にはdrupal上のノードが必要なため、適当なコンテンツを追加する必要があります。

f:id:tigerszk:20190228015634j:plain
適当なコンテンツを追加しておく

PoCの実行結果

結論から言えば、手元でも以下のように、curlコマンドを利用してPoCを打ち込んだ所、任意のコマンドが実行されることを確認しています。以下はPoCにてidコマンドを実行した結果となります。

f:id:tigerszk:20190228015122j:plain
PoCの実行結果

現在のPoCを試していくつか分かったこととしては、GETリクエストでの実行では一度打ち込むとキャッシュに残ってしまうため連続で実行ができません(キャッシュをクリアすれば再度成功することは確認しています)。 POSTメソッドやPATCHメソッドで実行した場合には連続で試行できます。

デバッガでの解析

PoCの実行をデバッガを利用して解析した結果、以下のようにPoCにて送信したシリアライズ化された値が、LinkItem.phpのunserializeメソッドに渡っており、デシリアライズされたことが分かります。

f:id:tigerszk:20190228020846j:plain
PoCのデータがデシリアライズされている

PoCに含まれているシリアライズ化された値は、Ambionics Security社のブログにて書かれていますが、Drupal 8が内部にて利用しているGuzzleというHTTPクライアントライブラリを利 用して任意のコードを実行するものとなります。Guzzleのdestructor処理にて恐らくガジェットチェーンを利用して任意のコードを実行していると思われます。

f:id:tigerszk:20190228021022j:plain
guzzleのdestract処理が実行されている

対策済みバージョンでは?

脆弱性が対策済みである8.6.10で検証してみた結果、PoCを実行すると以下のような応答となり、コードが実行されないことを確認しています。

f:id:tigerszk:20190228023917j:plain
応答結果

デバッガで追跡した結果、対策として追加されたcheckForSerializedStringsメソッドに値が渡され、例外が発生していることがわかります。

f:id:tigerszk:20190228024515j:plain
checkForSerializedStringsメソッドに値が渡っている

所感

まず、今回の脆弱性は、前提条件としてデフォルトでは無効となっているモジュールが有効である環境のみが影響を受けるため、個人的にはDrupalgeddon 2(CVE-2018-7600)などよりかはまだマシなほうなのかなという印象を受けています。ただし、条件がそろってしまえば攻撃の実行は非常に簡単であり、危険度の高い脆弱性ではあることは間違いないので、注意が必要です。 また、単純に外部から受け渡された値を検証なしにデシリアライズしていることが問題であるため、「安全ではないデシリアライゼーション」の結構良い事例となるような脆弱性なのではないかと思いました。

PS

Ambionics Security社のブログに、記載しているシリアライズ化されたペイロードはPHPGGCというツールを利用して作成している旨がと書かれています。 このツールは指定したライブラリに対応したデシリアライズ処理を悪用するPHP用の攻撃ペイロードを自動生成してくれるもののようで、非常に面白そうなので、その内時間を見つけて調べてみようかなと思っています。

GitHub - ambionics/phpggc