Взломали сайт WordPress — пошаговая зачистка wp2shell малвари
503 вместо сайта. В админку не зайти. В БД — 5 новых админов с почтой @wp2shell.invalid. Плагин-вирус со случайным именем, фейковый логин, SMTP-клиент для спама. wp2shell — массовый веб-шелл, который штампует бэкдоры по файловой системе. Пошагово: как нашёл, вычистил, поднял.
wp2shell проникает через уязвимый плагин — в этом случае через fileorganizer (файловый менеджер в админке). Он создаёт бэкдор-пользователей с максимальными правами, загружает фейковый логин (wp-l0gin.php) и скрытый SMTP-клиент (Leaf PHPMailer). Основной признак — пользователи с email @wp2shell.invalid или @wordpress-svc.internal. Зачистка: удалить бэкдор-юзеров из БД, удалить плагин-вирус, сменить пароль БД, сменить все 8 солей WordPress. После зачистки — обновить WordPress, плагины, включить 2FA. Полный процесс занимает 40-60 минут.
Как wp2shell попадает на сайт
fileorganizer — легитимный плагин-файловый менеджер, который позволяет редактировать файлы прямо из админки WordPress. Если у админа слабый пароль или плагин не обновлён — злоумышленник получает полный доступ к файловой системе. В этом случае через fileorganizer загрузили zip-архив с плагином ghazszlnzp (случайное имя), который содержал webshell и SMTP-клиент.
Хронология атаки (реальный случай, 19-29 июля)
19 июля — появились первые wpsvc-пользователи (первичный доступ). Через 5 дней — w2s_56636971b728. Ещё через 2 дня — правка footer.php (проверка, что доступ к файлам есть). 24-26 июля — новые админы w2s_cc62aa87498d и w2s_b8da1804ca24, плюс SQL-инъекции через REST API. 29 июля в 4:39 — модификация fileorganizer, в 7:05-7:49 — загрузка плагина ghazszlnzp (17 файлов). Атака развивалась 10 дней — с первого доступа до полного захвата.
Хостинг — Beget, PHP 8.2.28. Сайт на WordPress + WooCommerce + Storefront. Всё стандартно: магазин с 15 плагинами, никаких экзотических решений. Уязвимость — человеческий фактор и отсутствие мониторинга.
Пошаговая зачистка wp2shell малвари
Шаг 1. Найти и удалить бэкдор-пользователей
Первым делом — SQL-запрос в БД сайта. Захожу в phpMyAdmin хостинга, открываю таблицу wp_users. Вижу строки с email @wp2shell.invalid и @wordpress-svc.internal. У каждого — права Administrator (wp_capabilities сериализованный массив с a:1:{s:13:"administrator";b:1;}).
Проверяю: есть ли легитимные пользователи с такими email — нет. Удаляю:
DELETE FROM wp_usermeta WHERE user_id IN (3, 5, 7, 9, 11);
DELETE FROM wp_users WHERE ID IN (3, 5, 7, 9, 11);
Цифры условные — в реальном случае было 5 бэкдоров с ID 3, 5, 7, 9, 11 (первые два ID — легитимные админы, их не трогаем).
Важно: удалять сначала usermeta, потом users. У пользователей могут быть мета-ключи с дополнительными правами, которые останутся в БД мёртвым грузом, если удалить только users.
Шаг 2. Удалить плагин-вирус
В wp-content/plugins/ появилась папка со случайным именем — ghazszlnzp. Внутри 17 файлов:
- wp-l0gin.php — фейковый логин, маскируется под страницу входа WordPress, перехватывает пароли
- smtp.php — Leaf PHPMailer, рассылает спам через SMTP сайта
- xx.php — базовый webshell для выполнения команд
- Остальные — обвязка: хелперы, скрипты инсталляции, скрытые страницы
Просто удаляю папку через файловый менеджер хостинга:
rm -rf wp-content/plugins/ghazszlnzp/
Плагин автоматически исчезает из active_plugins в БД — WordPress проверяет существование папки при каждой загрузке. Если папки нет, плагин деактивируется.
Шаг 3. Удалить подозрительные плагины
fileorganizer — именно через него загрузили архив. Этот плагин-файловый менеджер — слишком опасный инструмент для рядового сайта. Его функциональность (загрузка zip, редактирование любых файлов) почти никогда не нужна в production. Если вам правда нужно редактировать файлы через админку — используйте FTP/SFTP и нормальный редактор кода, а не плагин с веб-интерфейсом.
Проверяю остальные плагины. Находим wp-filemanager, file-manager — те же грабли. Все файловые менеджеры — на удаление.
Шаг 4. Сменить пароль базы данных
Злоумышленник мог получить доступ к wp-config.php. Оттуда — логин и пароль БД. Если у хостинга нет изоляции баз данных (MySQL на одном сервере), доступ к вашей БД открывает все записи, мета-данные, опции.
Через панель Beget генерирую новый пароль БД. Обновляю в wp-config.php:
define( 'DB_PASSWORD', 'новый-пароль-32-символа' );
На хостингах вроде Timeweb и Reg.ru — аналогично: через панель управления сменить пароль MySQL, обновить в конфиге. В некоторых случаях нужно также обновить пароль пользователя MySQL через phpMyAdmin (ALTER USER).
Шаг 5. Сменить соли WordPress
Соли — 8 констант в wp-config.php (AUTH_KEY, SECURE_AUTH_KEY, LOGGED_IN_KEY, NONCE_KEY, AUTH_SALT, SECURE_AUTH_SALT, LOGGED_IN_SALT, NONCE_SALT). Они используются для шифрования кук, nonce-токенов и паролей. Если их не сменить — злоумышленник с сохранённой кукой сможет войти в админку даже после смены пароля админа.
Генерирую новые соли на api.wordpress.org/secret-key/1.1/salt/ — заменяю все 8 строк в wp-config.php старыми. Старые соли комментирую, новые вставляю вместо них.
После смены солей все активные сессии пользователей сбрасываются — придётся заново входить в админку. Это нормально, так и должно быть.
Шаг 6. Проверить wp-content/uploads
Частая практика — прятать php-шеллы в папку с загрузками. Злоумышленники загружают файл через медиабиблиотеку (картинку), а потом через редактирование файла вписывают туда php-код. Или просто заливают php-файл с помощью fileorganizer.
find wp-content/uploads/ -name "*.php"
Если команда выдала результат — почти наверняка это шелл. В нашем случае uploads были чистыми — вирус работал исключительно через кастомный плагин.
Шаг 7. Проверить error log
Лог ошибок — кладезь информации. В lkartlog.ru error_log показал характерные строки: blind SQL injection через REST API. Злоумышленник отправлял POST-запросы на /wp-json/wp/v2/posts с бит-флип-атаками — пытался подобрать параметры через изменение одного бита в сериализованных данных. WordPress REST API — частая цель, потому что он открыт для неавторизованных запросов по умолчанию.
Чистка лога: сохранить копию для анализа, потом очистить текущий лог. На Beget лог в папке сайта — можно просто удалить, сервер создаст новый.
Проверка после зачистки
После всех шагов сайт должен открываться. Проверяю три вещи:
- Фронтенд — главная открывается, 503 исчез, контент отображается, картинки грузятся
- Админка — вход работает, плагины отображаются, WooCommerce функционирует
- БД — нет новых пользователей, нет подозрительных опций (проверить wp_options на наличие неизвестных записей)
После зачистки: обновить WordPress до последней версии, обновить все плагины (особенно WooCommerce, WPForms, любые плагины с формами и загрузкой файлов), сменить пароли всем админ-пользователям.
Дополнительно — включить 2FA для админов. Google Authenticator или плагин вроде WP 2FA. Это не панацея, но от автоматических атак (которые не умеют вводить TOTP-коды) защищает надёжно.
Когда не сработает
Простая зачистка не поможет, если:
- Вектор не устранён — если уязвимость в теме или другом плагине, вы через неделю получите новых бэкдоров. Потому я удалил fileorganizer — именно через него загрузили архив.
- Вирус встроен в ядро — wp2shell не трогает файлы ядра, но есть малварь, которая патчит wp-load.php, wp-settings.php, xmlrpc.php. В таком случае требуется переустановка WordPress через админку (Обновление → Переустановить).
- Заражён сервер — если хостинг скомпрометирован, локальная зачистка бессмысленна. Признаки: другие сайты на том же аккаунте тоже заражены, в логах сервера подозрительная активность не с вашего сайта.
- Бэкапы заражены — если восстанавливаться из бэкапа, сделанного после атаки, вы просто откатываетесь к заражённой версии. Нужен бэкап до 19 июля (первого появления wpsvc-пользователей).
В этих случаях — полная переустановка WordPress с чисткой файловой системы и поиском уязвимости на уровне хостинга.
FAQ
Нужна помощь с зачисткой WordPress?
Проверю сайт, найду закладки, вычищу малварь, закрою дыры. Бесплатная диагностика — напишите, расскажу что и как.