
Drupalgeddon2 (CVE-2018-7600) PoCのCLI書き換え — 許可されたテスト/教育用
Drupalgeddon2 (CVE-2018-7600) の概念実証をコマンドラインから再実装したものです。Hack The Box Academy の Attacking Common Applications モジュールに取り組む中で、学習演習として作成しました。
[!WARNING] 許可されたセキュリティテストおよび教育のみを目的としています。 自身が所有していない、または明示的な書面による許可を得ていないシステムに対して実行することは、多くの法域で違法です。詳細は 法的利用と責任 を参照してください。
[!NOTE] AI 支援を受けて作成されました。 詳細は 著者についての注記 を参照してください。
Drupal は HTB Academy の Attacking Common Applications モジュールで取り上げられる「一般的なアプリケーション」の一つであり、CVE-2018-7600(「Drupalgeddon2」)はその代表的な未認証RCEの例です。私はワンショットスクリプトをコピーペーストして次に進むのではなく、このバグを引き起こす Form API インジェクションを実際に理解したいと考え、公開されている PoC を学習演習として一から再構築しました。
広く参照されている元の PoC、a2u/CVE-2018-7600(Vitalii Rudnykh 氏作成)はバグの実演には優れていますが、実行のたびにペイロードをその場で編集する必要があります。ラボやCTFのワークフロー(異なるターゲットに対して繰り返し実行し、再現可能な足がかりを得たい)では、それは面倒です。このバージョンは、それを適切なCLIツールに変えたものです。
cmd= の扉を残しません。このツールは意図的に既知であり、長い間パッチが適用されている脆弱性(2018年に開示)に範囲を限定しています。目的は、技術を理解し、クリーンで文書化されたリファレンス実装を提供することであり、新規の攻撃能力を提供することではありません。
このリポジトリのコードは、HTB モジュールに取り組む際に AI 支援(Anthropic の Claude) を受けて作成されました。私が設計目標と要件(CLIの操作性、Webシェルの自動展開、対話モード、シェル名とパラメータのランダム化)を設定し、結果をレビューおよびテストしました。この開示は、誠実であるため、そしてここでの価値はすべての行の作者であることではなく、理解とエンジニアリング上の決定にあるためです。
--cmd でそのシェルを通じてコマンドを実行したり、--shell で対話型の疑似シェルに入ったりできます。CVE-2018-7600 は以下のバージョンに影響します:
この実装は Drupal 8 の Form API ベクター(user/register AJAX エンドポイント)を対象としています。Drupal 7 は別のエンドポイント/ペイロードを通じて悪用可能ですが、ここでは処理しません。
パッチが適用されたリリース(7.58 / 8.5.1 以降)は影響を受けません。
requestspip install requests
# 単発コマンド
python3 drupalgeddon2.py -u http://target/ -c id
# 対話型疑似シェル
python3 drupalgeddon2.py -u http://target/ --shell
# シェルだけを設置し、何も実行しない
python3 drupalgeddon2.py -u http://target/ --deploy-only
# Burp 経由でルーティング、プロキシの自己署名証明書を無視
python3 drupalgeddon2.py -u http://target/ -c id --proxy http://127.0.0.1:8080 -k
CVE-2018-7600 は Drupal の Form API における入力サニタイズの欠陥です。Drupal はフォームをネストされた レンダラブル配列 として表現し、# で始まる配列キーはユーザーデータではなく特別なレンダープロパティとして扱われます。パッチ(SA-CORE-2018-002)では、これらの # で始まるキーをユーザー入力を介して除去するサニタイズが追加されました。
パッチ適用前は、認証されていない攻撃者が Drupal の AJAX ハンドラによって処理されるフォーム要素にレンダープロパティを注入することができました。次のようなプロパティを送信することで:
#post_render — Drupal がレンダリング後に呼び出すコールバックのリスト#markup — それらに渡される引数をユーザー登録フォームの mail 要素に対して指定すると、Drupal はレンダリングステップで攻撃者が制御する入力を用いて任意の PHP 関数(ここでは exec)を呼び出します。つまり認証なしでリモートコード実行が可能です。
この PoC はそのプリミティブを使用して、1行の PHP シェルをローカルで base64 エンコードし、サーバーにそれをデコードさせて Web ルートにファイルとして書き込ませ、その後、通常の GET リクエストを通じてそのファイルとやり取りします。
防御側の立場から:
対策
検出のアイデア
#post_render、#markup、#type、#lazy_builder など)を検査する。正当なフォーム送信にはこれらは含まれません。…/user/register?element_parents=…&_wrapper_format=drupal_ajax へのリクエストで不審なパラメータが含まれているものをフラグ付けする。.php ファイルへの GET を関連付ける。system($_GET[...]) シェル)を監視する。このツールは教育目的および許可されたセキュリティテスト(自身のラボ環境、HTB/CTF のターゲット、または明示的な書面による許可を得たシステム)のために公開されています。コンピュータシステムへの不正アクセスは、英国の Computer Misuse Act 1990、米国の Computer Fraud and Abuse Act など、各国の法律で犯罪とされています。利用方法については利用者が単独で責任を負います。作成者は、悪用またはそれによって生じたいかなる損害に対しても責任を負いません。
MIT
| フラグ | 説明 |
|---|
-u, --url | (必須) ターゲットのベースURL(例:http://target/) |
-c, --cmd | ターゲットで実行する単一のコマンド |
--shell | 対話型の疑似シェルを起動 |
--deploy-only | Web シェルのみ設置し、何も実行しない |
--shell-name | 設置するシェルのファイル名(デフォルト:ランダムな .php) |
--param | シェル用の GET パラメータ名(デフォルト:ランダムな md5) |
--proxy | プロキシURL(例:http://127.0.0.1:8080) |
-k, --insecure | TLS 検証を無効化(自己署名プロキシ証明書用) |
--timeout | リクエストごとのタイムアウト(秒)(デフォルト:15) |