[Из песочницы] Уязвимость в Telegram позволяет скомпрометировать секретные чаты

Посвящается к юбилею Telegram


В секретных чатах Telegram используется «сквозное шифрование», и что? End to end encryption Telegram слабо защищает переписку пользователей. Простой пример: злоумышленник достал приватный ключ gpg Алисы, естественно, чтобы расшифровать сообщение, зашифрованное для Алисы необходим пароль от этого ключа, который невозможно сбрутить, придерживаясь современной доктрины парольной защиты. В Telegram end to end encryption на Android — это становится возможно с вероятностью 100%. Обход двухфакторной аутентификации, восстановление пин-кода и угон секретных чатов в Telegram об этой уязвимости и будет статья.
В своей работе я постараюсь описать подробный мануал по уязвимости в Telegram на Android-девайсах, приведу примеры по восстановлению local code Telegram на Android, Desktop Linux/Windows. Скомпрометирую секретный чат Telegram. В этом противостоянии с командой Дурова мне поможет моя компания: Я; Android 7.0; Android 6.0 (root); Android 4.4.2 (root); ПК с OS Linux/Windows. На первый взгляд кажется силы не равны, посмотрим…

ИХМО. С чего все началось


В моем случае всю мощь PR-компании вокруг платформы Telegram ощутил и я. На огромных колесах «Телеги» хайп катился от месяца к месяцу, не имея ни центра, ни границ. Влияние Э. Сноудена на популяризацию повсеместного пользовательского шифрования переписки. Вспомните культовый мессенджер ICQ с его приложением QIP 2005 на Desktop-е, там вся переписка хранилась на ПК в открытом доступе в файлах .txt. Telegram по поводу шифрования переписки «кто первый стал массово шифровать частную переписку» не сразу, но позже заявил, что пионер — это он. История Telegram ничем особо не выделялась: конкурс на безопасность протокола MTProto от durov; калымы для художников и художниц (рисование стикеров); API по созданию ботов/приложений; ICO TON, принесшее хозяевам Telegram немалые деньги; блокировка мессенджера в Иране, РФ и снова в Иране;, а также поступлению в сеть редких онлайн-вбросов подноготной Telegram. В июле 2018 г. «Телега промчалась и по мне». Когда на массовом рынке мессенджеров появился «очередной Telegram» со своим слоганом и небольшой оговоркой (это супер быстро, просто и бесплатно). «Telegram — это приложение для обмена сообщениями с акцентом на скорость и безопасность». На счет последнего в таком крутом слогане, durov и его команда (за счет Николая Дурова техническая сторона команды сильная) открыто взаимодействуют со специалистами по ИБ/багхантерами, которые находят/пытаются найти уязвимости в протоколе MTProto или баги на платформе Telegram. Специалисты присылают свой материал на почту security@telegram.org — это официальный метод такого взаимодействия «охотниками за головами» и разработчиками Telegram, так же об этом упоминается и тут. Неофициальный формат такого общения, когда письма игнорируются со стороны разработчиков Telegram, и тогда спецы обычно постят свои твиты в микроблоге, где некоторые из них комментирует durov.

К услугам Черного принца пользователя конфиденциальность на мобильной платформе Telegram представлена, как неприступная, грозная, новомодная разработка MTProto от Николая Дурова. Секретные чаты в Telegram (далее СЧ) — это чаты, которые присутствуют лишь на мобильной платформе Telegram и защищены сквозным шифрованием, ключи хранятся только на устройствах на которых были сгенерированы, а еще это гордость Telegram-Dubai (так их назову). СЧ Telegram считаются очень защищенными чатами во всем мире, в Telegram-Dubai мире, несколько раз durov сотрясал воздух, сравнивая свой продукт с конкурентами в публичной воинственной форме и всегда побеждал.

Обойдя end to end encryption Telegram мессенджера на Android, баг-репорт отправил письмом на вышеупомянутый e-mail. Ответа не получил, спустя несколько дней написал в техподдержку волонтерам Telegram. Волонтеры мне ответили, что донесут мою мысль до руководства Telegram, запросив с меня уточнение: откуда и когда я отправил свое письмо. Спустя две недели тишины я еще раз напомнил о своем письме волонтерам, на этот раз и добровольцы мессенджера полностью проигнорировали моё напоминание. Через неделю я снова повторил отправку письма на официальную почту Telegram — нет ответа. Что же остается, чем же заняться? докучать со своим баг-репортом по Telegram через микроблог?, осаждать неофициальные источники общения команды durov-а? Или написать и выложить статью для СМИ? Прямо какая-то кибербюрократия сформировалась в рядах Telegram. Не могу не отметить w9w с habr.com, который, по моему мнению, нашел лучшую уязвимость на платформе Telegram: уязвимость в telegra.ph. Суть — любой юзер мог отредактировать чужую статью на telegra.ph. Со своим отчетом об уязвимости w9w (он нашел их несколько) так же не смог достучаться на security@telegram.org. После прохождения бюрократического квеста, w9w получил за найденные уязвимости маленькое финансовое вознаграждение. Интересно, это жадность Telegram? или какая-то другая причина? Вернемся к Telegram, немного отзывов о нем.

btqyqapjuur9cnzfm5itije2vgk.jpeg

У многих людей есть свой семейный фотоальбом, у багхантеров — свой послужной список «найденных багов/ошибок/уязвимостей». В своем ПС, по окончанию работы над статьей, я равнодушно закрашу ячейку B30 в красный цвет, тем самым, оставив свой вопрос к команде Telegram открытым.

Часть 1. Восстановление local code Telegram на OS Android Linux/Windows Desktop. Основано на реальных событиях


В июле летом 2018 г. на Github-е один из разработчиков неформальной группировки версии John The Ripper (далее JTR) выложил написанный на Python-е исходный код парсинг-модуля «telegram2john.py». Из названия программы становится ясно для чего и кому служит данный модуль. Кому не понятен смысл подобных модулей, это модули, расширяющие функционал JTR. Официальный JTR умеет потрошить 8 форматов, а JTR jumbo-1-bleeding — 263 форматов, и один из таких форматов — Telegram local code. Опробовав «telegram2john.py», я обнаружил ошибку в нем: одна из трех функций парсинга local code Telegram работала некорректно, о чем я и сообщил на Github-е разработчикам JTR. Исправление для «telegram2john.py» вышло оперативно. Это не первое обращение по найденным багам к разработчикам JTR, и каждый раз быстрый ответ и не менее быстрое исправление ошибок — просто приятно, когда существует такие будничные налаженные каналы связи. Через пару дней на тайном вече модуль «telegram2john.py» утвердили и отправили в репозиторий JTR.

Схема восстановления local code Telegram — многоэтапный процесс:

  1. Read the salt (32 bytes), encrypted data and sha1 of decrypted data from a file.
  2. Compute a PKCS5_PBKDF2_HMAC_SHA1 on the UTF8 (passcode), using the salt, 4000 iterations, keysize of 256 bytes
  3. Use a Telegram-specific KDF to get the AesKey and AesIV (Relatively cheap — bunch of memcpy and 4x sha1)
  4. Perform an AES-IGE-DECRYPT on the encrypted data using the derived key and IV from step 3.
  5. Compare sha1 of decrypted data with the sha1 read in step 1. If they match — passcode is correct.


Для пользователя JTR операция «кровотечения» упрощается до двухэтапного процесса: с помощью модуля «telegram2john.py» «вытягивание хэша» для Джоновского процессора из файла userconfing.xml, принадлежащему приложению Telegram (моментальная по времени операция), и brute force этого «хэша» с помощью JTR. При такой операции вероятность восстановления local code на Android-е составляет 100% успеха, время ожидания несколько секунд. Вероятность восстановления local code на Desktop-е Linux/Windows составляет X% успеха, время ожидания неопределенное. Почему? Потому что, во-первых, local code — обычный цифровой pin код на Telegram из четырех цифр (10^4 всевозможных комбинаций pin-а) ни больше ни меньше, во-вторых, алгоритм шифрования local code Telegram на Android-е не криптостойкий, отсюда высокая скорость перебора пароля. По-другому обстоят дела с Desktop-приложениями Telegram, где нет секретных чатов: в приложении на Desktop-е, шифрование local code криптостойкое (скорость перебора на CPU хэша Desktop/Telegram в 100 раз медленнее скорости перебора хэша Anroid/Telegram), а главное local code на Desktope/Telegram можно задавать «любой» длины и использовать любые символы.

lsubb0cle23xy2pkv_wkzmm7fi4.png
Криптостойкость local code Desktop Telegram высокая, скорость brute force в сто раз медленнее brute force local code Android Telegram.

Лично у меня складывается впечатление, что разработчики Telegram трудились над созданием уникального и защищенного своего протокола MTProto, а не над всесторонней конфиденциальностью пользователя, например, открытый кэш приложения, хранящийся в не под корневым каталогом Android или не криптостойкий local code Android, который, как оказывается восстанавливается с вероятностью 100%.

На момент написания статьи, JTR-ы, из коробки в свежих Kali Linux и Parrot Security OS имеют баги, не позволяющие парсить local code Telegram (JTR jumbo-1-bleeding всегда имеет какие-то баги, но его функционал развивается круче чем вы думаете, если вы думаете о ПО Hashcat). Итак, искушенный пользователь Kali/Parrot взломать восстановить Local code Telegram не сможет, в Windows JTR усеченный по функционалу — тоже не годится. Поэтому необходимо устанавливать на свою OS JTR c Github (для Linux-систем). Чтобы компиляция ПО JTR прошла успешно, до компиляции программы доставляете пакет в вашу OS «libssl-dev», далее

•    git clone git://github.com/magnumripper/JohnTheRipper -b bleeding-jumbo john && cd john/src
•       ./configure && make -s clean && make -sj4
•       john/run/telegram2john.py userconfing.xml > хэш (если модуль telegram2john.py доставляете например в Kali Linux отдельно, тогда запускаете так: python telegram2john.py userconfing.xml > хэш)
•       JohnTheRipper/run/john хэш - -mask=?d?d?d?d


Результат последних двух команд — получение local code Android Telegram за две секунды.

99l7mgbd_gjlbyfxzaae_f7tvwa.png
Восстановлен local code Android Telegram. Pin 5369.

Аналогично и с брутом local code Telegram приложений Desktop Linux/Windows, вместо файла «userconfing.xml» указывается путь к каталогу Telegram:

(Linux): ~/telegram2john.py ~/.local/share/TelegramDesktop;
(Windows): ~/telegram2john.py «C:/Users/Name/AppData/Roaming/Telegram Desktop» (для устаревшего приложения Telegram на Windows);
(Windows): ~/telegram2john.py «Telegram Desktop» (для обновленного приложения Telegram на Windows).

Обратите внимание, если вы повторно захотите распарсить local code Telegram, JTR выдаст «No password». Причина — пароль уже был найден ранее, Джонни — никогда не восстанавливает пароль по второму и последующему разу, для этого используйте опцию »- -show хэш», но иногда могут случаться баги, и опция — -show не отработает как надо (с другими хэшированиями такие баги встречал, но все уже поправили разработчики JTR). В таком случае загляните в файл ~/run/john/pot, все найденные пароли хранятся в нем, если его очистить, то можно повторно брутить хэши с найденными паролями.

4ltagz1y7hbtdec1le1mxt2pabi.png
John The Ripper не собирается повторно «пачкать руки в крови» о local code Android Telegram

файл userconfing.xml, который является мишенью JTR расположен в под корневом каталоге Android:

/data/data/org.telegram.messenger/shared_prefs/userconfing.xml


а значит добраться до файла можно имея root права, или через TWRP или с помощью digital forensics.

Подробный видео-мануал по восстановлению local code Telegram на Android/Linux/Windows ссылка в конце статьи.

Часть 2. Белые начинают и проигрывают. Угон секретных чатов в Telegram. Основано также на реальных событиях


Как базируется защита в Telegram:

  1. ввод номер телефона;
  2. получение смс, либо кода в приложении на другом устройстве — по желанию, ввод смс-кода или кода полученного в приложении на другом устройстве.
  3. Временная блокировка аккаунта при частом (в том числе успешном) залогиннировании пользователя.


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

Опциональная, базовая + усиленная защита Telegram:

1. ввод номер телефона;
2. получение смс, либо кода в приложении на другом устройстве — по желанию, ввод смс-кода или кода с приложения;
3. Ввод cloud code Telegram (хранится на сервере Telegram и у вас в уме, сбрасывается/привязывается через e-mail);
4. установка local code (на Android-е, настройки — конфиденциальность и безопасность — код пароль);
5. проверка текущей/последних сессий входа в мессенджер;
6. Выход из всех сессий кроме текущей;
7. очистка содержимого СЧ по таймеру;
8. запрет на скрин/запись экрана СЧ;
9. Временная блокировка аккаунта при частом (в том числе успешном) залогиннировании пользователя;
10. Как выяснилось при угоне СЧ (вход в чужую учетку с другого ip) временный бан реального/скомпрометированного аккаунта ~ через 5 минут и отмена СЧ в Telegram. В одной же сети реальной/скомпрометированной учетки, Telegram забывает банить за угон аккаунта.

Ниже я покажу, что СЧ уязвимы, один из таких СЧ я угоню (свой тестовый аккаунт в Telegram) и буду выдавать себя за пользователя «Хозяин»

После успешного восстановления local code Telegram я решил пощупать файлы рядом с файлом userconfing.xml на Android-е. Создал секретный чат, посмотрел какие файлы и в каких подкаталогах обновляются по времени. Попробовал скопировать эти файлы с OS Android 4.4.2 на другой гаджет с OS Android 6.0 (перенос файлов между гаджетами осуществлял через архивы rar; zip). Установил с GP последнюю версию Telegram на Android 6.0. Перенес c Android 4.4.2 > Android 6.0 обновленные файлы в аналогичные каталоги

/android/android/org.telegram.messenger/shared_prefs
/android/android/org.telegram.messenger/files
/android/android/org.telegram.messenger/no_backup


Согласно ворованной своей тестовой учетки Telegram восстановил права (какие были на 4.4.2) для каждого файла и папки персонально, операция не быстрая (у разных файлов самые разнообразные права), назначил UID GID «Telegram».

9qatohryqpk8h29khwslvmemi8o.jpeg

Запустил приложение? Тут же все ворованные файлы обновились по времени, а меня приветствовал экран «нового пользователя». Telegram вел себя так, как будто я новый юзер и предлагал зарегаться или войти через телефон (стандартная процедура при первоначальной установке Telegram на Android). То есть я не смог ворваться в чужую учетку. Подкрался еще и еще несколько раз с разных сторон, но в конченом итоге — фэйл.

Попробовал другой способ — бэкап тестовой учетки Telegram через Titanium backup.
Сделал бэкап приложения на Android 4.4.2, развернул бэкап 4.4.2. на Android 6.0.

iueb7vcq3h-upyl2_xxyl3qewoc.jpeg

Права на «ворованное» приложение, смена UID/GID не требуется — все сделает Titanium Baсkup. Запускаю Telegram скомпрометированной учетки на Android 6.0 и магия! Получаю запрос на ввод local code пользователя «Хозяин». Такой способ с Бэкапом предоставил обход двухфакторной аутентификации без танцев с бубном. Telegram со своей стороны запросил лишь local code от угнанной учетки. Отправляю украденный файл

/android/android/org.telegram.messenger/shared_prefs/userconfing.xml


на удаленную свою VDS Kali Linux, ставлю задачу на брут pin-кода и тут же получаю результат

_9buluigh-7cdh1bhltdbbl4rfa.png

Красным выделил (сверху вниз) полученные:
* хэш для JTR с помощью модуля telegram2john.py;
* восстановленный local code Android Telegram;
* Джонни full time job (неприлично-высокая скорость brute force пароля, опцию — -mask=? d? d? d? d, сообщающая Джонни чтобы он подбирал 4х значный цифровой код не включил, чтобы JTR разогнался и показал свою ярость скорость);
* запрос к JTR восстановленного local code.

Крутой Джонни! неправда ли?

Восстановив с помощью JTR Android local code Telegram, вошел c другого ip в чужой свой тестовый аккаунт, который изначально располагался на Android 4.4.2., а теперь скомпонованный на Android 6.0. При этом вижу все секретные чаты жертвы и всю переписку в них. Попробовал написать, в созданном ранее СЧ, пользователю Android 7.0 и сообщение успешно отправилось, юзер Android 7.0 отправил ответ, ответное сообщение было не просто получено, а получено на двух гаджетах: на Android 6.0 и на Android 4.4.2. Проверил, последние сессии входа, у реального пользователя отображался его ip и его гаджет Teclast Android 4.4.2 (настройки- конфиденциальность и безопасность-активные сеансы). У злоумышленника Android 6.0 в «активных сеансах» отображался девайс Teclast Android 4.4.2, ip Вирджиния. То есть реальный пользователь не получает информацию через «Активные сеансы», что его учетка была скомпрометирована, а получает «ложную» информацию, что он находится в сети с одного своего устройства и с одного своего ip.

ps5hviqijte1q-4ltk_1ucmhc48.jpeg

Реальный пользователь через активные сессии не видит, что он скомпрометирован. В истории последних сеансов не фиксируются точки входа злоумышленника. Более того, в реальном аккаунте «Хозяина» я щелкнул «выйти из всех сеансов кроме текущего». Злоумышленника при этом не выкинуло из сеанса, независимо от онлайн/офлайн статуса атакующего.

Попробовал туже операцию относительно скомпрометированной учетки — результат аналогичен: «Хозяина» не выкинуло из Telegram, сессионные ключи прежние.

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

ameizyvemokjmzivi6o6wf2ig1y.jpeg
Все ключи одинаковые в том числе и у скомпрометированной учетки.

Telegram заявляет, если ключи бьются на 2х устройствах, вы в безопасности — это не так. (Отступление. Сверять ключи все же нужно, после установки Telegram на Android и при создании самого первого СЧ, у пользователей СЧ отсутствовали слепки ключей, а графическое изображение ключа отличалось на устройствах. СЧ работал как обычно, что произошло я так и не разобрался, и это был единичный случай, когда ключи не бились между собой).

Вернулся к первому методу «copy-paste», который у меня изначально не получился.

Повторил все свои предыдущие шаги, добавив промежуточное 3-е действие.

1) Установил с GP последнюю версию Telegram.

2) Перенес каталоги с OS 4.4.2 на другой гаджет с OS 6.0

/android/android/org.telegram.messenger/shared_prefs 
/android/android/org.telegram.messenger/files 
/android/android/org.telegram.messenger/no_backup 


3) Удалил папку на Android 6.0, шах

/android/android/org.telegram.messenger/code_cache


4) Права не восстанавливал персонально, вместо этого раздал всем вышеописанным каталогам «рекурсивно» права 777 (полный доступ). Назначил тем же каталогам владельца и владельца группы (UID/GID) «Telegram» (на самом деле «рекурсивно» в root каталоге плохо работает в TC, поэтому пришлось перепроверять назначение прав).

5) Вперёд! Запускаю Telegram в другой сети с другим ip — неудача, снова это приветствие нового пользователя на английском языке.

6) Вперёд! Перезапускаю Telegram, шах и мат! Telegram выдал предупреждение на ввод local code пользователя, который был на Androide 6.0 (и который восстанавливается с вероятностью 100%), при этом запросы со стороны Telegram на cloud code или смс отсутствовали и до сих пор отсутствует напрочь. Обход двухфакторной аутентификации, нет! обход End to end encryption Telegram выполнен успешно.

Результат: сообщения злоумышленника в СЧ так же успешно отправлялись от имени реального пользователя, и так же была доступна вся переписка СЧ. Спустя ~400 ударов моего тревожного сердца, опасения подтвердились: угнанная учетка была заблокирована Telegram-ом у злоумышленника и у реального пользователя; СЧ — отменен.

zcu4hjtgqr1sspqp0l3qnqvq9le.jpeg
Временная блокировка учетки Telegram.

Авторизовавшись повторно в Telegram (иногда бан бывает на сутки, но мне повезло, почему-то в этот день все баны раздавались на секунды), у реального пользователя было все как обычно, а злоумышленник уже не мог снифить скомпрометированную учетку (сессионные ключи обновились).

Несколько официальных утверждений Telegram мне удалось опровергнуть


telegram.org/faq — «СЧ могут быть только на устройствах происхождения СЧ».

Я — «как видите СЧ могут быть не только на устройствах происхождения СЧ, но и на устройствах, где имеется Root и ключ СЧ, независимо от версии OS Android».

telegram.org/faq — «Вы можете сравнить это изображение (примечание: изображение СЧ ключа) с тем, которое имеет ваш друг — если оба изображения одинаковы, вы можете быть уверены, что секретный чат безопасен»

Я — «нельзя быть уверенным, что чат безопасен».

telegram.org/faq — «Мы также рекомендуем включить двухэтапную аутентификацию и установить сильный код доступа для блокировки вашего приложения, вы найдете обе опции в настройках — Конфиденциальность и безопасность».

Я — «Сильный код доступа установить можно только в приложении Telegram Desktop Linux/Windows, но не на Android»

telegram.org/faq — «Пользователь с корневым доступом может легко обойти функции безопасности, встроенные в операционную систему, прочитать память процесса или получить доступ к ограниченным областям, таким как внутреннее хранилище. Как только у злоумышленника есть доступ к корню, любые усилия по смягчению угроз становятся бесполезными. Никакое приложение не может быть названо безопасным в этих обстоятельствах, независимо от того, насколько сильно шифруется».

Я — «Или восстановить local code Android и получить/клонировать учетку. С каждой новой неверной попыткой ввода pin, Telegram увеличивает время ожидания между попытками ввода pin. Видимо, таким алгоритмом Telegram удовлетворен в защите пользователя от ручного brute force 10^4 всевозможных комбинаций pin-ов, но удовлетворен ли пользователь, когда его легко так скомпрометировать? Если разработчики Telegram хотели бы смягчить угрозы в этих обстоятельствах, они могли бы это реализовать ни как временную блокировку на несколько секунд на неверный ввод local code, а заменить на Telegram Android-е функцию pin на password, с шифрованием PBKDF2 — это сильно замедлит атаку brute force. Как пример хорошей защиты — password на вход в зашифрованную БД паролей Keepass2Android.

telegram.org/faq «Вы можете получать доступ к сообщениям в секретном чате из своего устройства происхождения. Они безопасны до тех пор, пока ваше устройство безопасно в вашем кармане».

Я — «Вот где, оказывается правда!»

Выводы


Демонстрация восстановления local code Telegram на Android/Linux/Windows.


Демонстрация уязвимости секретных чатов Telegram.


P.S.: дата/время на отдельных скринах или скрин-видео может не совпадать, так как эксперименты в Telegram и скрины делал по ходу написания статьи, а из-за раздачи банов Telegram-ом статья писалась несколько дней.

© Habrahabr.ru