Как-то раз я взломал один из серверов telegram. Не то чтобы это было нечто интересное, да и сами уязвимости стандартные. Удивление скорее вызывает факт того, как телеграм относится к безопасности и почему на протяжении многих лет уязвимостями так никто и не воспользовался. Но, не ошибается тот, кто ничего не делает!
![](https://habrastorage.org/r/w780q1/webt/wk/di/lw/wkdilw8ddnvximx393ubqzjlzzc.jpeg)
Ещё в мае 2017 года kyprizel обратил внимание на то, что telegram desktop может загружать ZIP-архивы к себе на сервер tdesktop.com. Как позже выяснилось, не только ZIP, а внутри там лежит информация о падении приложения, чтобы разработчик изучил при каких обстоятельствах произошло падение. К тому же разработчик получает к ним доступ через веб-интерфейс, судя по форме аутентификации. Я добавил хост в заметки и благополучно забыл.
![](https://habrastorage.org/r/w1560/webt/gu/--/fr/gu--frvhcdthnxhx2zqioktf634.png)
Вспомнил я о нём примерно через год, когда обсуждали в чате предстоящие исследования. На тот момент, в корне лежал файл error_log, в котором, как можно было догадаться, писались ошибки. Как минимум, там были полные пути к файлам, но помимо этого любимая ошибка «You have an error in your SQL syntax». Но все мы ленивые, а в bug bounty я вообще стараюсь не участовать, поэтому все осталось как есть.
![](https://habrastorage.org/r/w1560/webt/e0/wu/jw/e0wujwumxmexc_bfjeouep6u-ys.png)
Прошёл ещё год, меня пригласили выступить на конференции #PartyHack в Казани. А когда у тебя нет материала для выступления — ты смотришь в заметки. Что там у нас? Подозрительный хост в Telegram.
Так как на сервере использовался PHP, о чем свидетельствовал crash.php, я решил немного перебрать файлы с этим расширением, тогда я и наткнулся на info.php, где было содержимое функции phpinfo(). Первое, что я заметил — это использование веб-сервера Apache. Как же так? У всего телеграма nginx, а тут Apache! Да и кто использует apache в 2019?
![](https://habrastorage.org/r/w1560/webt/rx/ik/ji/rxikjiaasusstkiml3six_gxofg.png)
Что в первую очередь приходит в голову, когда слышишь Apache? Я сразу вспоминаю про mod_status, который собирается с ним по-умолчанию. Этот модуль генерирует страницу с текущим состоянием сервера, про системные ресурсы, запросы на сервер, скорость их обработки. Чаще всего путь к нему /server-status, редко просто /status. Чтобы понять, насколько это популярная ошибка администрирования, достаточно вспомнить, что она много лет висела на сайте apache.org
![](https://habrastorage.org/r/w1560/webt/qd/w-/kx/qdw-kx_ean9mrdh6zivh_r6vxde.png)
Я много лет собираю пути к потенциально опасным файлам и директориям в проекте fuzz.txt, поэтому server-status естественно был там.
Вообще в server-status примечательно то, что он показывает и IP адреса клиентов, которые отправляют запросы на сервер. Но в данном случае все запросы были с 127.0.0.1 на виртуальный домен preston-desktop.com. Nginx на фронтовой части просто проксировал все запросы на локальный apache, поэтому раскрытия пользовательской информации не было. Однако, стоило поставить server-status на мониторинг, вот небольшой скрипт сделанный на коленке, который кладет уникальные строки в базу данных sqlite. За небольшой промежуток времени было собрано множество уникальных ссылок, но в основном это запросы на обновления (с указанием версии), а загрузок крашей почти не было. Через некоторое время я увидел админа.
![](https://habrastorage.org/r/w1560/webt/tg/kz/ic/tgkzicj71uui9md_pu14veile1g.png)
Несмотря на то, что мы имеем ограниченную длину строки, по логам видно, что администратор время от времени скачивает логи падений для дальнейшего анализа, причем там передаются забавные параметры __login, и __token. А POST-запросы на скриншоте мои.
Глянув исходники, можно заметить два интересных метода.
Первый это query_report, который имеет дополнительные параметры apiid, version, dmp и platform. Он возвращает, нужны ли еще логи о падении приложения, или версия уже свежая и об ошибках известно. Механизм создан, чтобы не получать лишнее, а исправлять только актуальное.
![](https://habrastorage.org/r/w1560/webt/td/ge/cj/tdgecjmdy67onlq3wp9hphjcqn8.png)
Второй — сам report. Уже без дополнительных параметров. Если на предыдущий запрос вернулось слово, которое говорит о необходимости отправить дамп — файл отправляется.
![](https://habrastorage.org/r/w1560/webt/7w/sj/c_/7wsjc_j5-mz7hdlnmzqspht2mee.png)
Там же можно посмотреть, что данные отправляются с помощью multipart, где имя файла report.telegramcrash, а его Content-type application/octet-stream.
![](https://habrastorage.org/r/w1560/webt/qy/9b/il/qy9bilvvjbjqilkwb_hvjssrjpi.png)
Таким образом, можно было попробовать позаливать собственные файлы и протестировать уязвимости связанные с распаковкой ZIP и прочими upload-штуками.
![](https://habrastorage.org/r/w1560/webt/ic/yw/wx/icywwxtj2ae-ep5c5vinypogvw0.png)
И я бы дальше пытался отправлять различную нагрузку, чтобы найти хоть какую-то уязвимость, если бы не одна хитрость. Если подставить к методу report известные имена параметров из другого запроса, валидные значения которых мы взяли из server-status, можно попробовать применить секретную атаку всех веб-хакеров.
Использовав силу мегазорда (одинарная кавычка) в параметре platform можно было наблюдать аномальное поведение ресурса.
![](https://habrastorage.org/r/w1560/webt/_b/fn/-3/_bfn-3kkip9j6pmzb66cvuohpk4.png)
Есть кавычка — ошибка, нет кавычки — все хорошо. Для проверки достоверности можно написать какое-нибудь логическое выражение, например platform=mac’ AND ‘a’=’a. В ответе Done, как при удачной заливке файла.
Ну-с, не зря же придумали автоматизацию, поэтому я раскукоживаю sqlmap, который уже запылился от бездействия. Предвидя вопросы — все остальное было хорошо настроено, пользователь в СУБД не привилегированный.
![](https://habrastorage.org/r/w1560/webt/d5/os/61/d5os61kmxgwrq-mnx-c4qbbynri.png)
Отправил на security@telegram.org, чуть позже получил заветное письмо о награде в $30,000.
Шучу, $2000 за sqli, и $500 за phpinfo и server-status, что тоже неплохо. И волки целы и овцы сыты, или наоборот.
![](https://habrastorage.org/r/w1560/webt/7l/64/vw/7l64vwtrgwf_lirxun1xb2mf84g.png)
Пользователей я не взломал (твоя переписка в безопасности), развить атаку дальше не мог, сервер с дампами рандомных пользователей (именно краш-дампы без информации об айдишнике в телеграме, телефоне, сообщениях и чатах) — сомнительная ценность. По идее, можно было бы качать краши и самому изучать и эксплуатировать их. Узнав как роняется телеграм, можно было ронять его у жертвы, а дальше изучать всё что можно выжать из логов падения, если вообще их можно было скачать через эту инъекцию.
Неповторимый оригинал.
![](https://habrastorage.org/webt/wk/di/lw/wkdilw8ddnvximx393ubqzjlzzc.jpeg)
Ещё в мае 2017 года kyprizel обратил внимание на то, что telegram desktop может загружать ZIP-архивы к себе на сервер tdesktop.com. Как позже выяснилось, не только ZIP, а внутри там лежит информация о падении приложения, чтобы разработчик изучил при каких обстоятельствах произошло падение. К тому же разработчик получает к ним доступ через веб-интерфейс, судя по форме аутентификации. Я добавил хост в заметки и благополучно забыл.
![](https://habrastorage.org/webt/gu/--/fr/gu--frvhcdthnxhx2zqioktf634.png)
Вспомнил я о нём примерно через год, когда обсуждали в чате предстоящие исследования. На тот момент, в корне лежал файл error_log, в котором, как можно было догадаться, писались ошибки. Как минимум, там были полные пути к файлам, но помимо этого любимая ошибка «You have an error in your SQL syntax». Но все мы ленивые, а в bug bounty я вообще стараюсь не участовать, поэтому все осталось как есть.
![](https://habrastorage.org/webt/e0/wu/jw/e0wujwumxmexc_bfjeouep6u-ys.png)
Прошёл ещё год, меня пригласили выступить на конференции #PartyHack в Казани. А когда у тебя нет материала для выступления — ты смотришь в заметки. Что там у нас? Подозрительный хост в Telegram.
Так как на сервере использовался PHP, о чем свидетельствовал crash.php, я решил немного перебрать файлы с этим расширением, тогда я и наткнулся на info.php, где было содержимое функции phpinfo(). Первое, что я заметил — это использование веб-сервера Apache. Как же так? У всего телеграма nginx, а тут Apache! Да и кто использует apache в 2019?
![](https://habrastorage.org/webt/rx/ik/ji/rxikjiaasusstkiml3six_gxofg.png)
Что в первую очередь приходит в голову, когда слышишь Apache? Я сразу вспоминаю про mod_status, который собирается с ним по-умолчанию. Этот модуль генерирует страницу с текущим состоянием сервера, про системные ресурсы, запросы на сервер, скорость их обработки. Чаще всего путь к нему /server-status, редко просто /status. Чтобы понять, насколько это популярная ошибка администрирования, достаточно вспомнить, что она много лет висела на сайте apache.org
![](https://habrastorage.org/webt/qd/w-/kx/qdw-kx_ean9mrdh6zivh_r6vxde.png)
Я много лет собираю пути к потенциально опасным файлам и директориям в проекте fuzz.txt, поэтому server-status естественно был там.
Вообще в server-status примечательно то, что он показывает и IP адреса клиентов, которые отправляют запросы на сервер. Но в данном случае все запросы были с 127.0.0.1 на виртуальный домен preston-desktop.com. Nginx на фронтовой части просто проксировал все запросы на локальный apache, поэтому раскрытия пользовательской информации не было. Однако, стоило поставить server-status на мониторинг, вот небольшой скрипт сделанный на коленке, который кладет уникальные строки в базу данных sqlite. За небольшой промежуток времени было собрано множество уникальных ссылок, но в основном это запросы на обновления (с указанием версии), а загрузок крашей почти не было. Через некоторое время я увидел админа.
![](https://habrastorage.org/webt/tg/kz/ic/tgkzicj71uui9md_pu14veile1g.png)
Несмотря на то, что мы имеем ограниченную длину строки, по логам видно, что администратор время от времени скачивает логи падений для дальнейшего анализа, причем там передаются забавные параметры __login, и __token. А POST-запросы на скриншоте мои.
Глянув исходники, можно заметить два интересных метода.
Первый это query_report, который имеет дополнительные параметры apiid, version, dmp и platform. Он возвращает, нужны ли еще логи о падении приложения, или версия уже свежая и об ошибках известно. Механизм создан, чтобы не получать лишнее, а исправлять только актуальное.
![](https://habrastorage.org/webt/td/ge/cj/tdgecjmdy67onlq3wp9hphjcqn8.png)
Второй — сам report. Уже без дополнительных параметров. Если на предыдущий запрос вернулось слово, которое говорит о необходимости отправить дамп — файл отправляется.
![](https://habrastorage.org/webt/7w/sj/c_/7wsjc_j5-mz7hdlnmzqspht2mee.png)
Там же можно посмотреть, что данные отправляются с помощью multipart, где имя файла report.telegramcrash, а его Content-type application/octet-stream.
![](https://habrastorage.org/webt/qy/9b/il/qy9bilvvjbjqilkwb_hvjssrjpi.png)
Таким образом, можно было попробовать позаливать собственные файлы и протестировать уязвимости связанные с распаковкой ZIP и прочими upload-штуками.
![](https://habrastorage.org/webt/ic/yw/wx/icywwxtj2ae-ep5c5vinypogvw0.png)
И я бы дальше пытался отправлять различную нагрузку, чтобы найти хоть какую-то уязвимость, если бы не одна хитрость. Если подставить к методу report известные имена параметров из другого запроса, валидные значения которых мы взяли из server-status, можно попробовать применить секретную атаку всех веб-хакеров.
Использовав силу мегазорда (одинарная кавычка) в параметре platform можно было наблюдать аномальное поведение ресурса.
![](https://habrastorage.org/webt/_b/fn/-3/_bfn-3kkip9j6pmzb66cvuohpk4.png)
Есть кавычка — ошибка, нет кавычки — все хорошо. Для проверки достоверности можно написать какое-нибудь логическое выражение, например platform=mac’ AND ‘a’=’a. В ответе Done, как при удачной заливке файла.
Ну-с, не зря же придумали автоматизацию, поэтому я раскукоживаю sqlmap, который уже запылился от бездействия. Предвидя вопросы — все остальное было хорошо настроено, пользователь в СУБД не привилегированный.
![](https://habrastorage.org/webt/d5/os/61/d5os61kmxgwrq-mnx-c4qbbynri.png)
Отправил на security@telegram.org, чуть позже получил заветное письмо о награде в $30,000.
Шучу, $2000 за sqli, и $500 за phpinfo и server-status, что тоже неплохо. И волки целы и овцы сыты, или наоборот.
![](https://habrastorage.org/webt/7l/64/vw/7l64vwtrgwf_lirxun1xb2mf84g.png)
Пользователей я не взломал (твоя переписка в безопасности), развить атаку дальше не мог, сервер с дампами рандомных пользователей (именно краш-дампы без информации об айдишнике в телеграме, телефоне, сообщениях и чатах) — сомнительная ценность. По идее, можно было бы качать краши и самому изучать и эксплуатировать их. Узнав как роняется телеграм, можно было ронять его у жертвы, а дальше изучать всё что можно выжать из логов падения, если вообще их можно было скачать через эту инъекцию.
Неповторимый оригинал.