[Из песочницы] Почему самоуничтожающиеся фотографии/видео в Telegram не безопасны

image

Совсем недавно я увидел статью, где говорилось о внедрении самоуничтожающихся сообщений в мессенджере WhatsApp. Она будет иметь схожую с Telegram функциональность, но если в мессенджере Дурова удаление распространяется как на обычные сообщения (секретные чаты), также их можно использовать на фотках в обычных чатах. То есть после отправки предположим фотографии, собеседник сможет просмотреть ее ограниченное количество времени, а после, по идее, она будет удалена у обоих собеседников (желательно с сервера тоже), то в WhatsApp планируется внедрении удаления обычных сообщений (и сделано пока оно так себе).

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

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

Пользовался и я ими, правда не часто и скорее это были просто «развлечение» и за ними я особо не наблюдал. В июне месяце этого года я исследуя UserAPI Telegram, тестировал отправку фотографий и их получение. Развлекался, не более. И интерес появился в просмотре «вида» отправки сообщений, и как вообще они отображаются в ответе. Мне стало интересно как реализована эта функция «изнутри», удаляются ли файлы с сервера Telegram или может они как-то шифруются.

И на мое удивление, эти сообщения практически никак не отличаются от обычных. Прям совсем. У них присутствует такой же file_id как и обычных фотографий, с помощью которого, можно получить сам файл. И при этом даже если вы просмотрели сообщение, и оно исчезло в чате, вы спокойно можете его сохранить/отправить/переслать и сделать все то же самое, что вы могли сделать с обычными фотографиями/видео. То есть оно не удаляется с самого сервера Telegram.

Повторюсь, такие сообщения не относятся к секретным чатам, где переписка находится на двух устройствах, и с другого клиента я не могу получить к ним доступ. Эта функция разработана для обычных чатов и вроде бы как считалась «безопасной». Но и тут интересно, я нигде не нашел подробное описание этих самых самоуничтожающихся сообщений. То есть Telegram как бы и не говорит нам, что эти сообщения такие безопасные в плане доступа (если у вас есть доступ к самому аккаунту) как например те же самые секретные чаты. Единственное, что я видел, так это то что сам Telegram говорил что никакие сообщения, даже секретные чаты не имеют 100 процентной безопасности и что каждый отвечает сам за сообщения которые он отправляет, но…
Признаюсь, было бы это реализовано в каком нибудь WhatsApp/Viber/VK, я бы даже не обратил на это внимание, но Telegram является очень удобным мессенджером, который я сильно люблю, но вот что я ненавижу, так это его поддержка наполненная волонтерами.

В том же июне месяце я написал на почту support@telegram.org, где я составил целое письмо на двух языках. Где говорилось не только про самоуничтожающиеся сообщения, но так и про обычные и что Telegram не ставит никаких лимитов на пересылку, но об этом позже.

Спустя два месяца мне так и не ответили, поэтому пришлось писать в ту самую «поддержку» Telegram об разъяснении, что делать и куда писать при нахождении такого рода «Уязвимости».

Там мне на удивление ответили спустя три часа, где рассказали, что писать о серьезных уязвимостях в протоколе необходимо на security@telegram.org или же поделиться подробностями «тут». Прикладываю оригинальный текст ответа от поддержки:

Ответ поддержки от 5 июля

Привет. Вы можете поделиться подробностями тут или написать на security@telegram.org, если речь действительно идёт о какой-то уязвимости в наших приложениях или протоколе.


Я решил написать в саму поддержку о «подробностях» уязвимостей, прикладывая видео, сам скрипт и варианты решения проблемы (ниже есть мое сообщение), но, до нынешнего момента мне так и не ответили, ни на почте, ни в самой поддержке. Видимо пока, это их не волнует. Лучше давайте сделаем анимацию одиночных эмодзи.

Кроме варианта с самоуничтожающимися сообщениями, я так же заметил, что любое сообщение, которое было удалено, например, в личном чате, группе, канале, так же легко перехватить. Делается это при помощи обычного форварда всех сообщений, например, в отдельную группу, а после доставания их с помощью ID удаленного сообщения (сейчас библиотеки имеют хэндлеры на них).

Я так же описывал весь процесс в своем письме (хотя на деле он прост), с вариантом решения проблемы в виде ограничения форвардов самих сообщений. И если не полностью ограничивать, то запретить постоянный форвард всех сообщений. Думаю, команда разработчиков сможет сделать некий антифлуд от форвардов.

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

Расскажу о себе, 15 летний школьник, недавно увлекающийся разработкой на Python, баловался с User API и нашел такого рода «недоработку/уязвимость». Большее что взбесило и вынудило написать все это сюда — ужаснейшая реализация поддержки Telegram, которая просто меня проигнорировала три раза в течение 4 месяцев.

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

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

Сообщение для поддержки, на которое так и не пришел ответ
Hello, my name is Khamidov Amal.

Recently, I wrote a user experience for my project. At some point, I noticed how my friend sent me a self-removing photo. I looked at it on my Android client and it was removed as it should be after 10 seconds.

But I wondered how such messages are encrypted and how they are stored on the go. After all, it turns out that the telegram client first uploads the photo to the phone, and after reading it must remove it.

I wrote a small python script using the Pyrogram library and wanted to see how they came to the client.

I was surprised when I saw that these «self-deleting photos» look just like regular ones (what?).
That is, if I sent a regular photo, it was no different from the «self-deprecating».
After that, I wrote a script that sends this photo on the file, and at that moment, the photo went to my test channel like a normal photo. And on the phone from which I sent this most «self-extracting» photo, it was not even read.

It also allowed me to view the photo on my desktop client. That is, this script bypasses the most important essence of the «Self-extracting» photo.

I consider it a vulnerability, and I consider it a solution to reconsider the method of sending «self-deleting» messages and process them on the server and not on the device.

Also, I found the second one (almost a vulnerability), which was created using the API’s telegram itself and is not prohibited at all.

So, we are talking about ordinary messages.

I also wrote a regular script that sends (forward) all messages from the chat to my group and marks them by their ID.

I added a handler to this script that responds to all deleted messages and gives the ID of these deleted messages (hello pyrogram).

After that, I added a script and now, when the handler responds to all deleted messages, it checks them with the messages from the group (which contains all the messages) and looks for this message by ID.

On the one hand, this does not violate anything, because telegrams have an open code, everyone can write their userbots. but on the other hand (russian is good), in the last update you added the function of deleting your own and others' messages for the sake of security, but such simple scripts written by a 15-year-old schoolboy seem to bypass this very security.

I understand that everyone responds in response that he sends, but a person can send important files to an unnecessary person by mistake and at this moment he will delete the message (While the interlocutor has not read) without knowing that all these messages can be compromised and most importantly, that messages are not marked read.

The decision, I think, is to add limits on forward messages and review the way of «reading» messages.

In the second video I attached how can I save all deleted messages without reading them.
I attach the video and script that I wrote to clearly show how it works.


И как это выглядит в коде (использовал библиотеку Telethon, на Pyrogram то же самое почти):

Самая главная часть кода. Остальное — просто указание аккаунта, номера телефона и.т.д
@client.on(events.NewMessage(func=lambda e: e.is_private and getattr(e, 'photo')))
async def handler(event: message.Message):
    # event.input_chat may be None, use event.get_input_chat()
    chat: InputPeerUser = await event.get_input_chat()
    sender: User = await event.get_sender()
    photo: Photo = event.photo

    await client.send_message(img_channel, file=MessageMediaPhoto(photo),
                              message=f'{chat.user_id}\n'
                                      f'{sender.first_name}\n', parse_mode='HTML')

© Habrahabr.ru