Недавно я наткнулся на довольно интересный случай. На первый взгляд — обычное VPN-расширение для браузера: список стран, кнопка подключения, бесплатный сервер, платные серверы и подписка. Но мне стало интересно, что именно происходит после нажатия кнопки Connect. Я решил не ограничиваться интерфейсом и полез непосредственно в код расширения. И вот там уже стало интереснее.
Речь идёт о расширении TOP VPN.
Сразу скажу: я не буду утверждать, что это вредоносное расширение только на основании найденного worker.js. Но с точки зрения заявленной функции VPN здесь есть моменты, которые заставляют как минимум задуматься о том, что именно пользователь устанавливает себе в браузер.
Начинаем с worker.js
Основная логика находится в Service Worker:
/* Top VPN — Service Worker */ let relayActive = false; let chosenNode = null;
Дальше разработчики просто оставили список серверов непосредственно в JavaScript:
const SERVERS = [ { "id": "us-1", "name": "США 1", "countryCode": "US", "host": "103.35.189.225", "port": 1082, "premium": false }, { "id": "us-2", "name": "США 2", "countryCode": "US", "host": "103.35.191.173", "port": 1082, "premium": true } ];
И таких записей там достаточно много.
Например:
103.35.189.225:1082 103.35.191.173:1082 178.130.47.129:1082 80.92.204.33:1082 80.92.204.47:1082 5.180.30.122:1082 5.180.30.15:1082 86.104.74.110:1082 94.131.118.237:1082
Кроме IP-адресов встречаются и домены:
jp.neoncloak.space:1082 sg.neoncloak.space:1082 ca.neoncloak.space:1082 au.neoncloak.space:1082 tr.neoncloak.space:1082
То есть уже на этом этапе можно понять, что расширение работает с заранее определённой инфраструктурой. Но самое интересное находится чуть ниже.
Что происходит при подключении
Я дошёл до функции:
function engageTunnel(nodeId) { const node = SERVERS.find(function(s) { return s.id === nodeId; }); if (!node) return false;
Она получает идентификатор выбранной страны, находит соответствующий сервер и формирует конфигурацию proxy. Вот ключевой участок:
const config = { mode: "fixed_servers", rules: { singleProxy: { scheme: "socks5", host: node.host, port: node.port }, bypassList: BYPASS_LIST } };
Здесь для меня и начинается самое интересное. Расширение не устанавливает какой-то собственный VPN-протокол. Оно говорит браузеру:
используй SOCKS5 хост = указанный сервер порт = 1082
После чего применяет эту конфигурацию:
chrome.proxy.settings.set( { value: config, scope: "regular" }, function() { ... } );
Получается примерно такая схема:
┌──────────────┐ │ Chrome │ └──────┬───────┘ │ │ SOCKS5 ▼ ┌─────────────────────┐ │ 103.35.189.225:1082 │ └──────────┬──────────┘ │ ▼ Internet
И вот тут возникает вполне логичный вопрос:
а где здесь шифрование VPN?
SOCKS5 — это ещё не VPN
Я специально остановился на этом моменте, потому что здесь очень легко запутаться. Наличие socks5 в конфигурации не означает, что между пользователем и сервером автоматически создаётся защищённый VPN-туннель. SOCKS5 — это протокол прокси. Его задача — принять соединение клиента и передать его дальше. То есть:
Клиент ↓ SOCKS5 proxy ↓ Сайт
Это не то же самое, что:
Клиент ↓ зашифрованный VPN-туннель ↓ VPN-сервер ↓ Сайт
Именно поэтому я бы не стал называть найденную реализацию полноценным VPN только потому, что расширение называется TOP VPN.
Но HTTPS ведь всё равно шифруется?
Да. И здесь важно не перегнуть палку. Если я открываю:
https://example.com
то содержимое HTTPS-соединения защищается TLS между браузером и сервером сайта. SOCKS5 сам по себе не расшифровывает HTTPS. Поэтому утверждение:
«SOCKS5 полностью снимает шифрование с HTTPS»
было бы неправильным. Но это не означает, что оператор proxy ничего не видит. Proxy находится посередине сетевого соединения и видит сетевую метаинформацию, необходимую для работы соединения. А если приложение использует незашифрованный протокол, ситуация уже совсем другая.
Например:
HTTP ↓ SOCKS5 ↓ Internet
В таком случае данные могут проходить через proxy без защиты на уровне самого приложения. Поэтому здесь важно разделять шифрование HTTPS и защищённый VPN-туннель. Это совершенно разные вещи.
А кому тогда мы доверяем?
Вот это, пожалуй, главный вопрос, который я бы задавал при анализе любого неизвестного VPN.
Когда я использую обычное интернет-соединение:
Я → провайдер → Internet
а затем включаю такой proxy:
Я → SOCKS5-сервер → Internet
точка доверия меняется. Теперь часть сетевой информации проходит через сервер, который указан непосредственно в расширении. А эти адреса разработчик заранее положил сюда:
singleProxy: { scheme: "socks5", host: node.host, port: node.port }
То есть пользователь фактически доверяет владельцу этой proxy-инфраструктуры. И здесь я бы уже не стал слепо верить надписи VPN в интерфейсе.
Интересная деталь с neoncloak.space
Есть ещё одна вещь, которая привлекла моё внимание. После установки расширение открывает:
chrome.tabs.create({ url: "https://neoncloak.space/", active: true });
При этом часть серверов тоже использует домен:
jp.neoncloak.space sg.neoncloak.space ca.neoncloak.space au.neoncloak.space tr.neoncloak.space
То есть в одном месте у меня получается:
TOP VPN │ ├── worker.js │ ├── SOCKS5 │ ├── neoncloak.space │ └── *.neoncloak.space
Само по себе это, конечно, не является доказательством чего-либо плохого. Но для меня это хороший повод продолжить исследование инфраструктуры.
Бесплатный сервер и Premium
Ещё одна интересная деталь находится прямо в конфигурации:
"premium": false
Например:
{ "id": "us-1", "name": "США 1", "countryCode": "US", "host": "103.35.189.225", "port": 1082, "premium": false }
А другие серверы имеют:
"premium": true
Получается достаточно простая модель:
US-1 ↓ бесплатный US-2 US-3 DE-1 DE-2 ... ↓ Premium
При этом само расширение называется TOP VPN, а для платной подписки пользователю предлагают Myxa VPN. Вот это сочетание мне уже показалось достаточно странным. Получается несколько разных названий:
TOP VPN Myxa VPN neoncloak.space
И я бы точно не стал делать вывод, что это разные независимые продукты, пока не посмотрел их инфраструктуру и код.
Что происходит при отключении
Здесь всё достаточно просто. При отключении расширение возвращает браузеру системную proxy-конфигурацию:
function releaseTunnel() { chrome.proxy.settings.set({ value: { mode: "system" }, scope: "regular" }, function() { relayActive = false; chosenNode = null; chrome.action.setBadgeText({ text: "" }); }); }
То есть:
VPN ON Chrome ↓ SOCKS5 ↓ server
а после выключения:
VPN OFF Chrome ↓ System Proxy ↓ Internet
Никакой сложной логики здесь нет.
Что в итоге получилось
Когда я впервые увидел расширение, я ожидал найти обычную VPN-реализацию.
Вместо этого в worker.js обнаружился достаточно простой механизм:
выбрали страну ↓ нашли IP/домен ↓ выбрали порт 1082 ↓ SOCKS5 ↓ chrome.proxy.settings.set()
И всё. Поэтому я бы не писал, что «это точно вредоносный VPN» — для такого вывода одного worker.js недостаточно. Но назвать его полноценным VPN с собственной защищённой туннельной реализацией по этому коду я тоже не могу. Фактически перед нами браузерное расширение, которое перенаправляет трафик через заданные SOCKS5-серверы. И для меня это хороший пример того, почему при выборе VPN нельзя ориентироваться только на интерфейс и красивую кнопку ON. Я бы всегда сначала посмотрел, что находится под капотом.
Потому что между:
«Я включил VPN»
и:
«Я установил SOCKS5 proxy, принадлежащий неизвестному оператору»
есть довольно большая разница. И именно эту разницу обычный пользователь, скорее всего, вообще не увидит.

