PHP2Shell: как мы закрывали уязвимости PHP
21 октября PHP выпустил исправления сразу для двух критических уязвимостей, CVE-2026-109618 и CVE-2026-109619. Исследователи назвали их PHP2Shell. Суть простая: отправляешь сайту специально собранный запрос и выполняешь свой код на сервере. Затронуты все версии, начиная с PHP 5.4 из 2012 года. Рассказываю, как мы закрывали это на хостинге и о чём при этом легко забыть.
Обе ошибки сидят в механизме прогресса загрузки файлов, session upload progress. Он включён по умолчанию, так что уязвима самая обычная установка. Оценка опасности 9.2 из 10. По данным Sansec, публичные эксплойты на стандартной установке пока не срабатывают, им нужна ещё ошибка в самом сайте или точно подобранная сборка PHP. Но код уже в открытом доступе. Ждать, пока его доработают, я бы не стал.
Исправленные версии: 8.5.12, 8.4.27, 8.3.36 и 8.2.35. Для 8.1 и старше официальных релизов не будет, ветки не поддерживаются. Патчи в исходниках выложили для 7.4, 8.0 и 8.1, а дальше всё зависит от того, кто вам собирает PHP. Временная мера, которую советовали все, кто разбирал уязвимость:
session.upload_progress.enabled = Off
Она закрывает основной путь атаки, но не единственный. Обновляться всё равно надо.
По срокам вышло так. 17 октября Amazon увидел первую попытку атаки. 21 октября в 10:43 Cloudflare сообщил о первых атаках, патча ещё не было. В 17:00 вышли исправления. 22 октября в 18:32 у нас были обновлены все версии PHP на сервере хостинга. А официальное уведомление пришло через дата-центр, когда всё уже было закрыто. Это не упрёк, рассылка идёт по цепочке. Но вывод я для себя сделал простой: если ждать письма, окажешься позади тех, кто читает новости по безопасности.
На хостинге у каждого сайта своя версия PHP, от 5.2 до 8.5. Старый сайт на 5.6 уязвим так же, как новый на 8.4. Нас выручил CloudLinux: разработчики перенесли исправление во все свои сборки, включая давно не поддерживаемые. Клиенты ничего не заметили, версия та же, перезагружать ничего не пришлось.
Тут есть нюанс, на котором легко запутаться. После обновления phpinfo() показывает, например, 8.4.26, хотя исправлено в 8.4.27. Так и задумано: патч вносят в ту же сборку без смены номера. То же самое делают Debian, Ubuntu и другие дистрибутивы. Так что сканер, который ругается на «PHP 8.4.26», ещё не повод паниковать. Но и успокаиваться по номеру версии нельзя. Проверять нужно по changelog пакета:
# rpm -q --changelog alt-php84-cli | grep 109618
Больше всего времени ушло на PHP, который живёт не в сайтах. Веб-почта крутится в своём контейнере со своей версией, её обновили отдельно 23 октября, с 8.3.15 на 8.3.36. У панели управления тоже свой PHP, через него работает Roundcube. Исправленной сборки от разработчиков панели на тот момент не было, поэтому закрыли временной мерой через session.upload_progress.enabled = Off. Выйдет обновление - поставим и уберём заплатку.
Ну и неприятная находка. Пока проверяли файлы, нашли веб-шеллы на трёх сайтах клиентов. К PHP2Shell они отношения не имели: появились раньше, в июле и 18 октября, через дыры в плагинах CMS. Сайты приостановили, владельцам написали. Вывод для меня очевидный: свежий PHP не лечит сайт, который взломали раньше.
Ниже — список проверок для своего сервера или VDS.
Просмотры: 2