Содержание статьи
Представь: ты заходишь на официальную страницу банка, чтобы проверить баланс, и еще до загрузки этой страницы в твоем браузере выполняется скрипт, который инициирует сетевые проверки, а ты любуешься на пустой экран в ожидании.
Это не ошибка и не случайность, а осознанная стратегия защиты, которую сегодня можно встретить у ряда сервисов. Именно с такой штукой столкнулась наша команда пару месяцев назад.
Подозрительная активность
В сентябре 2025 года мы получили приглашение на CTF-соревнование с домена alfa.me. Профессиональная деформация сделала свое дело: вместо того чтобы просто принять приглашение, мы стали изучать сам сайт и нашли много интересного.
Мы включили Burp Suite, чтобы мониторить весь трафик и замечать возможные аномалии. Именно в этот момент и проявилась та самая активность, которая и потребовала отдельного, более глубокого исследования.



Скрипты загружались с серверов Servicepipe.ru — компании, предоставляющей решения для защиты веб‑приложений.


Подобная активность — элемент современной защиты: используется агрессивное сканирование портов, чтобы выявлять ботов и сомнительный трафик. Мы решили подробнее разобраться с тем, что делает этот скрипт.
Анализ в Burp показал, что такие решения технически очень сложны. Они используют WebSocket-соединения для обхода сетевых фильтров, кодируют передаваемые данные через XOR и Base64, применяют хеши MD5 для проверки целостности и внедряют механизмы противодействия отладке. Многоуровневая обфускация здесь не побочный эффект, а полноценный инструмент защиты: сложность кода специально повышена, чтобы затруднить анализ.
Что это за скрипт?
Этот JavaScript загружается до показа основной информации о банковских услугах: он стоит в приоритетном месте и обрабатывается на раннем этапе парсинга HTML. Код подтягивается с внешнего домена servicepipe. через тег < и выполняется синхронно, блокируя дальнейшую загрузку страницы до окончания своей работы. Похоже, безопасность поставлена выше удобства пользователя.

Внутри скрипта применено несколько слоев кодирования: сначала данные конвертируются в Base64, затем шифруются динамическим ключом XOR и представляются в виде шестнадцатеричных строк. Одновременно пользователь видит GIF-анимацию загрузки, которая скрывает активность скрипта.
Ключевая логика проверок ясна. Реальные пользователи работают с настоящих устройств, где открыты стандартные сервисные порты. Боты же чаще запускаются в изолированных средах, где такие порты закрыты. Сканирование 3389 (RDP), 5900/5901 (VNC) используется как своеобразный отпечаток пальца, позволяющий отличить живого пользователя от автоматизированной системы.
Кому как, а нам не очень нравится, когда кто‑то начинает сканировать порты без нашего разрешения. Поэтому мы решили расковырять этот скрипт, чтобы посмотреть, как он устроен изнутри, как работает и какую информацию собирает.
Технический анализ
Сработавший в нашем браузере скрипт — это JavaScript-модуль, реализованный как IIFE (Immediately Invoked Function Expression): самовыполняющаяся функция, которая запускается сразу при загрузке скрипта. Такой прием позволяет выполнить код, не оставляя следов в глобальной области видимости браузера, и тем самым затрудняет его анализ.
Для скрытия логики применяется структурная обфускация: переменные сведены к однобуквенным идентификаторам, функции создаются динамически через Function(, а основная логика разбита на десятки мелких вложенных фрагментов. В результате исследователь сталкивается не с цельным кодом, а с запутанным пазлом, где каждая часть скрывает следующую.
Применяются и антиотладочные приемы: код обнаруживает инструменты разработчика, блокирует попытки отладки и даже создает «фантомные» дебаггеры с ложными точками останова. В совокупности это превращает модуль в защитный барьер, где обфускация и криптография сочетаются с приемами, затрудняющими и психологически осложняющими работу исследователя.

Код сканирует несколько критически важных портов:
- 3389 (RDP) — удаленный доступ к рабочему столу;
- 5900/5901 (VNC) — протоколы удаленного управления, часто используемые для администрирования рабочих станций;
- 135 (RPC) — удаленный вызов процедур;
- 7070 (XMPP и AnyDesk в корпоративном контексте) — порт, через который проходят коммуникации и удаленный доступ к рабочим средам.
Если бы перед нами был код, написанный злоумышленниками, выбор портов был бы обусловлен практическими соображениями: каждую из этих служб хакер может попытаться использовать для атаки, захвата удаленного управления и эскалации привилегий.
Для защитного решения открытые порты и запущенные на них сервисы — это индикаторы реального физического устройства; их отсутствие может указывать на изолированную или автоматизированную среду (sandbox, headless, контейнер).
Подобное сканирование, на наш взгляд, имеет серьезные риски и вызывает вопросы законности. Пассивное наблюдение за локальными сервисами и активное сканирование без явного согласия пользователя затрагивают конфиденциальность и могут восприниматься как вмешательство в систему.
Кроме того, сканирование увеличивает поверхность атаки — если запущенный в браузере клиента код уязвим, хакеры смогут попытаться использовать его в своих интересах. Как минимум появляются сложности с соблюдением требований по защите данных. В общем, такая «проактивная» защита может сама превратиться в угрозу для безопасности и приватности пользователей.
Логика работы
Код использует систему временных задержек: попытки подключения идут с интервалом 5 мс. Такая скорость позволяет просканировать все целевые порты за доли секунды, при этом сканирование почти не влияет на производительность и не вызывает заметных задержек у пользователя.
Почему именно 5 мс? Это компромисс между агрессивностью и стабильностью. Более короткий интервал может вызвать сетевые ошибки и некорректную обработку пакетов, интервал длиннее снизит эффективность защиты и станет еще более ощутимым для пользователя.
При обнаружении признаков вмешательства или управления код переходит в режим имитации человеческой активности: он делает паузу в 2,5 с, что снижает вероятность срабатывания поведенческих детекторов.

Сканирование организовано асинхронно с использованием promises (async/await), fetch, WebSocket и неблокирующих таймеров, поэтому пользовательский интерфейс может продолжать работать, а операции выполняются в фоне без блокировки рендеринга. Это позволяет скрипту после загрузки продолжать незаметно работать, не привлекая к себе лишнее внимание.
Помимо прочего, скрипт выполняет запросы к расширениям браузера, чтобы выяснить, установлены ли блокировщики рекламы или всплывающих окон.

Тайминги адаптируются под ситуацию: если порт открыт, задержка между действиями увеличивается, что позволяет более детально обследовать сервис и собрать дополнительные признаки его работы. Если ответа нет, задержки сокращаются, чтобы ускорить проверку оставшихся портов.
Такой подход сокращает первичную задержку и позволяет повысить точность профилирования, но увеличивает этические и юридические риски, поскольку метод требует активного взаимодействия с локальными сервисами.
Продолжение доступно только участникам
Материалы из последних выпусков становятся доступны по отдельности только через два месяца после публикации. Чтобы продолжить чтение, необходимо стать участником сообщества «Xakep.ru».
Присоединяйся к сообществу «Xakep.ru»!
Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее
