FYZI Shield / Статьи / Кейс: повторные взломы

Сайт взламывали пять раз подряд. Почему чистка не помогала

Владелец сайта аудиторской компании обратился с жалобой «не могу сохранить изменения в админке». За следующие три недели сайт заражали ещё четыре раза — после каждой чистки и смены паролей. Рассказываем, как это выглядело, почему первые чистки лечили только симптомы и что в итоге остановило взломы.

Кейсы · Обновлено 23 октября 2026 · 6 мин чтения

СайтАудиторская компания
ДвижокWordPress + Elementor
Заражений5 за 3 недели
ИтогВзломы прекратились

Раунд 1. «Админка не сохраняет изменения»

Первый симптом был совсем не похож на взлом: при сохранении страниц WordPress выдавал ошибку. Выяснилось, что база данных выросла с 46 МБ до 1,1 ГБ. В ней было больше 4000 спам-записей про казино на разных языках, датированных 2015 годом, чтобы не бросаться в глаза в списке. Вместе с ревизиями и метаданными — около 14 000 лишних строк.

Хостинг увидел превышение лимита на размер базы и автоматически отключил право записи. Поэтому админка и перестала сохранять. Это не было действием злоумышленника, но выглядело как саботаж.

Кроме спам-записей:

Спам удалили, база вернулась к 46 МБ, хостинг сам восстановил права. Пароль администратора сменили.

Раунд 2. Спам вернулся через несколько часов

В названиях пунктов меню снова появились приписки вида «слово @ спам-домен». Пароль к этому моменту уже был новым — значит, у злоумышленника был другой ключ.

Нашёлся пароль приложения — отдельный токен для REST API, привязанный к аккаунту администратора. Его последний раз использовали с чужого IP. Смена основного пароля такие токены не отзывает, поэтому про них часто забывают. Токен удалили, создание новых запретили.

Раунд 3. Двадцать девять администраторов

Через две недели в базе нашлось 29 администраторов, которых владелец не создавал. Они появлялись примерно по одному в день, а их почтовые адреса содержали название автоматического инструмента для массового взлома WordPress. Сайт атаковал не конкретный человек, а бот, который обходит тысячи сайтов.

Чужих администраторов удалили. А затем впервые провели сверку файлов ядра WordPress с официальными контрольными суммами — и нашли то, что пропустили все предыдущие проверки.

Находка. В папке wp-includes лежал посторонний файл с именем, похожим на настоящий файл ядра. Внутри — зашифрованный код, который выполнялся на каждой загрузке страницы. Дата изменения файла была подделана на 2020 год, а комментарии в нём забиты случайными словами, чтобы обмануть сканеры. Подключали его шесть настоящих файлов ядра, в каждый была добавлена одна незаметная строка.

Почему его не нашли раньше: поиск вирусов шёл по файлам, изменённым за последние 30–45 дней, и по типичным словам вроде eval и base64. Подделанная дата и шифрование обходили обе проверки. Сверка с контрольными суммами WordPress находит такие файлы сразу, потому что ей не важны ни дата, ни содержимое — только «совпадает ли файл с оригиналом».

Посторонний файл удалили, шесть файлов ядра заменили оригинальными из официального репозитория WordPress той же версии.

Раунд 4. Один администратор без следов в логах

Через пять часов появился ещё один администратор. На этот раз в журнале доступа не было ни одного запроса в момент его создания. Файлы ядра оставались чистыми.

Это навело на мысль о прямом доступе к базе данных. Пароль от неё ни разу не меняли за все раунды — его сменили.

Раунд 5. Настоящий канал

Смена пароля базы не помогла: в тот же день появились ещё два администратора. Зато в этот раз журнал доступа показал причину. Сотни POST-запросов в день с 13 разных IP-адресов шли на пакетный эндпоинт REST API — /wp-json/batch/v1 — и все получали успешный ответ.

Пакетные запросы нужны редактору блоков, то есть авторизованным пользователям. Анонимному посетителю они не нужны вообще. Мы закрыли их для неавторизованных запросов небольшим must-use плагином — такой плагин загружается всегда и не отключается из админки.

Результат. После закрытия этого канала новые администраторы больше не появлялись. Проверка запроса без авторизации теперь получает ответ 403, а сайт и редактор работают как прежде.

Почему понадобилось пять раундов

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

Правильный порядок при повторном заражении:

  1. Сверка ядра с контрольными суммами — первым делом, а не в последнюю очередь. Команда wp core verify-checksums или скрипт, сравнивающий файлы с официальным списком WordPress.
  2. Журнал доступа за дни, когда появлялись чужие администраторы. Ищите POST-запросы к /wp-json/, ?rest_route=, admin-ajax.php и xmlrpc.php.
  3. Все виды доступа сразу: пароли администраторов, пароли приложений, секретные ключи, пароль базы, пароль хостинга.
  4. Закрыть то, что анонимам не нужно: пакетный REST, список пользователей через REST, XML-RPC.
  5. Наблюдение после чистки. Если взлом повторится, о нём нужно узнать в первый час, а не через две недели.

Подробнее про чужих администраторов — в статье «В WordPress появился неизвестный администратор», про поиск скрытого кода — в разборе eval(base64_decode).

Частые вопросы

Почему антивирусный плагин не нашёл бэкдор?

Код был зашифрован, а комментарии забиты случайным текстом, чтобы не совпасть с сигнатурами. Такой файл находит только сверка с оригинальными файлами WordPress: она не смотрит на содержимое, а проверяет, совпадает ли файл с эталоном.

Зачем злоумышленнику подделывать дату файла?

Многие ищут вирусы среди файлов, изменённых за последний месяц. Файл с датой 2020 года в такой поиск не попадёт, хотя появился на сайте недавно.

Не сломает ли закрытие пакетного REST редактор?

Нет, если закрывать его только для неавторизованных запросов. Редактор работает от имени вошедшего пользователя, и для него ничего не меняется.

Сколько стоит такое расследование?

Срочная чистка с поиском точки входа — от 4 990 ₽. Если сайт заражают повторно, начинаем именно с поиска канала, а не с удаления спама.

Читайте также

Сайт взломан? Пишите