
Как я Telegram ломал
Как-то раз я взломал один из серверов telegram. Не то чтобы это было нечто интересное, да и сами уязвимости стандартные. Удивление скорее вызывает факт того, как телеграм относится к безопасности и почему на протяжении многих лет уязвимостями так никто и не воспользовался. Но, не ошибается тот, кто ничего не делает!

Ещё в мае 2017 года kyprizel обратил внимание на то, что telegram desktop может загружать ZIP-архивы к себе на сервер tdesktop.com. Как позже выяснилось, не только ZIP, а внутри там лежит информация о падении приложения, чтобы разработчик изучил при каких обстоятельствах произошло падение. К тому же разработчик получает к ним доступ через веб-интерфейс, судя по форме аутентификации. Я добавил хост в заметки и благополучно забыл.

Вспомнил я о нём примерно через год, когда обсуждали в чате предстоящие исследования. На тот момент, в корне лежал файл error_log, в котором, как можно было догадаться, писались ошибки. Как минимум, там были полные пути к файлам, но помимо этого любимая ошибка «You have an error in your SQL syntax». Но все мы ленивые, а в bug bounty я вообще стараюсь не участовать, поэтому все осталось как есть.

Прошёл ещё год, меня пригласили выступить на конференции #PartyHack в Казани. А когда у тебя нет материала для выступления — ты смотришь в заметки. Что там у нас? Подозрительный хост в Telegram.
Так как на сервере использовался PHP, о чем свидетельствовал crash.php, я решил немного перебрать файлы с этим расширением, тогда я и наткнулся на info.php, где было содержимое функции phpinfo(). Первое, что я заметил — это использование веб-сервера Apache. Как же так? У всего телеграма nginx, а тут Apache! Да и кто использует apache в 2019?

Что в первую очередь приходит в голову, когда слышишь Apache? Я сразу вспоминаю про mod_status, который собирается с ним по-умолчанию. Этот модуль генерирует страницу с текущим состоянием сервера, про системные ресурсы, запросы на сервер, скорость их обработки. Чаще всего путь к нему /server-status, редко просто /status. Чтобы понять, насколько это популярная ошибка администрирования, достаточно вспомнить, что она много лет висела на сайте apache.org

Я много лет собираю пути к потенциально опасным файлам и директориям в проекте fuzz.txt, поэтому server-status естественно был там.
Вообще в server-status примечательно то, что он показывает и IP адреса клиентов, которые отправляют запросы на сервер. Но в данном случае все запросы были с 127.0.0.1 на виртуальный домен preston-desktop.com. Nginx на фронтовой части просто проксировал все запросы на локальный apache, поэтому раскрытия пользовательской информации не было. Однако, стоило поставить server-status на мониторинг, вот небольшой скрипт сделанный на коленке, который кладет уникальные строки в базу данных sqlite. За небольшой промежуток времени было собрано множество уникальных ссылок, но в основном это запросы на обновления (с указанием версии), а загрузок крашей почти не было. Через некоторое время я увидел админа.

Несмотря на то, что мы имеем ограниченную длину строки, по логам видно, что администратор время от времени скачивает логи падений для дальнейшего анализа, причем там передаются забавные параметры __login, и __token. А POST-запросы на скриншоте мои.
Глянув исходники, можно заметить два интересных метода.
Первый это query_report, который имеет дополнительные параметры apiid, version, dmp и platform. Он возвращает, нужны ли еще логи о падении приложения, или версия уже свежая и об ошибках известно. Механизм создан, чтобы не получать лишнее, а исправлять только актуальное.

Второй — сам report. Уже без дополнительных параметров. Если на предыдущий запрос вернулось слово, которое говорит о необходимости отправить дамп — файл отправляется.

Там же можно посмотреть, что данные отправляются с помощью multipart, где имя файла report.telegramcrash, а его Content-type application/octet-stream.

Таким образом, можно было попробовать позаливать собственные файлы и протестировать уязвимости связанные с распаковкой ZIP и прочими upload-штуками.

И я бы дальше пытался отправлять различную нагрузку, чтобы найти хоть какую-то уязвимость, если бы не одна хитрость. Если подставить к методу report известные имена параметров из другого запроса, валидные значения которых мы взяли из server-status, можно попробовать применить секретную атаку всех веб-хакеров.
Использовав силу мегазорда (одинарная кавычка) в параметре platform можно было наблюдать аномальное поведение ресурса.

Есть кавычка — ошибка, нет кавычки — все хорошо. Для проверки достоверности можно написать какое-нибудь логическое выражение, например platform=mac’ AND ‘a’=’a. В ответе Done, как при удачной заливке файла.
Ну-с, не зря же придумали автоматизацию, поэтому я раскукоживаю sqlmap, который уже запылился от бездействия. Предвидя вопросы — все остальное было хорошо настроено, пользователь в СУБД не привилегированный.

Отправил на security@telegram.org, чуть позже получил заветное письмо о награде в $30,000.
Шучу, $2000 за sqli, и $500 за phpinfo и server-status, что тоже неплохо. И волки целы и овцы сыты, или наоборот.

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

Ещё в мае 2017 года kyprizel обратил внимание на то, что telegram desktop может загружать ZIP-архивы к себе на сервер tdesktop.com. Как позже выяснилось, не только ZIP, а внутри там лежит информация о падении приложения, чтобы разработчик изучил при каких обстоятельствах произошло падение. К тому же разработчик получает к ним доступ через веб-интерфейс, судя по форме аутентификации. Я добавил хост в заметки и благополучно забыл.

Вспомнил я о нём примерно через год, когда обсуждали в чате предстоящие исследования. На тот момент, в корне лежал файл error_log, в котором, как можно было догадаться, писались ошибки. Как минимум, там были полные пути к файлам, но помимо этого любимая ошибка «You have an error in your SQL syntax». Но все мы ленивые, а в bug bounty я вообще стараюсь не участовать, поэтому все осталось как есть.

Прошёл ещё год, меня пригласили выступить на конференции #PartyHack в Казани. А когда у тебя нет материала для выступления — ты смотришь в заметки. Что там у нас? Подозрительный хост в Telegram.
Так как на сервере использовался PHP, о чем свидетельствовал crash.php, я решил немного перебрать файлы с этим расширением, тогда я и наткнулся на info.php, где было содержимое функции phpinfo(). Первое, что я заметил — это использование веб-сервера Apache. Как же так? У всего телеграма nginx, а тут Apache! Да и кто использует apache в 2019?

Что в первую очередь приходит в голову, когда слышишь Apache? Я сразу вспоминаю про mod_status, который собирается с ним по-умолчанию. Этот модуль генерирует страницу с текущим состоянием сервера, про системные ресурсы, запросы на сервер, скорость их обработки. Чаще всего путь к нему /server-status, редко просто /status. Чтобы понять, насколько это популярная ошибка администрирования, достаточно вспомнить, что она много лет висела на сайте apache.org

Я много лет собираю пути к потенциально опасным файлам и директориям в проекте fuzz.txt, поэтому server-status естественно был там.
Вообще в server-status примечательно то, что он показывает и IP адреса клиентов, которые отправляют запросы на сервер. Но в данном случае все запросы были с 127.0.0.1 на виртуальный домен preston-desktop.com. Nginx на фронтовой части просто проксировал все запросы на локальный apache, поэтому раскрытия пользовательской информации не было. Однако, стоило поставить server-status на мониторинг, вот небольшой скрипт сделанный на коленке, который кладет уникальные строки в базу данных sqlite. За небольшой промежуток времени было собрано множество уникальных ссылок, но в основном это запросы на обновления (с указанием версии), а загрузок крашей почти не было. Через некоторое время я увидел админа.

Несмотря на то, что мы имеем ограниченную длину строки, по логам видно, что администратор время от времени скачивает логи падений для дальнейшего анализа, причем там передаются забавные параметры __login, и __token. А POST-запросы на скриншоте мои.
Глянув исходники, можно заметить два интересных метода.
Первый это query_report, который имеет дополнительные параметры apiid, version, dmp и platform. Он возвращает, нужны ли еще логи о падении приложения, или версия уже свежая и об ошибках известно. Механизм создан, чтобы не получать лишнее, а исправлять только актуальное.

Второй — сам report. Уже без дополнительных параметров. Если на предыдущий запрос вернулось слово, которое говорит о необходимости отправить дамп — файл отправляется.

Там же можно посмотреть, что данные отправляются с помощью multipart, где имя файла report.telegramcrash, а его Content-type application/octet-stream.

Таким образом, можно было попробовать позаливать собственные файлы и протестировать уязвимости связанные с распаковкой ZIP и прочими upload-штуками.

И я бы дальше пытался отправлять различную нагрузку, чтобы найти хоть какую-то уязвимость, если бы не одна хитрость. Если подставить к методу report известные имена параметров из другого запроса, валидные значения которых мы взяли из server-status, можно попробовать применить секретную атаку всех веб-хакеров.
Использовав силу мегазорда (одинарная кавычка) в параметре platform можно было наблюдать аномальное поведение ресурса.

Есть кавычка — ошибка, нет кавычки — все хорошо. Для проверки достоверности можно написать какое-нибудь логическое выражение, например platform=mac’ AND ‘a’=’a. В ответе Done, как при удачной заливке файла.
Ну-с, не зря же придумали автоматизацию, поэтому я раскукоживаю sqlmap, который уже запылился от бездействия. Предвидя вопросы — все остальное было хорошо настроено, пользователь в СУБД не привилегированный.

Отправил на security@telegram.org, чуть позже получил заветное письмо о награде в $30,000.
Шучу, $2000 за sqli, и $500 за phpinfo и server-status, что тоже неплохо. И волки целы и овцы сыты, или наоборот.

Пользователей я не взломал (твоя переписка в безопасности), развить атаку дальше не мог, сервер с дампами рандомных пользователей (именно краш-дампы без информации об айдишнике в телеграме, телефоне, сообщениях и чатах) — сомнительная ценность. По идее, можно было бы качать краши и самому изучать и эксплуатировать их. Узнав как роняется телеграм, можно было ронять его у жертвы, а дальше изучать всё что можно выжать из логов падения, если вообще их можно было скачать через эту инъекцию.
Неповторимый оригинал.
Comments 55
Only users with full accounts can post comments. Log in, please.