Если ты администрируешь веб-серверы или разрабатываешь бэкенд на PHP, последние дни наверняка запомнились экстренными ночными дежурствами. По индустрии прокатилась ударная волна: исследователи из Wiz опубликовали технические подробности критической цепочки уязвимостей в ядре языка PHP, получившей собирательное имя php2shell (идентификаторы CVE-2026-109618 и CVE-2026-109619).
Оценка серьезности по шкале CVSS v4.0 составляет пугающие 9.2 из 10 (Critical). И этот рейтинг абсолютно оправдан: уязвимость позволяет неавторизованному злоумышленнику удаленно выполнить произвольный код (Remote Code Execution, RCE) на сервере через единственный специально сформированный HTTP POST-запрос.
Самое неприятное в этой истории — вектор атаки. Твое приложение может быть написано по лучшим стандартам индустрии: ты можешь использовать фреймворк Laravel или Symfony со строгой типизацией, параметризованными SQL-запросами и санитайзингом пользовательского ввода. Но php2shell бьет глубже: эксплойт срабатывает внутри низкоуровневого парсера ядра языка на языке C до того, как управление вообще дойдет до твоего PHP-скрипта.
Анатомия атаки: как multipart ломает рантайм
Давай разберем по винтикам, как безобидная загрузка формы превращается в удаленный системный шелл.

Стандарт HTTP определяет формат multipart/form-data для передачи файлов и полей форм: данные разбиваются на части, разделенные текстовыми границами (boundary). За разбор этого потока байтов в ядре PHP отвечает файл main/rfc1867.c.
Вот какая цепочка событий разворачивается при атаке:
- Аномальный входящий поток: атакующий отправляет HTTP POST-запрос с типом
multipart/form-data. В заголовках запроса намеренно опускается или искажается заголовокContent-Length, либо включается потоковая передачаTransfer-Encoding: chunked. - Мусорная лавина: тело запроса содержит тысячи мелких пустых полей формы, глубоко вложенные заголовки и специально подобранные бинарные последовательности, имитирующие структуры внутренних указателей языка Си.
- Искусственный OOM: парсер
rfc1867.cначинает жадно выделять память под каждое поле в куче Zend Engine. В определенный момент процесс упирается в системный лимитmemory_limit(или исчерпывает оперативную память процесса) и выбрасывает фатальную ошибкуFatal error: Allowed memory size exhausted. - Роковая процедура завершения (Shutdown Routine): казалось бы, процесс должен безопасно упасть и завершиться. Но Zend Engine устроен так, что при фатальной ошибке он запускает специальный обработчик аварийной очистки ресурсов, чтобы освободить дескрипторы файлов и очистить кэш.
- Разыменование поврежденного указателя: код очистки структур данных наивно предполагает, что связные списки и хэш-таблицы входящей формы были полностью и корректно инициализированы. Однако из-за внезапного сбоя памяти список оказался «разорванным». Очищающий цикл берет контролируемое атакующим значение из недостроенного буфера, считает его адресом функции деструктора и передает управление по этому адресу.
В результате процессор переходит к исполнению шелл-кода, внедренного в тело запроса. Поскольку веб-сервер (будь то PHP-FPM, Apache mod_php, LiteSpeed или современный FrankenPHP) работает от имени системного пользователя www-data или nginx, атакующий получает полноценный доступ к файловой системе сервера и базе данных.
Почему правила WAF — лишь временная повязка
Как только новость о php2shell стала публичной, крупнейшие провайдеры сетевой безопасности и CDN (включая Cloudflare, Fastly и AWS WAF) экстренно развернули правила сигнатурного анализа для блокировки подозрительных POST-запросов с аномальным количеством multipart-секций.
Однако полагаться исключительно на WAF в этой ситуации смертельно опасно. Опытные исследователи безопасности уже продемонстрировали несколько методов обхода статических фильтров:
- разбиение границ multipart на микро-чанки TCP;
- манипуляции с кодировками символов перевода строки (
\r\nпротив\n); - внедрение редких и нестандартных заголовков полей, которые игнорируются простыми регулярными выражениями WAF, но корректно проглатываются внутренним парсером PHP.
WAF дает системным администраторам драгоценную фору в несколько часов, но единственным надежным лекарством остается физическое обновление бинарных файлов PHP на серверах.
Официальные патчи и процедура обновления
Команда безопасности PHP Group выпустила внеочередные срочные релизы для всех поддерживаемых стабильных веток:
- ветка 8.5 получила обновление 8.5.12;
- ветка 8.4 пропатчена до 8.4.27;
- ветка 8.3 обновлена до 8.3.36;
- ветка 8.2 получила версию 8.2.35.
Для проверки текущей версии рантайма на сервере выполни команду в терминале:
php -v
# Либо проверь версию конкретно запущенного сокета пула:
php-fpm8.4 -v
Если ты используешь популярные серверные дистрибутивы Debian или Ubuntu с официальными репозиториями Ондрея Суры (ppa:ondrej/php), процедура обновления выглядит стандартно:
sudo apt update
sudo apt install --only-upgrade php8.4-fpm php8.4-cli php8.4-common
# Критически важно: обязательно перезапусти службу после обновления!
sudo systemctl restart php8.4-fpm
В Docker-окружениях необходимо пересобрать образы с обновлением базовых тегов php:8.4-fpm-alpine или принудительно запустить apk upgrade --no-cache в Dockerfile.
Ловушка устаревших версий (EOL)
Самая большая драма разворачивается вокруг проектов, работающих на старых версиях PHP: 8.1, 8.0, 7.4 и древнее. Все они официально достигли статуса End-of-Life (EOL), а значит, официальная команда разработки PHP не выпускает для них бесплатные патчи безопасности.
Если твой легаси-проект застрял на PHP 7.4, у тебя есть три пути:
- Экстренная миграция на ветку 8.2+ (самый правильный, но трудоемкий путь).
- Использование дистрибутивов с длительной поддержкой: Red Hat Enterprise Linux, Ubuntu Pro и Debian LTS бэкпортируют исправления безопасности в старые системные пакеты.
- Коммерческая поддержка: приобретение сторонних патчей (например, от TuxCare или специализированных вендоров).
Как проверить сервер на признаки взлома
Если сервер находился в публичном доступе без патча, стоит немедленно провести аудит активных процессов. Поскольку шелл-код обычно пытается запустить командную оболочку или сетевые утилиты скачивания пейлоадов, проверь дерево процессов:
# Ищем командные оболочки и утилиты, запущенные дочерними процессами PHP-FPM
ps -ef --forest | grep -E 'php-fpm.*(sh|bash|curl|wget|nc|python)'
Любое появление процесса /bin/sh или /bin/bash, родителем которого выступает php-fpm, является стопроцентным маркером успешной компрометации системы.
Инцидент с php2shell совпал по времени с обнаружением еще одной критической уязвимости — переполнения буфера в Си-декодере Brotli, встроенном в платформу Node.js. Это наглядно показывает, что специалисты по безопасности смещают фокус с прикладного кода на низкоуровневые сетевые парсеры рантаймов. Внимательно следи за обновлениями базовых образов и не откладывай установку системных патчей.
