

ДИСКЛЕЙМЕР Я не подаю ценных идей цензорам. Все, описанное в данной статье, было своевременно сообщено технической поддержке Телеграм год назад, которая благополучно проигнорировала все обращения. Ввиду этого, а также в силу того, что протоколы не изменились ни на йоту, считаю себя вправе опубликовать результаты исследований и технические детали. Я не подаю ценных идей цензорам. Все, описанное в данной статье, было своевременно сообщено технической поддержке Телеграм год назад, которая благополучно проигнорировала все обращения. Ввиду этого, а также в силу того, что протоколы не изменились ни на йоту, считаю себя вправе опубликовать результаты исследований и технические детали.





ДИСКЛЕЙМЕР 2 Меня глубоко возмущает подход разнообразных "девелуперов" противоцензурных решений, которые, разрабатывая свои решения, не почесались провести тестирование на контролируемом бордере на предмет реальной их устойчивости. При этом имеют нахальство заявлять, что они устойчивы к цензуре и так далее и тому подобное. Как показывает практика, подобные заявления не соответствуют действительности (мягко говоря).





Собственно Телеграм

Фундаментально слабым местом протокола Телеграм является bootstrap клиента. Первоначальный вход начинается с HTTP POST к серверу по характерному IP-адресу к API. То есть, клиент сообщает серверу о своем присутствии онлайн:







Вызов API происходит на четыре подсети:



149.154.164.0/22 149.154.172.0/22 91.108.4.0/22 91.108.56.0/24 2001:67c:4e8::/48 2001:b28:f23d::/48

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



На второй фазе, после входа, происходит переход по тем же адресам под TLS.





Давайте посмотрим, что у нас на 149.154.167.50:443 --



# openssl s_client -connect 149.154.167.50:443 CONNECTED(00000003) 1:error:140790E5:SSL routines:ssl23_write:ssl handshake failure:s23_lib.c:177: --- no peer certificate available --- No client certificate CA names sent --- SSL handshake has read 0 bytes and written 307 bytes --- New, (NONE), Cipher is (NONE) Secure Renegotiation IS NOT supported Compression: NONE Expansion: NONE No ALPN negotiated SSL-Session: Protocol : TLSv1.2 Cipher : 0000 Session-ID: Session-ID-ctx: Master-Key: Key-Arg : None PSK identity: None PSK identity hint: None SRP username: None Start Time: 1555498957 Timeout : 300 (sec) Verify return code: 0 (ok) ---

Мы видим, что, хотя соединение у нас по TLSv1.2, легитимный сертификат CA не предъявляется (более того, не предъявляется вообще никакого сертификата).



На 2 фазе, таким образом, нам достаточно не разрешить метод CONNECT по сетям Телеграм на порту 443.



Исходя из вышеизложенного, напишем универсальное решение для транспарентного прокси L7 (для простоты ограничимся IPv4 - не все страны и не все провайдеры поддерживают IPv6 на магистралях):



# Block Telegram acl Telegram url_regex 149\.154\.1(6[0-9]|7[0-5])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\/api$ acl Telegram url_regex 91\.108\.([4-7]|5[6|7])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\/api$ http_access deny Telegram deny_info TCP_RESET Telegram acl Telegram_api_terminate ssl::server_name_regex 149\.154\.1(6[0-9]|7[0-5])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]) acl Telegram_api_terminate ssl::server_name_regex 91\.108\.([4-7]|5[6|7])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]) # SSL bump rules acl DiscoverSNIHost at_step SslBump1 ssl_bump peek DiscoverSNIHost ssl_bump terminate Telegram_api_terminate ssl_bump splice all

Как видите, мы, не выполняя MiTM и не устанавливая сертификата прокси клиенту, в первом ACL просто терминируем bootstrap на уровне HTTP, посылая клиенту TCP RST (можно и просто запретить метод POST на эти сети), во втором ACL мы терминируем CONNECT по SNI (по факту, здесь SNI не нужен - мы видим IP, по которому без всякого SNI и происходит соединение).



Применим эти правила:





Клиент не может сообщить о себе серверу. Сервер, не зная о его присутствии, не может PUSH бросить - он не знает, куда и кому его бросать.



истинного HTTPS) тривиальной проверкой хэндшейка. И, даже если не копать глубоко, bootstrap слишком примитивен и перешибается легким пинком.



UPDATE Если Телеграм начинает прятаться за легитимными CDN (что происходило в прошлом году), то его bootstrap все равно имеет характерный вид HTTP POST http://A.B.C.D/api . В этом случае мы просто расширяем регулярное выражение до вида ^http://0.0.0.0/api$ (по данным исследования, больше подобных поведенческих сигнатур ни у кого нет) и, либо идентифицируем IP и помещаем их в бан-лист динамически на срок от 1 часа до суток, либо просто пресекаем HTTP POST и последующий CONNECT с отправкой в сессию TCP RST. Честно говоря, сигнатура бутстрапа настолько характерная, что я немного удивлен тем, что она еще не добавлена в Cisco NBAR2.



Я хочу добавить, что подавляющее большинство массовых мессенджеров, выполняющих бутстрап и аутентификацию по HTTPS на центральный сервер, также банятся в одно действие по SNI. По моему глубокому убеждению, eSNI в обозримом будущем не имеет реальных шансов стать массовым (по причине необходимости кэширования веб-трафика, вне зависимости от того, HTTP он или HTTPS - плата за трафик есть плата за трафик; а также по причине необходимости аудита соединений на предмет защиты от малвари и фишинга), а TLS 1.3 требует предъявления SNI в обязательном порядке.



По этой причине, все мессенджеры, не имеющие встроенной соксификации - в опасности.



MTProto proxy Существует мнение, что MTProto proxy решает все проблемы с цензурой.

На первый взгляд кажется, что действительно решает. Если ковыряться на L2.

Все, однако, не настолько радужно.

Во-первых, клиент Телеграм постоянно выполняет вот такие обращения к dns.google.com для определения IP прокси по DoH в огромном количестве:

Вызов API происходит на четыре подсети:Собственно говоря, на этом все. Достаточно заблокировать данные сети на бордере, и вход с аутентификацией становится невозможным. Никто другой эти подсети не использует, так что мы можем с чистой совестью их побанить.На второй фазе, после входа, происходит переход по тем же адресам под TLS.Давайте посмотрим, что у нас на--Мы видим, что, хотя соединение у нас по TLSv1.2, легитимный сертификат CA не предъявляется (более того, не предъявляется вообще никакого сертификата).На 2 фазе, таким образом, нам достаточно не разрешить метод CONNECT по сетям Телеграм на порту 443.Исходя из вышеизложенного, напишем универсальное решение для транспарентного прокси L7 (для простоты ограничимся IPv4 - не все страны и не все провайдеры поддерживают IPv6 на магистралях):Как видите, мы,, в первом ACL просто терминируем bootstrap на уровне HTTP, посылая клиенту TCP RST (можно и просто запретить метод POST на эти сети), во втором ACL мы терминируем CONNECT по SNI (по факту, здесь SNI не нужен - мы видим IP, по которому без всякого SNI и происходит соединение).Применим эти правила:Клиент не может сообщить о себе серверу. Сервер, не зная о его присутствии, не может PUSH бросить - он не знает, куда и кому его бросать.Как видите, все трескучие заявления околоайтишных "экспертов", что "мы-де замаскируемся под HTTPS" - не более, чем слова. Недостаточно встать на 443 порт, чтобы замаскироваться под HTTPS. Проверяется это в одно действие (если оставить в стороне проверку HTTP headersHTTPS) тривиальной проверкой хэндшейка. И, даже если не копать глубоко, bootstrap слишком примитивен и перешибается легким пинком.Если Телеграм начинает прятаться за легитимными CDN (что происходило в прошлом году), то его bootstrap все равно имеет характерный вид. В этом случае мы просто расширяем регулярное выражение до вида(по данным исследования, больше подобных поведенческих сигнатур ни у кого нет) и, либо идентифицируем IP и помещаем их в бан-лист динамически на срок от 1 часа до суток, либо просто пресекаем HTTP POST и последующий CONNECT с отправкой в сессию TCP RST. Честно говоря, сигнатура бутстрапа настолько характерная, что я немного удивлен тем, что она еще не добавлена в Cisco NBAR2.Я хочу добавить, что подавляющее большинство массовых мессенджеров, выполняющих бутстрап и аутентификацию по HTTPS на центральный сервер, также банятся в одно действие по SNI. По моему глубокому убеждению, eSNI в обозримом будущем не имеет реальных шансов стать массовым (по причине необходимости кэширования веб-трафика, вне зависимости от того, HTTP он или HTTPS - плата за трафик есть плата за трафик; а также по причине необходимости аудита соединений на предмет защиты от малвари и фишинга), а TLS 1.3По этой причине, все мессенджеры, не имеющие встроенной соксификации - в опасности.