
Сайт на WordPress взломали — и первое, что видит владелец, это не изменённая главная и не баннер хакера, а внезапный обвал позиций и странные строки в выдаче: «купить диплом», «займ без отказа», иероглифы вперемешку с латиницей. Файлы можно почистить за час. Проблема в том, что поисковик уже забрал в индекс несколько тысяч чужих страниц, и они продолжают жить своей жизнью даже после того, как на сервере от них не осталось ни байта.
Ниже — порядок, по которому такая история закрывается за один вечер: как убедиться, что это именно взлом, что делать в первые двадцать минут, чем чистка отличается от лечения и почему сама по себе она ничего не решает. В SEO с 2005 года, и сайты после взлома приходят на разбор регулярно — почти всегда с одной и той же незакрытой частью работы.
Как отличить взлом от других причин падения
Позиции падают по десятку причин, и половина не связана с безопасностью: переезд на новый шаблон, ошибка в robots.txt, смена хостинга, обновление алгоритма. У взлома есть отпечаток, который видно снаружи, без доступа к серверу. Проверка занимает пять минут.
- Оператор site: в поиске. Запрос вида
site:вашдомен.руплюс отдельноsite:вашдомен.ру займ,site:вашдомен.ру диплом,site:вашдомен.ру casino. Если в выдаче появляются адреса, которых вы не создавали, дальше можно не гадать. - Число страниц в индексе. В Яндекс Вебмастере раздел «Индексирование» — «Страницы в поиске». Сайт из 200 статей, у которого в поиске 4 800 адресов, заражён почти наверняка. Скачок на графике даёт и дату: с неё начинают отсчёт при поиске изменённых файлов.
- Раздел «Диагностика». Яндекс сообщает о вредоносном коде отдельным уведомлением. Появляется оно не мгновенно: отсутствие ничего не доказывает, наличие — доказывает всё.
- Просмотр как робот. В Вебмастере есть инструмент, который показывает страницу глазами поискового робота. Классический сценарий заражения WordPress — клоакинг: человеку отдаётся нормальная страница, роботу и переходу из поиска — спамная. Браузером вы её не увидите никогда.
- Дата изменения файлов. По SSH одна команда показывает всё, что менялось за последние двое суток:
find /путь/к/сайту -type f -mtime -2 -name "*.php". Ядро WordPress свои файлы просто так не переписывает. Если в выдаче оказались файлы из wp-includes и корня — это не обновление.
Отдельно смотрится список пользователей. Лишний администратор с почтой на бесплатном домене — прямое подтверждение; иногда его прячут фильтром в выводе списка, поэтому надёжнее считать строки в таблице wp_users запросом.
Чем спам-страницы бьют по позициям
Механизм ущерба состоит из четырёх слоёв, и они складываются, а не заменяют друг друга.
Первый — тематический сдвиг. Поисковик определяет, о чём сайт, по совокупности страниц. Когда к сотне статей о строительстве добавляются тысячи страниц про займы, тематика домена перестаёт быть однозначной, и даже нетронутые страницы теряют в релевантности по своим запросам.
Второй — расход обхода. Лимит на количество страниц, которые робот берёт за визит, конечный и общий на весь сайт. Пять тысяч сгенерированных адресов съедают его целиком: новые статьи перестают индексироваться, обновления старых не доходят до индекса неделями.
Третий — исходящие ссылки. Спам-страницы почти всегда ставят ссылки на сторонние ресурсы, ради этого всё и делается. Сайт превращается в донора для чужой ссылочной схемы, и алгоритмы, отвечающие за качество исходящего профиля, реагируют.
Четвёртый — пометка в выдаче. Когда вредоносный код подтверждён, у сайта в результатах поиска появляется предупреждение. Оно убивает переходы задолго до того, как упадут позиции: человек видит красную строчку и не кликает.
При этом взлом сам по себе не обнуляет историю домена и не даёт вечного «бана». Вопрос в скорости: чем дольше спам живёт в индексе, тем дольше возвращаются позиции.
Первые двадцать минут: изоляция
Соблазн начать с удаления подозрительных файлов силён, и почти всегда это ошибка: пока не закрыт вход, вы удаляете, а скрипт создаёт заново. Порядок изоляции такой.
- Полная копия «как есть». Архив файлов и дамп базы до любых правок — не для восстановления, а как материал для расследования и источник случайно удалённого.
- Смена всех паролей. Панель хостинга, FTP и SSH, пользователь базы данных, администраторы WordPress. Пароль базы меняется вместе со строкой в
wp-config.php, иначе сайт ляжет. - Сброс сессий. Замена восьми констант-ключей в
wp-config.php(AUTH_KEYи остальные) разлогинивает всех, включая того, кто зашёл с украденной сессией. Строки генерируются на официальном сервисе ключей WordPress. - Удаление лишних администраторов и понижение ролей у всех, кому админка не нужна.
- Проверка задач cron в таблице опций: там часто прописан хук, который каждый час восстанавливает удалённый бэкдор. Пока он там, чистка бессмысленна.
Только после этого имеет смысл трогать файлы.
Где искать заражение в файлах WordPress
Заражений три типовых вида: подмена файлов ядра и темы, новые файлы-шеллы в загрузках и каталогах плагинов, генератор страниц — один скрипт, отдающий бесконечное число адресов без создания файлов.
| Где смотреть | Признак заражения | Что делать |
|---|---|---|
| Файлы ядра (корень, wp-admin, wp-includes) | Отличие от эталона той же версии, свежая дата изменения, длинная строка base64 в начале файла | Не чистить вручную. Скачать дистрибутив своей версии и перезалить каталоги целиком, кроме wp-content |
| wp-content/uploads | Файлы .php среди картинок, каталоги с бессмысленными именами, .htaccess внутри папок загрузок | PHP в загрузках не нужен никогда. Удалять, затем запретить исполнение через правило веб-сервера |
| Файлы темы (functions.php, header.php, footer.php) | Вставки eval, gzinflate, preg_replace с модификатором /e, вызовы file_get_contents к внешнему домену | Сравнить с копией темы из репозитория или из своего бэкапа, вернуть чистую версию |
| Каталоги плагинов | Плагин, которого нет в списке в админке; папка с датой изменения свежее остальных | Удалить плагин целиком и поставить заново из официального источника |
| .htaccess в корне | Правила RewriteCond по User-Agent или Referer, перенаправляющие переходы из поиска | Заменить файл на стандартный блок WordPress, сохранив свои правила отдельно |
| База данных | Скрипты в wp_options, чужой домен в siteurl, тысячи записей неизвестного типа в wp_posts | Правки только по дампу и с проверкой, что тип записи действительно не ваш |
Быстрее всего заражение находится сравнением с эталоном, а не глазами: для ядра это официальный архив нужной версии, для плагинов — их же дистрибутивы. Файлы, которых нет ни в одном эталоне, изучаются первыми. Типовые точки входа собраны в материале про способы взлома сайта: в девяти случаях из десяти дырой оказывается не WordPress, а заброшенный плагин.
Чистка без поломки сайта
Главное правило чистки: не удалять то, что не опознано. Файл с непонятным именем может оказаться частью коммерческого плагина, а строка кодировки в теме — легальной защитой лицензии. Удалили — сайт отдал белый экран, и вы чините уже две проблемы вместо одной.
Порядок такой. Перезаливаются каталоги ядра из официального дистрибутива той же версии — wp-admin, wp-includes и файлы в корне, кроме wp-config.php и .htaccess. Плагины именно переустанавливаются, а не обновляются: обновление поверх заражённого каталога оставляет лишние файлы на месте. Тема возвращается к чистой версии, свои правки переносятся из дочерней.
Дальше — база. Записи неизвестного типа удаляются запросом с явным указанием типа и статуса, а не «всё, что новее такой-то даты». В опциях проверяются siteurl, home, виджеты и автозагружаемые опции подозрительного размера. В wp-config.php часто оставляют одну строку подключения внешнего файла в самом начале.
Последнее — права: каталоги 755, файлы 644, wp-config.php 600 или 400. Права 777, которые ставят «чтобы заработало», — самая частая причина повторного взлома через неделю после чистки. Остальные принципы собраны в материале о том, как защитить сайт от взлома.
Главная ошибка: файлы вычистили, индекс не тронули
На этом месте останавливается большинство. Сайт чистый, хостинг доволен, а позиции не возвращаются: поисковик ничего не знает о том, что вы поработали. В его индексе по-прежнему лежат тысячи страниц вашего домена, и лежать они будут, пока робот не переобойдёт каждую и не получит внятный ответ. Сам он сделает это за месяцы — у мусорных адресов низкий приоритет обхода. Задача — сообщить об их смерти явно и быстро.
Ключевой момент — какой ответ отдавать. После чистки адреса обычно начинают отдавать 404, а WordPress часто подменяет его редиректом на главную или на похожую запись. Это худший вариант: робот видит рабочую страницу и оставляет адрес в индексе. Почему так происходит — в материале про битые ссылки и неправильные редиректы.
| Тип мусора | Правильный ответ | Почему так |
|---|---|---|
| Сгенерированные спам-страницы (тысячи адресов по шаблону) | 410 Gone | Прямой сигнал «удалено навсегда». Обрабатывается быстрее 404 и не оставляет надежды на возврат |
| Единичные страницы, у которых был свой смысл до подмены | 200 с восстановленным содержимым | Адрес накопил сигналы, терять его незачем — достаточно вернуть нормальный текст |
| Спамные адреса, совпадающие по структуре с вашими разделами | 301 на профильный раздел | Работает, только если содержимое действительно близко. Иначе поисковик посчитает перенаправление некорректным |
| Адреса с параметрами, порождённые скриптом | 410 плюс запрет параметра в robots.txt | Число комбинаций бесконечно, точечное удаление не закончится никогда |
| Страницы, попавшие в индекс с чужого поддомена | Удаление поддомена и 410 на уровне сервера | Поддомен в панели Вебмастера — отдельный сайт со своей очередью на удаление |
Технически 410 для группы адресов удобнее всего ставить одним правилом на уровне сервера — по шаблону пути или по параметру, а не списком из четырёх тысяч строк. Правило проверяется до правки: адрес открывается через инструмент проверки ответа сервера в Вебмастере, и в ответе должен быть именно 410.
Переобход: как ускорить выброс мусора
После того как ответы настроены, остаётся заставить робота их увидеть. Инструментов три, и они дополняют друг друга.
Переобход страниц в Яндекс Вебмастере. Суточный лимит зависит от сайта, обычно это десятки адресов. Отправлять туда все четыре тысячи бессмысленно — отправляются самые заметные: те, что реально показываются в выдаче по спамным словам.
Инструмент удаления страниц. Работает, если адрес отдаёт 404, 410 или закрыт в robots.txt. Принимает и отдельные адреса, и префикс каталога — основной способ выбросить массовый мусор.
IndexNow. Протокол мгновенного уведомления работает в обе стороны: им сообщают не только о новых страницах, но и об изменившихся, включая удалённые. Если он уже настроен, отправка списка удалённых адресов ускоряет реакцию; подробности — в материале про IndexNow и моментальную индексацию.
Дальше — контроль. Раз в несколько дней повторяется запрос с оператором site и спамными словами, а в Вебмастере отслеживается число страниц в поиске: график должен идти вниз ступеньками. Стоит на месте через две недели — значит, часть адресов по-прежнему отдаёт 200; их ищут выгрузкой страниц в поиске и проверкой кодов по списку, порядок описан в разборе как проверить индексацию сайта в Яндексе. Параллельно запрашивается перепроверка в «Диагностике», иначе пометка в выдаче висит дольше нужного.
Что закрыть после чистки
Повторный взлом того же сайта — обычное дело, и происходит он не потому, что «плохо почистили», а потому, что не закрыли вход. Минимальный набор, который стоит сделать в тот же вечер, пока руки в деле.
- Обновить всё. Ядро, темы, плагины. Заброшенные плагины, которые не обновлялись больше года, удалить и заменить — именно они дают большинство дыр.
- Удалить неиспользуемое. Отключённый плагин остаётся исполняемым кодом на диске. Отключение не защищает, удаление защищает.
- Запретить PHP в загрузках. Правило веб-сервера, которое не отдаёт .php из каталога
wp-content/uploads, закрывает самый популярный способ закрепиться. - Отключить редактор файлов в админке строкой
define('DISALLOW_FILE_EDIT', true);вwp-config.php. Тот, кто получил доступ к админке, теряет возможность править код прямо из браузера. - Ограничить попытки входа и включить двухфакторную проверку для администраторов. Страницу входа при этом переименовывать не нужно — она должна остаться на стандартном адресе, иначе ломаются интеграции и восстановление доступа.
- Настроить резервные копии с хранением вне того же сервера и с глубиной хотя бы в тридцать дней. Копия за вчера бесполезна, если заражение произошло месяц назад и всё это время лежало тихо.
- Следить за числом страниц в поиске. Резкий рост — ранний сигнал, что адреса создаются без вашего ведома.
Про сроки. Мусор уходит из индекса за две–четыре недели при активной работе с переобходом, позиции возвращаются медленнее и не всегда полностью. Первых недель пугаться не стоит: падение идёт по инерции, пока индекс ещё содержит спам. Если через полтора-два месяца динамики нет, дело уже не во взломе, а в обычной технической части — с неё начинается любой бесплатный аудит сайта.
Частые вопросы
Хостинг сам почистил сайт антивирусом. Этого достаточно?
Недостаточно, и по двум причинам. Антивирус хостинга ищет сигнатуры известных шеллов и хорошо находит файлы, но почти никогда не трогает базу, задачи cron и лишних администраторов. Плюс он ничего не делает с индексом — а это и есть та часть, из-за которой позиции не возвращаются.
Можно ли просто восстановиться из бэкапа и забыть?
Можно, если копия точно старше заражения и вы знаете дату. Но откат возвращает и уязвимость, через которую вошли, поэтому сразу после восстановления обновляют всё и закрывают дыру. И в любом случае остаётся работа с индексом: бэкап сайта не откатывает индекс поисковика.
Ставить ли noindex на спам-страницы вместо 410?
Нет. Метатег noindex требует, чтобы страница открывалась и отдавала 200, то есть спам продолжает существовать. Для удалённого содержимого правильный сигнал — код ответа, а не метатег. Noindex уместен для своих служебных страниц, которые должны работать, но не показываться в поиске.
Закрыть весь сайт в robots.txt на время чистки — хорошая идея?
Плохая. Робот перестанет заходить и не увидит ни ваших исправлений, ни кодов 410, а страницы в индексе останутся замороженными в том виде, в каком были. Сайт должен оставаться открытым, чтобы переобход состоялся.
Спам вернулся через неделю после чистки. Где искать?
В трёх местах по порядку: запланированные задачи в таблице опций, файлы вне корня сайта (соседние домены на том же аккаунте хостинга) и учётные записи FTP, которые заводят отдельно от паролей панели. Если на аккаунте несколько сайтов, лечить нужно все сразу — иначе они перезаражают друг друга.
Насколько это вообще реально сделать самому за вечер?
Реально, если есть доступ по SSH, свежая копия и понимание, где что лежит. Если сайт коммерческий, заражение старше месяца или на аккаунте несколько проектов — быстрее разобрать ситуацию вместе: SEO-консультация по вашему сайту обычно закрывает вопрос о порядке действий за одну встречу. Дальше всё равно нужны месяцы обычной работы, и как она устроена — в разделе SEO-продвижение сайтов.
Коротко
- Взлом подтверждается снаружи: оператор site со спамными словами, скачок числа страниц в поиске, просмотр страницы глазами робота и свежие даты изменения PHP-файлов.
- Порядок обязателен: сначала изоляция (пароли, ключи сессий, лишние администраторы, задачи cron), потом чистка. В обратную сторону не работает — скрипт восстанавливает удалённое.
- Ядро и плагины не лечат вручную, а перезаливают из официальных дистрибутивов; вручную разбирают только тему, базу и
.htaccess. - Чистка файлов не убирает страницы из поиска. Массовому мусору нужен код 410, единичным подменённым страницам — восстановленное содержимое, и никаких редиректов на главную.
- Выброс из индекса ускоряют инструмент удаления страниц по префиксу каталога, переобход самых заметных адресов и IndexNow; контроль — по графику страниц в поиске.
- Повтор закрывают обновления, удаление неиспользуемых плагинов, запрет PHP в загрузках, отключение редактора файлов и бэкапы с глубиной от месяца — при сохранении стандартного адреса входа.
Увеличьте позиции и продажи вашего сайта
Профессиональное SEO-продвижение с гарантией результата. Выберите подходящую услугу:
Остались вопросы по продвижению?
Меня зовут Анатолий Кузнецов, я SEO-оптимизатор с 20-летним стажем. Разберу ваш сайт, отвечу на вопросы и подскажу, что улучшить для роста позиций в Яндексе и Google.
Связаться со мной →
Комментарии
Олимпиада Цуканова
В поиске 11 тысяч страниц вместо трёхсот, все про кредиты. Файлы почистил программист неделю назад, а число не падает совсем. Что я делаю не так?
Анатолий Кузнецов автор
Скорее всего, ничего дополнительно не делаете — а надо. Чистка файлов и удаление из индекса это две независимые задачи, вторая сама не запускается. Проверьте прямо сейчас: возьмите любой спамный адрес из выдачи и посмотрите код ответа сервера. Если там 200 или редирект на главную, робот считает страницу живой и никуда её не денет. Нужен 410 по шаблону пути — одним правилом на весь каталог, а не списком. После этого идите в инструмент удаления страниц в Вебмастере и отправляйте туда префикс каталога, он принимает целые разделы. График страниц в поиске начнёт спускаться ступеньками через несколько дней, это нормальная скорость.
Ярополк Юрлов
Смотрю сайт в браузере — всё чисто. Но в выдаче вместо моих заголовков какая-то реклама букмекеров. Как такое возможно?
Анатолий Кузнецов автор
Это клоакинг, самый неприятный вариант заражения именно потому, что глазами его не поймать. Скрипт смотрит на User-Agent и на источник перехода: обычному посетителю отдаёт вашу страницу, роботу и переходу из поиска — спамную. Проверяется двумя способами. Первый — инструмент «Просмотр как робот» в Вебмастере, он покажет ровно то, что видит поисковик. Второй — открыть страницу в режиме инкогнито, перейдя на неё именно из поисковой выдачи, а не по прямому адресу. Код при этом обычно сидит в .htaccess в виде правил RewriteCond по User-Agent или в начале index.php одной длинной строкой. Начните с этих двух файлов.
Вениамин Ремезов
Вопрос по таблице: почему 410, а не 404? В документации пишут, что для поисковика разницы почти нет.
Анатолий Кузнецов автор
Разница есть, и она в скорости, а не в конечном результате. 404 означает «сейчас не найдено» — робот допускает, что страница вернётся, и заходит проверять её ещё несколько раз, растягивая удаление на недели. 410 означает «удалено навсегда», и повторные проверки сокращаются. На объёме в три сотни адресов вы разницу не заметите, на объёме в несколько тысяч она превращается в лишний месяц. Плюс чисто практический момент: 410 вы ставите правилом сервера осознанно, а 404 в WordPress легко превращается в редирект или в страницу с кодом 200 из-за плагина или темы, и об этом узнают слишком поздно.
Калерия Ушанова
Удалила всё подозрительное из uploads, сайт лёг белым экраном. Восстановила из бэкапа вместе с вирусом. Теперь боюсь трогать.
Анатолий Кузнецов автор
Белый экран после удаления — почти всегда признак того, что удалён файл, который где-то подключается через include. Лечится это не возвратом всего архива, а точечно: включите вывод ошибок в wp-config, откройте сайт, и PHP прямо назовёт путь к отсутствующему файлу. Дальше решайте по имени: если это часть плагина — переставьте плагин целиком, если непонятная вставка — уберите строку подключения из того файла, который её вызывает. И порядок на будущее: копия делается перед чисткой, чистка идёт от ядра к плагинам и только потом к загрузкам, а после каждого шага сайт открывается и проверяется. Тогда вы всегда знаете, какое именно действие что сломало.
Пелагея Гвоздарёва
Нашла в wp_options задачу, которая каждый час дёргает какой-то внешний адрес. Удалять прямо в phpMyAdmin или это опасно?
Анатолий Кузнецов автор
Удалять можно, но аккуратно и не всю опцию целиком. В строке cron лежит сериализованный массив со всеми задачами сайта, включая легальные — проверку обновлений, отправку писем, работу плагинов. Если стереть значение полностью, WordPress пересоберёт его сам, но часть плагинов свои задачи потеряет до следующей активации. Правильнее убрать конкретный хук: сделать дамп таблицы, открыть значение, найти имя задачи с внешним адресом и удалить только её ветку, сохранив структуру массива. И обязательно найдите файл, который эту задачу регистрирует, иначе она вернётся при первом же обращении к сайту.
Трифон Ефимцев
У меня на аккаунте хостинга шесть сайтов. Заражённым выглядит один. Проверять остальные обязательно?
Феодора Зюзина
Обязательно. У нас была ровно такая история: почистили один, через десять дней он заразился снова с соседнего домена на том же аккаунте. Лечить надо все разом и в один заход.
Герасим Наливкин
Совет из практики: сохраните список всех страниц в поиске выгрузкой из Вебмастера ДО чистки. Потом по нему удобно проверять коды ответа скриптом и видеть, что осталось живым.
Демьян Пестов
Про права 777 отдельное спасибо. Хостинг сам предлагал их поставить, когда не работала загрузка картинок. Поставил, через месяц получил всё описанное.
Тамила Оглоблина
А как быть, если сайт был заражён полгода и половина спамных адресов уже набрала внешние ссылки? Они же так и будут стучаться.
Никанор Хомутов
Будут, но это не страшно. Внешние ссылки на несуществующие адреса просто дают 410 и постепенно перестают учитываться. Хуже, когда такие адреса продолжают отдавать 200 через кэш плагина, который забыли сбросить.
Юстина Шелестова
Не хватает раздела про почту. У нас после взлома домен попал в спам-листы, письма с форм перестали доходить, и заметили это только через три недели по отсутствию заявок.