PHP2Shell: как проверить PHP-FPM после выхода исправлений критических уязвимостей

mr. Cooper • 1 неделю назад • Инсайды и новости
PHP2Shell: как проверить PHP-FPM после выхода исправлений критических уязвимостей

21 октября 2026 года команда PHP выпустила обновления безопасности для четырёх веток языка: 8.5.12, 8.4.27, 8.3.36 и 8.2.35. Релизы исправляют две критические уязвимости - CVE-2026-109618 и CVE-2026-109619, которые позволяют добиться удалённого выполнения кода без авторизации.

Исследователи Wiz назвали исследование PHP2Shell. В демонстрации атак использовались WordPress, Drupal и Joomla, но уязвимости находятся в PHP, поэтому привязки к конкретной CMS нет.

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

Что обнаружили исследователи

CVE-2026-109618 связана с обработкой сериализованных данных в механизме отслеживания загрузок файлов - upload progress. При нехватке памяти PHP может прервать выполнение в момент, когда внутренние данные запроса ещё не полностью инициализированы. При очистке запроса движок использует некорректное состояние. Wiz продемонстрировала удалённое выполнение кода до авторизации, а также отдельный сценарий раскрытия памяти PHP-процесса.

CVE-2026-109619 затрагивает другое состояние интерпретатора. Данные, принадлежащие завершившемуся запросу, могут сохраняться после освобождения соответствующей памяти. Если тот же рабочий процесс PHP-FPM получает следующий запрос до сброса устаревшего состояния, он может обратиться к уже недействительным данным.

В исходном коде PHP исправления связаны с обработкой аварийного выхода из выполнения - bailout. Обе уязвимости относятся к внутренним механизмам движка, поэтому обновление CMS само по себе их не устраняет.

Исправленные версии PHP

Ветка

Версия с исправлениями

PHP 8.5

8.5.12

PHP 8.4

8.4.27

PHP 8.3

8.3.36

PHP 8.2

8.2.35

Для PHP 8.1 и более старых веток нужно уточнять наличие исправления у поставщика ОС или хостинга: эти версии больше не получают обычные обновления от проекта PHP, хотя некоторые поставщики выпускают собственные исправленные пакеты.

Проверяем PHP-FPM на сервере

Найти службу

В Linux с systemd выполните:

//bash

systemctl list-units --type=service --all | grep -Ei 'php.*fpm|fpm.*php'

В списке могут оказаться службы для разных веток PHP. Выберите ту, которая относится к нужному сайту, и посмотрите её параметры:

//bash

systemctl cat ИМЯ_СЛУЖБЫ

В строке ExecStart указан исполняемый файл, запускаемый службой. Его путь может отличаться от стандартного /usr/sbin/php-fpm, особенно если PHP установлен через панель управления.

Сопоставить службу с сайтом

Если сайт работает через Nginx, найдите директиву fastcgi_pass в его конфигурации:

//bash

sudo nginx -T 2>&1 | grep -nE 'server_name|fastcgi_pass'

По имени домена определите соответствующий блок server и адрес PHP-FPM. Это может быть Unix-сокет вроде /run/php/php8.4-fpm.sock или сетевой адрес.

Теперь можно сопоставить сокет с настройкой listen в конфигурации пула PHP-FPM. Путь к конфигурации зависит от способа установки PHP; его можно уточнить через параметры запуска службы и конфигурацию установленного пакета.

Проверить версию запускаемого PHP

Когда путь к бинарному файлу известен, выполните:

//bash

/ПУТЬ/К/php-fpm -v

Подставьте реальный путь из ExecStart. Команда покажет версию этого бинарного файла, но окончательную проверку нужно сделать через HTTP: именно так выясняется, какая версия отвечает на запросы сайта.

Проверить версию через HTTP

Временно создайте в корневом каталоге сайта файл с непредсказуемым именем, например runtime-check-a7f3.php, со следующим содержимым:

//php

<?php

header('Content-Type: text/plain; charset=utf-8');

echo 'PHP_VERSION=', PHP_VERSION, "\n";
echo 'PHP_SAPI=', PHP_SAPI, "\n";

Откройте файл через HTTPS по адресу сайта. При обработке через PHP-FPM значение PHP_SAPI обычно будет fpm-fcgi. PHP_VERSION покажет версию интерпретатора, который обработал этот запрос.

После проверки немедленно удалите файл. Не используйте для этой задачи публичный phpinfo(): он раскрывает значительно больше сведений об окружении.

Если через HTTP отображается старая версия, проверьте, какой обработчик подключён к домену и обновлён ли именно его пакет. После установки обновления повторите запрос. Для завершённой проверки результат должен соответствовать исправленному релизу или подтверждённой поставщиком сборке с backport исправления.

Если обновления ещё нет

Разработчики PHP прямо указывают: полной временной защиты от этих уязвимостей нет, безопасное решение - установить исправление. Отключение session.upload_progress.enabled, фильтрация запросов через WAF или ограничение загрузки файлов не заменяют патч и не гарантируют защиту от обоих сценариев.

Если пакет пока не появился в панели управления, проверьте уведомления поставщика и запросите срок выпуска исправленной сборки для используемой ветки. Не подменяйте PHP-FPM случайным бинарным файлом из стороннего источника: такая замена может нарушить совместимость расширений и конфигурации.

Для старых веток отдельно уточните у поставщика, выпущен ли backport. Сам номер версии иногда остаётся прежним при переносе исправления в пакет дистрибутива, поэтому ориентироваться нужно на подтверждённый статус обновления.

Проверка PHP2Shell заканчивается не после установки пакета и не после команды php -v. Критерий простой: веб-запрос обслуживается исправленной сборкой PHP, а используемый сайтом обработчик действительно обновлён.

Комментарии

Л
Лиза Лиза • 1 неделю назад

За напоминание про рестарт самого демона FPM после апдейта отдельное спасибо. Сегодня с утра обновили пакеты на двух виртуалках, глянули php -v в консоли и сидели довольные, пока не проверили версию через phpinfo(), а там в памяти до сих пор крутились старые воркеры 8.3.35. А вот с отключением register_shutdown_function при жестком OOM новость неприятная - у нас как раз на шатдаунах висит снятие блокировок в Redis и отправка алертов в Sentry. Придется пересматривать логику.

Чтобы оставить комментарий, войдите в аккаунт.

Похожие статьи