
Клиент звонит и говорит, что его сайт «перекидывает на казино». Вы открываете сайт — всё в порядке. Открываете с телефона — в порядке. Проверяете мониторинг — зелёный, за месяц ни одного сбоя. Клиент настаивает, вы начинаете думать, что у него вирус на телефоне.
Клиент прав. Просто сайт научили показывать вам одно, а посетителю из поиска — другое.
Клоакинг — это отдача разного содержимого разным посетителям по какому-то признаку. Приём сам по себе нейтральный: по нему же работает, например, показ мобильной версии. Проблема в том, что при взломе его используют, чтобы спрятать вредоносное поведение от владельца сайта.
Логика зловреда простая. Он определяет, кто пришёл, и решает, что показать:
Признаки, по которым делается выбор, почти всегда одни и те же.
User-Agent. Строка, которой браузер сообщает, кто он. Зловред смотрит, есть ли в ней признак мобильного устройства, и работает только для них. Причина прагматичная: на мобильных выше доля случайных посетителей и ниже вероятность, что кто-то откроет исходный код страницы.
Referer. Заголовок, в котором браузер сообщает, откуда посетитель пришёл. Если там поисковик — посетитель случайный, он не знает, как сайт выглядит обычно, и редирект его не удивит. Если Referer пустой (человек ввёл адрес руками) — скорее всего это владелец, ему показываем норму.
Cookie и частота визитов. Постоянному посетителю подмену не показывают — чтобы не вызвать подозрений.
Иногда добавляется задержка по времени: редирект включается ночью или через несколько секунд после загрузки, чтобы владелец, быстро проверивший сайт, ничего не заметил.
Здесь стоит признать неприятное, потому что это касалось и нас.
Проверка доступности запрашивает страницу и смотрит на код ответа и содержимое. Она приходит с одним и тем же User-Agent, обычно с честным именем бота, и без Referer. То есть выглядит ровно как тот посетитель, которому зловред показывает нормальный сайт. Мониторинг видит норму и честно об этом сообщает.
Вторая причина: серверный код мониторинга, как правило, не исполняет
JavaScript. Он получает HTML и анализирует его как текст. Если редирект сделан
серверно — через .htaccess или PHP — его видно по цепочке перенаправлений. Но
если он сделан скриптом внутри страницы, для такой проверки его просто нет.
Наша проверка доступности работала именно так: сравнивала конечный адрес после серверных перенаправлений. Сценарий «взлом с редиректом на казино, который видят только посетители из поиска» мы называли в собственных материалах, а ловили только в простейшей серверной форме.
Правильный способ поймать подмену — не проверить сайт один раз, а запросить одну и ту же страницу от лица разных посетителей и сравнить ответы. Если сайт отдаёт всем одно и то же, сравнивать нечего. Если разное — это и есть подмена.
Минимально достаточный набор:
Проверить руками можно через curl. Вот запрос от лица мобильного посетителя,
пришедшего из Яндекса:
curl -sSL -o /dev/null -w '%{url_effective}\n' \
-A 'Mozilla/5.0 (Linux; Android 14; Pixel 8) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Mobile Safari/537.36' \
-H 'Referer: https://yandex.ru/search/?text=example.ru' \
https://example.ru/
Флаг -w '%{url_effective}' покажет конечный адрес после всех перенаправлений.
Если там чужой домен — подмена найдена. Повторите тот же запрос с десктопным
User-Agent и без Referer: разница в ответе и есть доказательство.
Сравнивать стоит три вещи.
Конечный хост. Самый явный признак: одной персоне сайт отдаёт себя, другой — чужой домен.
Код ответа. Подмена не всегда редирект. Бывает, что мобильному отдаётся 200 с совершенно другой страницей, а иногда наоборот — вашему боту 200, а мобильному 302.
Скрытые переходы в разметке. Даже без исполнения JavaScript признаки видны в
коде страницы: присваивания location.href, location.replace(),
window.location, а также <meta http-equiv="refresh"> с чужим адресом.
Внутренние переходы на тот же домен — это норма, искать надо переходы на чужой
хост.
Проверяйте не только главную. Зловред часто живёт на страницах каталога или статьях — там, куда приходят из поиска. Главная может быть чистой.
Проверяйте с мобильным агентом и поисковым Referer. Без этих двух условий проверка почти бессмысленна: она смотрит ровно туда, где зловред прячется.
Не доверяйте своему браузеру. Ваш компьютер, скорее всего, уже помечен зловредом как «свой»: вы заходили на сайт напрямую, у вас есть cookie.
При жалобе клиента начинайте с воспроизведения его условий. Какое устройство, откуда пришёл, по какому запросу. «У меня всё работает» — это не проверка.
Проверяйте после взлома ещё несколько недель. Часть зловредов восстанавливается из планировщика или из базы, и возвращается через дни после чистки.
Мы добавили тип проверки «Подмена для посетителей из поиска». Она запрашивает страницу тремя персонами, описанными выше, и сравнивает ответы между собой: конечный хост, код ответа и скрытые переходы в разметке. Расхождение — сигнал. Referer подбирается по зоне домена: для российских — Яндекс, для остальных — Google.
Отдельно объясню, чего проверка не делает, потому что это важнее рекламы возможностей. Она не исполняет JavaScript. Мы сознательно не ставим в боевой контур headless-браузер: однажды осиротевший процесс браузера на нашем собственном сервере съел память, система ушла в swap, и мониторинг встал целиком. Цена такой проверки — три обычных запроса вместо запуска браузера.
Из этого следует граница: редирект, который возникает только после исполнения скрипта со сложной логикой — по таймеру, после касания экрана, после подгрузки внешнего файла — так не поймать. Мы ловим два самых частых случая: разный HTML в зависимости от User-Agent и Referer, и переход на чужой домен, видимый в разметке. По нашим наблюдениям это покрывает большинство реальных заражений, но исчерпывающей проверкой не является, и говорить об этом честнее, чем обещать полное покрытие.
Pingvera следит за сайтами клиентов «снаружи и изнутри» — доступность из регионов, формы, оплата, домен, SSL, сервер — и предупреждает в Telegram, email и Max раньше, чем напишет клиент.
Попробовать Pingvera бесплатно