Вразливість, що дозволяє вклинюватися в TCP-з'єднання, що здійснюються через VPN-тунелі

Опубліковано техніка атаки (CVE-2019-14899), що дозволяє підмінити, змінити або підставити пакети TCP-з'єднання, що прокидаються через VPN-тунелі. Проблема торкається Linux, FreeBSD, OpenBSD, Android, macOS, iOS та інші Unix-подібні системи. Linux підтримує механізм rp_filter (reverse path filtering) для IPv4, включення якого в режим Strict нейтралізує цю проблему.

Метод дозволяє здійснити підстановку пакетів на рівні TCP-з'єднань, що проходять усередині шифрованого тунелю, але не дозволяє вклинюватися в з'єднання, що застосовують додаткові шари шифрування (наприклад, TLS, HTTPS, SSH). Застосовувані в VPN алгоритми шифрування немає значення, оскільки підроблені пакети надходять із зовнішнього інтерфейсу, а обробляються ядром як пакети з VPN-інтерфейсу. Найбільш вірогідною метою атаки є втручання у незашифровані з'єднання HTTP, але не виключається та використання атаки для маніпуляції з відповідями DNS.

Успішна заміна пакетів продемонстрована для тунелів, створюваних за допомогою OpenVPN, WireGuard та IKEv2/IPSec.Tor проблемі не схильний, оскільки використовує SOCKS для прокидання трафіку та прив'язку до loopback-інтерфейсу. Для IPv4 атака можлива у разі переведення rp_filter в режим Loose (sysctl net.ipv4.conf.all.rp_filter = 2). Спочатку в більшості систем застосовувався режим Strict, але починаючи з systemd 240, випущеного в грудні минулого року, режим роботи за замовчуванням був замінений на «Loose» і ця зміна відобразилася в налаштуваннях за замовчуванням багатьох дистрибутивів Linux.

Механізм rp_filter застосовується для додаткової перевірки шляхів проходження пакетів для запобігання спуфінгу адреси джерела. При установці значення 0 перевірка адреси джерела не проводиться і будь-який пакет може без обмежень перенаправлятися між мережними інтерфейсами. Режим 1 «Strict» включає перевірку кожного пакету, що приходить ззовні на відповідність таблиці маршрутизації, і якщо мережевий інтерфейс, через який був отриманий пакет, не пов'язаний з оптимальним маршрутом доставки відповіді, то пакет відкидається. Режим 2 "Loose" пом'якшує перевірку, щоб допустити роботу при застосуванні балансувальників навантаження або асиметричної маршрутизації, при якій
маршрут відповіді може проходити через той мережевий інтерфейс, через який надійшов вхідний пакет.

У режимі «Loose» вхідний пакет перевіряється на відповідність таблиці маршрутизації, але вважається припустимим, якщо адресу джерела можна досягти через будь-який наявний мережний інтерфейс. Запропонована атака будується на тому, що атакуючий може відправити пакет із підміненою адресою джерела, що відповідає інтерфейсу VPN, і незважаючи на те, що даний пакет надійде в систему через зовнішній мережевий інтерфейс, а не через VPN, в режимі rp_filter Loose такий пакет не буде відкинуто.

Для здійснення атаки зловмисник повинен контролювати шлюз, через який користувач виходить у мережу (наприклад, через організацію MITM, при підключенні жертви до контрольованої атакуючої точки бездротового доступу або через злом маршрутизатора). Контролюючи шлюз, через який підключений до мережі користувач, атакуючий може надсилати фіктивні пакети, які сприйматимуться в контексті мережного інтерфейсу VPN, але відповіді надсилатимуться через тунель.

Шляхом генерації потоку фіктивних пакетів, в яких підставляється IP-адреса інтерфейсу VPN, здійснюються спроби вплинути на встановлене клієнтом з'єднання, але спостерігати вплив цих пакетів можна лише через пасивний аналіз за шифрованим потоком трафіку, пов'язаним з роботою тунелю. Для проведення атаки необхідно дізнатися призначену VPN-сервером IP-адресу мережного інтерфейсу тунелю, а також визначити, що в даний момент через тунель активно з'єднання до певного хоста.

Для визначення IP віртуального мережного інтерфейсу VPN використовується відправка на систему жертви SYN-ACK пакетів, послідовно перебираючи весь діапазон віртуальних адрес (у першу чергу перебираються адреси, що використовуються в VPN за замовчуванням, наприклад OpenVPN використовується підмережа 10.8.0.0/24). Про існування адреси можна судити з урахуванням надходження відповіді з прапором RST.

Аналогічним чином визначається наявність з'єднання з певним сайтом і номер порту на стороні клієнта - перебираючи номери портів у бік користувача відправляється SYN-пакет, адреса джерела, в якому підставлений IP сайту, а адреса призначення віртуальний IP VPN. Серверний порт можна передбачити (80 для HTTP), а номер порту за клієнта можна обчислити перебором, аналізуючи щодо різних номерів зміна інтенсивності ACK-ответов разом із відсутністю пакета з прапором RST.

На даному етапі атакуючий знає всі чотири елементи з'єднання (адреси/порт IP джерела та адресу/порт IP призначення), але для того, щоб згенерувати фіктивний пакет, який сприйме система жертви, атакуючий повинен визначити номери послідовності та підтвердження (seq та ack) TCP -з'єднання. Для визначення даних параметрів атакуючий безперервно відправляє підроблені RST-пакети, перебираючи різні номери послідовності, доки не зафіксує ACK-пакет у відповідь, надходження якого вказує, що номер потрапляє у вікно TCP.

Далі атакуючий уточнює правильність визначення відправкою пакетів з тим самим номером і спостерігаючи надходженням ACK-ответов, після чого підбирає точний номер поточної послідовності. Завдання ускладнене тим, що відповіді відправляються всередині шифрованого тунелю і аналізувати їх наявність у потоці трафіку, що перехоплюється, можна лише непрямими методами. Факт відправлення адресованого VPN-серверу ACK-пакета клієнтом визначається на основі розміру та затримки шифрованих відповідей, що корелюють із відправкою підроблених пакетів. Наприклад, для OpenVPN шифрований пакет з розміром 79 дозволяє точно судити, що всередині міститься підтвердження ACK.

До того, як захист від атаки буде додано в ядро ​​операційної системи, як тимчасовий метод блокування проблеми рекомендується за допомогою пакетного фільтра в ланцюжку «preroute» блокувати проходження пакетів, в яких адресою призначення вказана віртуальна IP-адреса тунелю.

iptables -t raw -I PREROUTING! -i wg0 -d 10.182.12.8 -m addrtype! -src-type LOCAL -j DROP

або для nftables

nft add table ip raw
nft add chain ip raw prerouting '{ type filter hook prerouting priority 0; }'
nft add rule ip raw prerouting 'iifname != wg0 ip daddr 10.182.12.8 fib saddr type != local drop'

Для захисту при використанні тунелів з IPv4 адресами достатньо перевести rp_filter в режим «Strict» («sysctl net.ipv4.conf.all.rp_filter = 1»). З боку VPN метод визначення номера послідовності може бути блокований шляхом додавання до зашифрованих пакетів додаткового заповнення, що робить розмір всіх пакетів однаковим.

Джерело: opennet.ru

Додати коментар або відгук