Хабрахабр

Telegram научился маскироваться под HTTPS

В код клиентов Telegram добавили возможность маскировки под HTTPS (TLS + HTTP/2.0).

Кроме того, добавили возможность кодировать секрет в адресе прокси сервера как base64, в дополнение к hex. Для использования этой возможности добавили новый префикс секрета — «ee».

Перед тем, как углубиться в детали, попробуем разобраться как развивалась поддержка прокси-серверов в Telegram.

Предыстория

  1. Сначала Телеграм поддерживал SOCKS-прокси. Это помогало обойти блокировку серверов по IP, но протокол был заметен в трафике, а пароль передавался в открытом виде
  2. Примерно год назад выпустили официальный прокси, работающий по новому протоколу MTProto. В отличие от SOCKS, пароль в MTProto не передавался в открытом виде. В протоколе избавились от каких-либо служебных заголовков, по которым можно было бы понять что это действительно он. Ещё добавили возможность показа рекламы пользователям прокси-сервера
  3. Оказалось что прокси-серверы, работающие по протоколу MTProto, можно обнаружить по длине пакетов. При установке соединения клиент и прокси сервер обмениваются пакетами определённой длины, а при работе — пакетами одной и той же длины по модулю 4. Эта особенность начала использоваться крупными провайдерами для блокировки мессенжера. Разработчики Telegram отреагировали на это модификацией протокола, добавив в каждый пакет некоторое количество случайных байт. Так как изменение ломало совместимость, пришлось дополнить формат секрета специальным префиксом «dd», означающим использование модифицированного протокола:
    tg://proxy?server=178.62.232.110&port=3256&secret=dd00000000000000000000000000000000
  4. При изучении особенностей блокировок прокси серверов в Китае и Иране выяснилось, что надзорные органы используют для детекта replay-атаки. В альтернативных реализациях прокси-серверов на Python, Erlang и Go появилась частичная защита от такого вида атак. Для этого прокси серверы запоминают данные, передающиеся на начальном этапе установки соединения и не дают повторно соединиться с такими же данными. У подхода есть проблема с крупными прокси-серверами, т.к. для запоминания требуется большое количество оперативной памяти
  5. В Китае и Иране применяют следующую тактику: если протокол неизвестен, то на всякий случай скорость его работы сильно режут. На практике это означает возможность использования Telegram только для передачи текстовых сообщений, без картинок и видео. Причём в Китае так умели делать давно, а в Иране научились относительно недавно. В России пока не научились, но закон уже приняли. Попытка разработчиков мессенжера замаскировать трафик под какой-нибудь популярный протокол на этом фоне выглядит закономерно.

Что изменилось?

В протоколе между клиентом Telegram и прокси-сервером добавили ещё один слой инкапсуляции поверх TCP. Вместо посылки данных по TCP, данные оборачиваются в записи TLS следующего вида:

Пакет от клиента к прокси-серверу имеет такую структуру:
В начале работы добавился этап эмуляции TLS-handshake.

Самая важную функцию несёт поле Random, куда помещается результат HMAC от общего секрета и данных в пакете, что позволяет доказать клиенту что он знает секрет. Почти все поля не имеют для клиентов Telegram смысла и нужны лишь для того чтобы прикидываться TLS. Это полезно для защиты от replay-атак. Так же, клиент ксорит последние 4 байта поля Random со своим временем в формате unixtime, что позволяет прокси-серверу определять когда был сгенерирован пакет. Если пакет сгенерирован давно или в будущем, то прокси-сервер может его сразу отбросить.

Если он совпадает с вычисленным, прокси отвечает пакетом со следующей структурой:
При подключении клиента, прокси сервер проверяет переданный HMAC.

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

Где попробовать?

Для демонстрации был доработан и поднят прокси-сервер на языке Python, к которому можно подключаться десктопным клиентом Telegram последних версий и смотреть передающийся трафик с помощью Wireshark:

62. tg://proxy?server=178. 110&port=3256&secret=7gAAAAAAAAAAAAAAAAAAAABnb29nbGUuY29t 232.

Скорее всего, в ближайшее время, данную функциональность добавят и в другие реализации прокси-серверов. Так же, поддержка маскировки под TLS была добавлена в прокси-сервер на языке Erlang.

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть