История одной XSS в Telegram
Статья имеет ознакомительный характер и предназначена для специалистов по безопасности, проводящих тестирование в рамках контракта. Автор не несет ответственности за любой вред, причиненный с применением изложенной информации. Распространение вредоносных программ, нарушение работы систем и нарушение тайны переписки преследуются по закону
Введение
Здравствуйте, уважаемые читатели Хабра! Сегодня я хочу поделиться с вами информацией о XSS-уязвимости, которую я обнаружил в Telegram около двух недель назад. Также статья коснется некоторых особенностей работы программы поиска уязвимостей от Telegram. Моя цель — не только продемонстрировать вам интересный и относительно простой пример XSS, но и обозначить причины, по которым, возможно, не стоит тратить свои усилия на участие в багбаунти программе Telegram.
Часть 1. XSS
В Telegram уже длительное время, по крайней мере с 2021 года, существовала возможность выполнения XSS-атаки на пользователя, исключительно в веб-версии приложения.
Прежде чем углубиться в детали конкретной уязвимости, которую я обнаружил, давайте кратко рассмотрим общую стратегию атаки, которую я использовал. Этот метод атаки хорошо известен в сообществе кибербезопасности и заключается во вставке псевдопротокола javascript в HTML-ссылки. Вкратце, это выглядит следующим образом:
Click Me!
Разумеется, если мы отправим такую ссылку через Telegram, то не увидим ожидаемый результат:
В связи с этим, я решил более тщательно изучить исходный код веб-клиента Telegram и обнаружил следующий фрагмент кода:
export function ensureProtocol(url?: string) {
if (!url) {
return undefined;
}
return url.includes('://') ? url : `http://${url}`;
}
Этот код проверяет наличие протокола в ссылках, приходящих в сообщениях, и если протокол отсутствует, автоматически добавляет 'http' в начало ссылки.
Такой подход к проверке является некорректным и определенно не соответствует RFC стандарту. Пример обхода данной проверки тривиален:
slonser.ru/#://
При отправке сообщения с такой ссылкой можно заметить, что веб-клиент не добавил http://
в начало ссылки. Следовательно, при нажатии на неё, пользователь будет перенаправлен на http://web.telegram.org/slonser.ru/#://.
Однако, если бы мы попытались вставить ссылку в следующем формате:
javascript:alert()/#://
Мы бы обнаружили, что наша ссылка не была корректно обработана. В чем же причина? Возможно, у Telegram есть черный список для некоторых ссылок? Или, возможно, они все-таки проверяют протокол javascript отдельно на серверной стороне? Ответ, разумеется, отрицательный! Дело в том, что символы »:» и »()» не являются допустимыми для доменных имен, и поэтому регулярное выражение на сервере не распознает это как ссылку.
На момент я задумался, решив, что попытка не удалась, и, возможно, Stored XSS в Telegram так и останется недостижимой мечтой. Однако, мне удалось довольно быстро придумать изящное решение:
javascript:alert@github.com/#://
Что же происходит в этом примере? Данная ссылка использует HTTP Basic Authentication, и серверная часть Telegram интерпретирует это как ссылку на github.com с данными аутентификации: username равным «javascript» и password равным «alert» (и в некотором смысле это верно). Как приятный дополнительный эффект, мы получаем превью нашей ссылки, которое выглядит как валидная ссылка на GitHub:
Это существенно усиливает потенциальную угрозу от XSS-атаки, поскольку пользователи могут быть убеждены, что перед ними обычная ссылка на GitHub. Теперь осталось решить вопрос с символами, которые не допустимы в разделе username: password при парсинге. Решение заключается в использовании кодирования символов с помощью функции urlencode. Вот и финальный вариант :
javascript:alert%28%27Slonser%20was%20here%21%27%29%3B%2F%2F@github.com#;alert(10);://eow5kas78d0wlv0.m.pipedream.net%27
После нажатия на эту ссылку, мы увидим ожидаемый результат:
Часть 2. Impact
Рассмотрим, что же позволяет сделать данная уязвимость, например если отправить ссылку в крупный чат, то мы сможем от имени пострадавшего:
Читать все сообщения пользователя, а также отправлять сообщения от его имени.
Полностью захватить учетную запись пользователя, например, отправив запрос на установку нового пароля.
Прочитать сообщения с кодами для входа в Telegram, которые приходят в приложение.
Получить удаленное выполнение кода (RCE) в версии Telegram на платформе Electron! Да, вы не ослышались, посредством нажатия на специально сформированную ссылку, жертва может невольно предоставить злоумышленнику доступ к своему компьютеру.
Часть 3. Общение с Telegram Security
Хронология событий развивалась следующим образом:
17 июня — отправил отчет о найденной уязвимости в Telegram, но не получил ответа.
21 июня — обнаружил, что уязвимость была устранена, однако ответа от команды Telegram так и не последовало.
24 июня — отправил запрос относительно статуса моего отчета о уязвимости. Ответа снова не последовало.
26 июня — благодаря связям через знакомых, смог напрямую связаться с командой безопасности Telegram. Получил ответ:
Hello,
Thank you for your email. We will send you an update soon.
All the best,Telegram Support
27 июня — получил сообщение:
Thank you for your report. We would like to award you a bounty of XXXX euro for your findings.
Я специально скрыл сумму вознаграждения, чтобы проверить детективные навыки читателей этой статьи. В качестве подсказки: программа багбаунти Reddit, которая имеет схожие условия (с максимальной выплатой в приложении 10 тыс. долларов, как и у Telegram), предоставила 5 тыс. долларов за аналогичную проблему.
Итак, сколько же мне выплатили?
Ответ
500 евро.
Считаю ли я эту сумму справедливой? — Нет.
Вправе ли Telegram так поступать? — Да, безусловно. У них нет четкой градации уязвимостей и соответствующих выплат на их платформе багбаунти.
Каковы мои впечатления? — Негативные. Создается впечатление, что Telegram не особо заинтересован в обеспечении своей безопасности. Я не уверен, что стоит заниматься поиском уязвимостей ради такого опыта.
Part Final. Выводы
Мои выводы следующие:
Даже в таком продвинутом приложении как Telegram можно обнаружить базовые и, казалось бы, начального уровня ошибки. Поэтому всегда решайтесь на анализ даже самых сложных приложений, так как вероятно вы сможете обнаружить что-то интересное.
К сожалению, программа багбаунти от Telegram оставляет желать лучшего. Отсутствует четкая градация уязвимостей, поддержка не всегда отвечает на обращения, а справедливость выплат вызывает сомнения.
Надеюсь, эта статья была полезной для вас. Жду ваших комментариев!