После патчей PHP2Shell хостер сломал ColdFusion-сайты: как найти забытый PHP

Автор блога на ColdFusion при входе в админку тестового блога получил от IIS ошибку 403 Forbidden с сообщением, что запросы multipart form-data заблокированы защитой от PHP. Его блоги работают на ColdFusion и не содержат ни строки PHP, так что причину пришлось искать. Совпадение по времени не случайно: 21 октября 2026 года PHP выпустил экстренные патчи для двух критических уязвимостей (получивших прозвище PHP2Shell), которые позволяют неаутентифицированному запросу выполнить код на сервере. Затронуты все конфигурации PHP, обслуживающие веб-запросы: PHP-FPM, mod_php в Apache, php-cgi, FrankenPHP и LiteSpeed. Исправление, установить новую версию: 8.5.12, 8.4.27, 8.3.36 или 8.2.35.
Хостинг-компания автора в ту же неделю добавила защитное правило в серверные правила URL Rewrite в IIS. Оно действовало на все сайты сервера и блокировало любой запрос с типом содержимого multipart/form-data независимо от адреса, это кодировка любой формы, которая умеет загружать файл, и многие формы используют её и без загрузок. Собственные рекомендации PHP такой блокировки не включают: обновиться, а до этого отключить session.upload_progress.enabled и уменьшить post_max_size. Автор понимает, почему хостер взялся за самый грубый инструмент: для PHP-сайта это жёсткая, но понятная защита. Но на его сайтах ColdFusion вход в админку, загрузка изображений и загрузка файлов перестали работать сразу на всех четырёх сайтах, потому что правило срабатывало на любой адрес, а не только на .php.
После того как автор сузил правило до адресов .php, всё заработало. Тогда он спросил себя, зачем на сервере вообще PHP. Оказалось, это установка phpMyAdmin, которую он сам просил много лет назад для управления одной базой MySQL: она лежала в папке сайта, а страница входа была открыта всему интернету. Хостер отключил общее правило, когда автор сообщил, что PHP больше не используется, и автор стал искать другие следы PHP.
Проверка 1: передаёт ли IIS файлы .php в PHP. В PowerShell от имени администратора командой Get-WebHandler с фильтром по пути *.php ищется обработчик. Пустой вывод означает, что IIS PHP не запускает; если есть строка вроде FastCGI *.php C:\php\php-cgi.exe, запускает, для каждого сайта, наследующего настройки сервера. Имя обработчика и путь scriptProcessor нужно записать для удаления.
Проверка 2: есть ли файлы .php в сайтах. Get-ChildItem -Recurse на сервере с многолетними загрузками может работать минутами, поэтому автор использует системную dir /s /b и считает файлы, а затем группирует их по папкам. У автора нашлось около 4500 файлов в двух папках, обе, phpMyAdmin: одна внутри сайта, вторая в корне веб-каталога, которую Default Web Site отдавал любому, кто заходил на голый IP-адрес сервера. Если найдены незнакомые PHP-файлы, особенно разбросанные по папкам с картинками и загрузками или недавно изменённые, нужно остановиться и считать это возможным взломом: по словам автора, злоумышленники любят подкладывать в папки загрузок небольшие PHP-скрипты (веб-шеллы). Для этого приведена команда, выводящая 15 последних изменённых файлов.
Проверка 3: установлен ли PHP и запущен ли. Смотрим процессы php* и наличие папки C:\php. Отсутствие процесса php-cgi.exe ничего не доказывает: он просто не нужен, пока никто не запрашивал PHP-страницу, IIS запускает его по требованию. Важен обработчик из проверки 1.
Проверка 4: что видно из интернета. С любого компьютера автор опрашивает на своих сайтах адреса phpmyadmin/, phpMyAdmin/, pma/ и info.php. Всё, что отвечает кодом 200, заслуживает внимания: открытая страница входа phpMyAdmin, постоянное приглашение, боты подбирают на ней пароли весь день, и каждая попытка запускает PHP и обращается к базе данных.
Удаление выполняется по порядку, сначала резервная копия; каждый шаг обратим. Шаг 1: сохранить конфигурацию IIS командой appcmd.exe add backup с именем before-php-removal; откат, appcmd.exe restore backup. Шаг 2: переместить, а не удалять phpMyAdmin и другие PHP-приложения из веб-папок, в его конфигурации может быть пароль к базе, поэтому хранить копию в закрытом месте несколько недель. Если файл занят, остановить IIS через iisreset /stop, переместить, запустить iisreset /start (сайты будут недоступны несколько секунд). Вместо phpMyAdmin для MySQL автор предлагает настольный инструмент на сервере через удалённый рабочий стол, например HeidiSQL или MySQL Workbench. Шаг 3: запретить расширение .php в фильтрации запросов IIS на уровне сервера, тогда любой адрес .php получает 404 независимо от того, есть ли файл. Шаг 4: удалить обработчик (у автора он назывался FastCGI) и запись FastCGI с путём к php-cgi.exe, затем повторить проверку 1, вывод должен быть пустым. Шаг 5: в последнюю очередь удалить PHP через «Приложения» или переименовать папку, например C:\php в C:\php-removed, и удалить через несколько недель. Если PHP установил хостер, перед шагом 5 стоит спросить его.
Если правило нужно оставить (PHP где-то используется или хостер его хочет), его надо ограничить адресами .php, а не всеми: «весь вред» нанесло значение match url=".*". Автор меняет его командой Set-WebConfigurationProperty с шаблоном в одинарных кавычках: через appcmd.exe PowerShell незаметно исказил кавычки, без ошибки и без изменений. Для Lucee на Linux и Apache те же вопросы решаются командами php -v, apachectl -M, find по /var/www и /home, а на Debian и Ubuntu Apache перестаёт запускать PHP после a2dismod php8.3 (с вашей версией) и перезапуска apache2; панели управления вроде Virtualmin часто ставят PHP для своих нужд, так что перед удалением пакетов надо проверить.
В разделе «Подводные камни» автор перечисляет: серверное правило затрагивает все сайты; хостеры повторно запускают свои скрипты, и у него правило пересоздавалось при каждом запуске, поэтому локальная правка могла быть тихо отменена; правка может попасть не в тот web.config; Trusted Cache в ColdFusion держит старую скомпилированную копию файла, пока её не очистить. Главное: удаление PHP не заменяет обновление. Если PHP используется, надо обновиться до 8.5.12, 8.4.27, 8.3.36 или 8.2.35 (или новее) и до тех пор поставить session.upload_progress.enabled = 0 в php.ini. PHP 8.1 и старше больше не получают обновлений от проекта PHP. Удалять PHP правильно только тогда, когда он никому не нужен.
Ключевые факты
- 21 октября 2026 года PHP выпустил экстренные патчи для двух критических уязвимостей PHP2Shell (выполнение кода неаутентифицированным запросом); исправленные версии: 8.5.12, 8.4.27, 8.3.36, 8.2.35.
- Серверное правило IIS у хостера блокировало все запросы multipart/form-data на любой адрес, и у автора на всех четырёх сайтах ColdFusion перестали работать вход в админку и загрузки; помогло сужение правила до адресов .php.
- Источником оказался забытый phpMyAdmin, установленный годы назад для одной базы MySQL: у автора нашлось около 4500 PHP-файлов в двух папках, одна из них была доступна по голому IP сервера.
- Четыре проверки в PowerShell: обработчик *.php в IIS, подсчёт файлов .php, процессы и папка PHP, внешний опрос адресов вроде phpmyadmin/ и info.php; для Linux и Apache даны аналогичные команды.
- Безопасное удаление в пять шагов с резервной копией IIS: переместить PHP-приложения, запретить .php, убрать обработчик и запись FastCGI, удалить PHP; но удаление не заменяет патч, если PHP используется.
Почему это важно
Критические уязвимости PHP, как объясняет автор, вынуждают хостеров принимать грубые защитные меры, которые задевают и сайты вообще без PHP: правило, написанное против PHP2Shell, остановило вход и загрузки на всех четырёх сайтах ColdFusion автора. Заодно история показывает типичную проблему: забытое PHP-приложение (у автора это phpMyAdmin многолетней давности с открытой страницей входа) остаётся на сервере и становится поверхностью атаки, о которой владелец не помнит.
Кому это важно
Прежде всего тем, кто запускает ColdFusion или Lucee на Windows с IIS, а также на Linux с Apache, и размещается у хостера, управляющего сервером. Источник адресован людям, которые никогда не ставили PHP намеренно, но могли получить его вместе с панелью управления, старой установкой phpMyAdmin или образом хостера. Подойдёт и администраторам, у которых PHP действительно используется: им напоминание об обновлении.
Как это применить
Сначала пройти проверки: в PowerShell от имени администратора найти обработчик *.php, посчитать файлы .php в веб-каталоге (через dir /s /b, это быстрее Get-ChildItem), проверить процессы и папку C:\php, а с другого компьютера опросить адреса phpmyadmin/, pma/, info.php. Если PHP не нужен, действовать по порядку: сделать резервную копию конфигурации IIS через appcmd.exe, переместить PHP-приложения из веб-папок, запретить .php в фильтрации запросов, удалить обработчик и запись FastCGI, и в самом конце удалить или переименовать PHP. Если правило хостера нужно оставить, ограничить его адресами .php. На Linux, php -v, apachectl -M, find, при необходимости a2dismod. Если PHP используется, обновить его до указанных версий или новее.
Можно ли доверять
Это практическое руководство от практикующего администратора по его собственному случаю; имя автора в тексте не указано, хостинг-компания не названа. Нет доказательств, что сервер автора взламывали. Названия двух уязвимостей (CVE) и их техническое устройство в материале не раскрыты, кроме того, что они допускают выполнение кода неаутентифицированным запросом. Версии ColdFusion, Lucee и IIS не указаны, поэтому команды стоит сначала проверить на тестовой среде, а числа версий PHP, сверить с официальным объявлением проекта.
Риски и подводные камни
Удаление PHP не заменяет обновление: если PHP где-то используется, он остаётся уязвимым до установки исправленной версии (PHP 8.1 и старше обновлений больше не получают). Незнакомые или недавно изменённые PHP-файлы в папках загрузок автор советует считать возможным взломом, а не просто удалять. Остановка IIS для переноса занятых файлов даёт несколько секунд простоя. Хостер может пересоздавать своё правило при каждом запуске скриптов, поэтому локальную правку надо согласовать с ним. Если PHP поставил хостер, перед удалением стоит спросить его. Правка может попасть не в тот web.config, а Trusted Cache в ColdFusion держит старую скомпилированную копию изменённого файла.