Хостер заблокировал аккаунт за вредоносную активность и прислал список зараженных файлов. Самое частое решение: удалить файлы из списка и попросить разблокировку. Через несколько дней все возвращается. В одной из моих чисток в списке хостера было 2 файла из примерно 25 работавших закладок, зато там же был помечен штатный файл Битрикса, без которого сайт падает целиком. Чтобы заражение не вернулось, чистить надо по-другому.
Как выглядит взломанный сайт
Чаще всего никак. Все разделы открываются, ошибок нет, владелец заходит на сайт и видит обычную страницу. При этом:
- сайт падает в поиске Google или страницы выпадают из индекса;
- в Search Console появляются чужие адреса или меры за спам;
- хостер присылает уведомление о вредоносной активности или блокирует аккаунт.
Это клоакинг: подмена показывается только поисковому роботу. Посетителям из определенных стран дополнительно может включаться переадресация на чужой магазин. Обычная проверка в браузере заражение не покажет.
Проверка одной командой
Запросить главную страницу дважды: как Googlebot и как обычный браузер.
curl -s -A "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" https://example.ru/ -o gb.html -w "%{size_download}\n"
curl -s -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/131.0" https://example.ru/ -o br.html -w "%{size_download}\n"
grep -o -i "<title>[^<]*</title>" gb.html br.html
Если размер ответа и заголовок страницы различаются, клоакинг есть. В разобранном случае робот получал 183 КБ с японским заголовком про копии люксовых часов, браузер 54 КБ обычной главной.
Три уточнения:
- проверяйте и Яндекс: подмена часто ловит только Google, YandexBot получает чистую страницу;
- подмена бывает навешана только на главную, внутренние страницы чистые;
- проверку лучше делать с самого сервера. Серия запросов с подделанным Googlebot снаружи может закончиться баном вашего IP фаерволом хостинга.
Где прячут закладку
Главная цель - файл, который выполняется на каждом запросе: bitrix/modules/main/include/prolog.php. Чужой код ставится в самое начало, до подключения движка. Оригинальный файл короткий, около 380 байт, и все, что стоит выше строки require_once, лишнее.
Самого спамного текста на сайте нет. Он подтягивается на лету с другого взломанного сайта, поэтому поиск по словам из подмены ничего не найдет.
Другие места, которые я находил:
- языковые файлы в глубине
bitrix/, которые никто не открывает; - редко используемые каталоги мастеров и публичных шаблонов;
- PHP-файлы в каталогах картинок;
- PHP внутри настоящей картинки: валидный PNG, после заголовка которого лежит код. Сам он не выполняется, его подключает однострочная закладка в безобидном файле страницы;
- первая строка включаемой области: обычный текст страницы, а перед ним одна строка PHP;
- вложенные каталоги-двойники вида
kontakty/kontakty/; .htaccessдвух видов. Одни разрешают выполнять PHP в каталоге со шеллом. Другие запрещают весь PHP, кроме шеллов атакующего, и заодно ломают штатные скрипты Битрикса в этом каталоге.
Почему антивирус хостинга не помогает
Он ищет сигнатуры известных шеллов и пропускает:
- короткие врезки в рабочие файлы: 900 байт внутри
prolog.phpни под одну сигнатуру не подходят; - незнакомые ему обфускаторы;
- честные файловые менеджеры, которые используются как шелл;
- PHP в картинках и однострочные закладки;
.htaccess.
И при этом он может пометить штатный файл Битрикса bitrix/modules/main/lib/security/w/wwall.php. Это встроенный фаервол Битрикса, его код закрыт лицензионной обфускацией, и он скачивает правила с серверов Битрикса. Для эвристики антивируса это выглядит как троян. Удалять его нельзя: ядро вызывает его на каждом запросе, и без него падают все страницы. Правильно добавить файл в исключения сканера и объяснить хостеру.
Поэтому список хостера это отправная точка, а не задание на чистку.
Порядок работ
1. Ничего не удалять сразу
Сначала снять картину, потом менять. Все изменения вести скриптом с журналом действий и списком контрольных сумм. Если перезаписать зараженный файл до того, как сделана копия, образец потерян, а вместе с ним и понимание, как вас взломали.
2. Посмотреть весь аккаунт, а не один сайт
ls -la ~/domains/*/public_html/bitrix # не общее ли ядро у нескольких сайтов
crontab -l # чужие задания по расписанию
cat ~/.ssh/authorized_keys # чужие ключи
grep -rn "auto_prepend_file" ~/domains --include=.htaccess --include=.user.ini
Если bitrix на боевом сайте это ссылка на ядро тестового, то дыра на тесте автоматически работает на боевом.
3. Искать по дате изменения метаданных, а не по дате файла
Дату файла подделывают одной командой touch. В одном случае набор шеллов стоял с датой ровно на два года раньше реальной, секунда в секунду. Дату изменения метаданных (ctime) так не подделать, она меняется при любой записи.
find ~/domains -type f \( -iname "*.php*" -o -name ".htaccess" \) -newerct "2026-08-01" \
! -path "*/cache/*" ! -path "*/managed_cache/*" \
-printf "%CY-%Cm-%Cd %CH:%CM | %TY-%Tm-%Td | %s | %p\n" | sort
Самый сильный признак - файлы, у которых дата файла старше даты метаданных больше чем на сутки. Значит, дату подделали:
find ~/domains -type f -newerct "2026-08-01" -printf "%C@ %T@ %p\n" | awk '($1-$2)>86400'
4. Сигнатуры и картинки
Шаблоны держать в файле, а не в командной строке: при запуске через ssh экранирование ломается, и grep молча ничего не находит. Проверьте шаблоны на заведомо зараженном файле.
grep -rlIE -f sig.txt --include="*.php" ~/domains
find ~/domains -type f -size -3M \( -iname "*.png" -o -iname "*.jpg" -o -iname "*.gif" -o -iname "*.ico" \) \
! -path "*/resize_cache/*" -exec grep -laE "<\?php|eval\(" {} +
В sig.txt строки вида eval\(base64_decode, eval\(gzinflate, eval\(\$_(POST|GET|REQUEST|COOKIE), Priv8, YAK Pro.
Найдя один файл, ищите его копии по всему аккаунту: по контрольной сумме, имени и уникальным строкам. Раскладка обычно веерная, одинаковые копии лежат на всех сайтах.
5. Карантин вместо удаления
Подозрительные файлы переносить в отдельный каталог с сохранением путей и списком контрольных сумм. Перед запуском антивируса хостера карантин зашифровать: антивирус проверяет весь домашний каталог и найдет шеллы в открытой папке.
Файлы ядра восстанавливать из оригинала. Эталоны для сверки: официальные пакеты обновлений в bitrix/updates/, чистая копия ядра на соседнем сайте, резервная копия.
После карантина прогнать все поиски заново.
6. Сменить доступы одновременно с чисткой
Не после, а вместе:
- пароль панели хостинга и SSH, завершить все сеансы, включить двухфакторный вход;
- пользователи FTP: лишних удалить, остальным новые пароли;
- администраторы сайта: проверить список, лишних отключить;
- пароль базы данных;
- ключи платежных систем и API, которые лежат в файлах сайта. Шелл их читал.
7. Проверить результат и следить неделю
- проверка подмены с сервера под Googlebot и браузером, все разделы, оплата;
- неделю каждый день поиск новых файлов по ctime в ядре и корнях сайтов. Если закладки восстанавливаются, значит остался канал;
- Search Console: чужие подтверждения домена, ручные меры, удаление мусорных адресов.
Грабли
Чистка не закончена, пока жив хоть один шелл на любом сайте аккаунта. Все сайты на одном аккаунте работают под одним пользователем, и шелл на заброшенном поддомене пишет в ядро боевого сайта. В одном случае каталог появился снова через 0,26 секунды после переноса, а врезка в ядро вернулась через три дня. Причиной были несколько шеллов на других доменах того же аккаунта.
Журналы хостер хранит недолго, иногда около 15 дней. Снимайте их в первые дни, иначе выяснить, как вас взломали, будет не по чему.
Отсутствие записей в журнале одного сайта ничего не доказывает, если у остальных сайтов журналов нет вообще.
Сколько это занимает
По моим двум последним чисткам: около 6 часов до письма хостеру (поиск и карантин, разбор находок и ложных срабатываний, шифрование и итоговая проверка, разбор блокировки) и еще 3-4 часа после разблокировки (пароли, проверка сайта и оплаты, контроль, поиск точки входа). На аккаунте с одним сайтом обычно быстрее.
Список для проверки
- Сравнили ответ сайта для Googlebot и для браузера?
- Посмотрели все сайты аккаунта, а не только тот, на который жаловались?
- Искали по ctime, а не по дате файла?
- Проверили картинки и
.htaccess? - Сменили все пароли вместе с чисткой?
- Не удалили штатные файлы Битрикса по списку антивируса?
- Следите за новыми файлами хотя бы неделю?
Если хостер уже заблокировал ваш сайт или вы видите подозрительные признаки, напишите мне. Начну с проверки подмены и списка того, что лежит на аккаунте, это занимает около часа.