Многие пользователи полагают, что активация виртуальной частной сети гарантирует абсолютную изоляцию трафика исключительно за счет криптографии. Современные алгоритмы, такие как ChaCha20-Poly1305 и AES-256-GCM, математически надежно защищают полезную нагрузку от перехвата в физической среде передачи. Однако криптографические функции не определяют направление движения пакета. Решение о том, через какой интерфейс отправлять данные, принимает исключительно таблица маршрутизации ядра операционной системы.

В 2023 году группа исследователей в составе Мати Ванхуфа, Нянь Сюэ, Яшасви Малла, Цзыхан Сяо и Кристины Нита-Ротару представила фундаментальное исследование архитектурных уязвимостей VPN, получившее название TunnelCrack. Зафиксированные как CVE-2023-36664 и CVE-2023-35838, эти сценарии демонстрируют, как ненадежная локальная сеть или мошенническая точка доступа Wi-Fi может манипулировать системными правилами маршрутизации, направляя трафик целевых служб мимо шифрованного туннеля в открытом виде.

Для понимания природы проблемы необходимо детально разобрать две основные разновидности атаки: LocalNet и ServerIP.

+-----------------------------------------------------------------------------+
|                     СХЕМА УТЕЧКИ МАРШРУТИЗАЦИИ LOCALNET                     |
|                                                                             |
|  [Устройство пользователя]                                                  |
|         │                                                                   |
|         ├── Назначение: Публичный IP-адрес (например, 142.250.190.46)       |
|         │                                                                   |
|         ▼                                                                   |
|  [Решение таблицы маршрутизации ядра]                                       |
|         │                                                                   |
|         ├─► Маршрут A: Туннель VPN по умолчанию (0.0.0.0/1 через utun0)     |
|         │                                                                   |
|         └─► Маршрут B: Локальная подсеть LocalNet (142.250.0.0/16 wlan0)    |
|                    (Приоритет наибольшего совпадения префикса LPM)          |
|                                                                             |
|         ▼                                                                   |
|  [Физический адаптер: wlan0] ───────────────► [Шлюз точки Wi-Fi]            |
|  (Нешифрованные кадры Ethernet идут наружу)   (Перехват трафика)            |
+-----------------------------------------------------------------------------+

Атака LocalNet (CVE-2023-36664): злоупотребление исключениями локальной сети

Уязвимость LocalNet связана с функциональностью доступа к локальной сети, реализованной во многих клиентских приложениях. При подключении дома или в офисе пользователям требуется взаимодействие с сетевыми принтерами, локальными накопителями NAS или смарт-устройствами. Для поддержки таких сценариев операционные системы создают прямые маршруты канального уровня для локальной подсети.

При подключении к беспроводной сети DHCP-сервер передает конфигурацию: IP-адрес, маску подсети и шлюз. В стандартных условиях используется приватный диапазон RFC 1918, например 192.168.1.0/24. Ядро системы автоматически добавляет маршрут:

192.168.1.0/24 dev wlan0 proto kernel scope link src 192.168.1.105

Параметр scope link указывает ядру, что пакеты в пределах 192.168.1.0/24 доставляются локально без обращения к внешнему шлюзу. Клиентское ПО обычно оставляет этот маршрут активным либо вносит его в список исключений для сохранения сетевых сервисов.

Злоумышленник, контролирующий точку доступа, объявляет произвольный диапазон публичных IP-адресов в качестве локальной подсети. Например, мошеннический DHCP-сервер назначает устройству адрес из блока 142.250.0.0/16 с маской 255.255.0.0:

# Ядро устанавливает маршрут для публичного диапазона на физическом интерфейсе
142.250.0.0/16 dev wlan0 proto kernel scope link src 142.250.10.45

Когда приложение или браузер обращается к серверу внутри этого диапазона, ядро сопоставляет записи в базе пересылки (FIB). В соответствии со стандартами IP-маршрутизации:

  1. Виртуальный интерфейс объявляет маршруты по умолчанию с префиксом /1 (0.0.0.0/1 и 128.0.0.0/1).
  2. Внедренная локальная запись имеет префикс /16, являющийся более специфичным, чем /1.
  3. По правилу Longest Prefix Match (наибольшее совпадение префикса) приоритет получает маршрут /16.

В результате пакет направляется напрямую через физический интерфейс wlan0. Защищенный туннель не задействуется, и трафик передается в открытом виде через узел злоумышленника.

Атака ServerIP (CVE-2023-35838): манипуляции со служебными маршрутами шлюза

В то время как LocalNet эксплуатирует параметры подсетей, уязвимость ServerIP направлена на механизм инициализации самого протокола туннелирования.

Чтобы передавать инкапсулированные пакеты через интернет к удаленному серверу, сетевой стек должен знать прямой путь к его внешнему IP-адресу. Если направить весь исходящий трафик в виртуальный интерфейс без исключений, инкапсулированные пакеты будут повторно направляться в туннель, вызывая циклическую рекурсию и разрыв связи.

Для предотвращения этого клиентские программы создают прямой маршрут хоста (/32 для IPv4 или /128 для IPv6) к IP-адресу сервера через физический шлюз:

# Маршрут хоста к серверу через локальный роутер
198.51.100.50/32 via 192.168.1.1 dev wlan0

Уязвимость возникает, если доменное имя сервера разрешается через ненадежные DNS-серверы локальной сети при установлении соединения:

  1. При старте подключения клиент отправляет DNS-запрос для получения IP-адреса шлюза.
  2. Поддельный DNS-сервер в локальной сети возвращает IP-адрес целевого ресурса, за которым планируется наблюдение.
  3. Клиент принимает этот ответ и добавляет маршрут /32 для указанного IP через интерфейс wlan0.
  4. Сессия с данным фиктивным узлом не устанавливается, однако трафик устройства к этому публичному ресурсу теперь направляется в открытом виде мимо шифрования.

Даже при использовании статических IP-адресов серверов злоумышленник может подделать DNS-ответы для других ресурсов, сопоставив их с адресом шлюза, что приведет к отправке данных через физический адаптер без защиты.

+-----------------------------------------------------------------------------+
|                      СРАВНЕНИЕ АТАК LOCALNET И SERVERIP                     |
+------------------------+----------------------------------------------------+
| Тип атаки              | Основной механизм эксплуатации                     |
+------------------------+----------------------------------------------------+
| LocalNet               | Крупные публичные маски подсетей через DHCP        |
| (CVE-2023-36664)       | Приоритет префикса перекрывает маршруты /1 туннеля |
|                        | Использование функции доступа к локальной сети     |
+------------------------+----------------------------------------------------+
| ServerIP               | Подмена DNS-ответов при инициализации соединения   |
| (CVE-2023-35838)       | Маршрут хоста /32 направляет данные наружу         |
|                        | Использование правил предотвращения рекурсии       |
+------------------------+----------------------------------------------------+

TunnelCrack и TunnelVision: различие векторов угроз

Важно отличать TunnelCrack от атаки TunnelVision (CVE-2024-3661). Хотя обе угрозы манипулируют таблицами маршрутизации, механизмы их реализации принципиально отличаются:

  • TunnelVision опирается исключительно на DHCP Option 121 (RFC 3442, классовые статические маршруты). Системы, игнорирующие опцию 121 по умолчанию (например, стандартный Android), не подвержены этой атаке.
  • TunnelCrack не требует специальных опций DHCP. Атака LocalNet использует стандартное поле маски подсети (RFC 2132), существующее с 1997 года. Поскольку обработка масок подсети обязательна для любого сетевого стека, TunnelCrack затрагивает широкий спектр платформ: iOS, macOS, Windows, Linux и Android.

Таблицы маршрутизации обрабатывают пакеты по длине маски, не учитывая уровень криптографической защиты. При наличии более специфичного маршрута на беспроводном адаптере ядро передает пакет в открытом виде.

Иерархия приоритетов в таблице маршрутизации ядра:
┌────────────────────────────────────────────────────────┐
│  Маршрут хоста (/32): Конкретный целевой IP (ServerIP) │  ◄── Наивысший приоритет
├────────────────────────────────────────────────────────┤
│  Локальная подсеть (/16, /24): LocalNet                │  ◄── Перекрывает туннель
├────────────────────────────────────────────────────────┤
│  Разделенный маршрут туннеля (/1): 0.0.0.0/1           │  ◄── Стандартный туннель
├────────────────────────────────────────────────────────┤
│  Основной шлюз (/0): 0.0.0.0/0                         │  ◄── Низший приоритет
└────────────────────────────────────────────────────────┘

Архитектурные меры нейтрализации уязвимостей

Эффективная защита от TunnelCrack требует комплексного подхода, выходящего за рамки простой модификации записей маршрутизации. Современные архитектуры применяют фильтрацию на уровне ядра, сетевые пространства имен и строгую привязку сокетов.

1. Межсетевой экран уровня ядра и функция аварийного отключения

Надежный механизм Kill Switch не должен полагаться только на приоритеты маршрутов. Требуется внедрение правил пакетного фильтра в ядре, отбрасывающих любые исходящие данные с физического адаптера, кроме инкапсулированных пакетов туннеля.

В Linux на базе nftables исходящий трафик через адаптер Wi-Fi жестко ограничивается:

# Разрешение только инкапсулированных UDP-пакетов туннеля через физический интерфейс
table inet vpn_filter {
    chain output {
        type filter hook output priority 0; policy drop;

        # Разрешение трафика интерфейсов loopback и туннеля
        oifname "lo" accept
        oifname "rice0" accept

        # Разрешение только шифрованного туннеля на физическом адаптере
        oifname "wlan0" udp dport 51820 ip daddr 203.0.113.10 accept
    }
}

В Windows платформа Windows Filtering Platform (WFP) блокирует нешифрованные пакеты на транспортном уровне до их передачи на сетевую карту. В macOS правила пакетного фильтра pf гарантируют обработку исходящих данных исключительно через виртуальный интерфейс.

2. Отключение доступа к локальной сети в публичных точках Wi-Fi

Поскольку атака LocalNet опирается на исключения локальной сети, безопасные клиенты отключают доступ к локальным ресурсам при работе в ненадежных сетях:

  • Клиент удаляет прямые маршруты канального уровня.
  • Весь трафик, включая обращения к приватным диапазонам, направляется в защищенный туннель.
  • Даже при назначении фиктивной подсети /8 через DHCP пакетный фильтр блокирует прямую передачу пакетов.

3. Сетевые пространства имен и привязка SO_BINDTODEVICE

В средах Linux и Android сетевые пространства имен обеспечивают строгую изоляцию. Физический сетевой адаптер перемещается в отдельное пространство имен, а приложения пользователя остаются в основном пространстве, где доступен только виртуальный интерфейс, исключая доступ к внешним сетевым интерфейсам.

Приложения также могут явно связывать сокеты с виртуальным интерфейсом с помощью системного вызова SO_BINDTODEVICE:

// Привязка сокета приложения к виртуальному интерфейсу
setsockopt(sock_fd, SOL_SOCKET, SO_BINDTODEVICE, "rice0", strlen("rice0"));

При жесткой привязке сокета ядро игнорирует общие записи таблицы маршрутизации и передает трафик непосредственно в указанный интерфейс.

Проверка устойчивости конфигурации к манипуляциям

Сетевые инженеры и пользователи могут самостоятельно протестировать систему на устойчивость к атакам TunnelCrack:

  1. Анализ активных маршрутов: Проверьте состояние таблицы маршрутизации до и после установления соединения на наличие подозрительных записей хоста или широких подсетей канального уровня:
    ip route show table all
    
  2. Тестирование поддельной подсети: На тестовом маршрутизаторе настройте выдачу публичного диапазона (например, 198.51.100.0/24) через локальный DHCP. Подключите устройство, запустите туннель и убедитесь, что трафик к 198.51.100.1 либо блокируется фильтром, либо направляется в туннель.
  3. Контроль параметров локального доступа: Убедитесь, что в используемом клиенте отключена опция видимости локальной сети при подключении к общественным точкам доступа.

Архитектура VPNRice объединяет протокол RiceGuard и ядро L3-туннелирования, гарантируя строгую изоляцию сокетов и многоуровневую фильтрацию. Любые попытки навязывания некорректных маршрутов нейтрализуются системным фильтром.

Для обеспечения надежной защиты рабочих станций и мобильных устройств загрузите актуальное приложение на странице Скачать VPNRice.