Ещё в мае 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, что тоже неплохо. И волки целы и овцы сыты, или наоборот.
Пользователей я не взломал (твоя переписка в безопасности), развить атаку дальше не мог, сервер с дампами рандомных пользователей (именно краш-дампы без информации об айдишнике в телеграме, телефоне, сообщениях и чатах) — сомнительная ценность. По идее, можно было бы качать краши и самому изучать и эксплуатировать их. Узнав как роняется телеграм, можно было ронять его у жертвы, а дальше изучать всё что можно выжать из логов падения, если вообще их можно было скачать через эту инъекцию.
Неповторимый оригинал.
Комментарии (49)
vladimir-ivanov
19.07.2019 16:11+7Заголовок кликбэйтный, молодец.
Описал хорошо, молодец.
Но чувак с дурацкой self xss на макдаке набрал больше плюсиков(
Driver86
19.07.2019 16:58я решил немного перебрать файлы с этим расширением, тогда я и наткнулся на info.php, где было содержимое функции phpinfo()
Как и зачем такое бывает?w0den
19.07.2019 17:55+4Многие разработчики используют функцию
phpinfo()
чтобы проверить, если всё настроено должным образом. Проблема в том, что некоторые разработчики создают незащищённый PHP файл в корень сайта и в качестве имени файла используют info.php, i.php, phpinfo.php и другие «легко угадываемые слова». Kонечно же, всё усложняется, когда разработчики забывают удалить созданный файл.
Например, Google может подсказать, насколько распространена данная практика:
intitle:phpinfo "safe_mode_exec_dir" // About 96,100 results (0.23 seconds)
x86corez
19.07.2019 17:05Да и кто использует apache в 2019?
Я использую :') На всякий случай проверил, /server-status и /status возвращают 404.vlreshet
19.07.2019 19:53+1Та же фигня. Не очень понимаю с каких это пор apache2 — всё, и его нельзя использовать в 2019-ом году.
firk
19.07.2019 20:33+6Apache это legacy больше чем наполовину (а может быть даже и 90%), и меньше половины — полезный функционал. Тащить эти лишние больше-половины как минимум оверхед а вообще это ещё и небезопасно ибо легко промахнуться с их настройками.
И это не в 2019 году началось а уже наверно лет 10 как назад.
Но инерция очень велика, и во всяких популярных готовых веб-приложениях типа "скачал и прокликал next-next-next в веб-установщике" до сих пор на первом месте стоят инструкции как их ставить под апачем, а большинство веб-сайтов именно таким образом и делаются.vlreshet
19.07.2019 21:58C apache2 ежегодно проходим внешнее тестирование безопасности — всё нормально. Тот же Laravel из коробки идёт с .htaccess файлом. Так что я не сказал бы что apache прям умер, и использовать его нельзя-нельзя, моветон, и это только для next-next-next приложений. В том же докер-хабе есть очень много образов с apache, а значит его всё ещё активно используют очень многие.
gecube
20.07.2019 18:02Это ничего не означает. Инерция мышления она просто огромная. А раз так, то есть спрос на эти образы, но это совершенно не означает, что это правильно.
Более того — .htaccess можно относительно легко переписать на rewrite правила nginx и с точки зрения конфигурации это будет более безопасно и более быстро высчитываться.
firedragon
20.07.2019 09:34Очень многие люди. Связка NGINX и Apache. Апач все-же больше имеет крутилок для настройки.
Вот в качестве примера хостинг панель. Я если честно как-то растерялся зачем по умолчанию 2 сервака, но из коробки они работают так.
vestacp.com/docs/#config-log-location-rhel-centossumanai
20.07.2019 09:46+1Апач все-же больше имеет крутилок для настройки.
Как бы не меньше. Единственное, чем он рулит — это его htaccess, в который умеет по умолчанию много софта.Zoomerman
22.07.2019 04:23.htaccess хорош лишь тем, что считывается и выполняется при каждом запросе. Не нужно перезапускать сервис при динамическом изменении конфигурации.
VestaCP вполне удовлетворительно живёт и без апача на беке — вариант nginx+php-fpm
А в варианте, если php поднять до 7.3, скорость обработки php файлов начинает превышать скорость hhvm.
Если без .htaccess нельзя обойтись в проекте, то лучше использовать LightSpeed, который их умеет понимать и работает с сопоставимой с nginx скоростью и скромностью.
decomeron
19.07.2019 20:48Но все мы ленивые, а в bug bounty я вообще стараюсь не участовать, поэтому все осталось как есть.
Не поленились и 2000 баксов заработали. Лень, признак гениальности?
dim2r
19.07.2019 23:44-5Спасибо за урок.
Сразу переименовал свой server-status.
И добавил в несколько ходовых файлов для атак
index.php, user.php, phpinfo.php elrekt.php, config.php
команду
'iptables -A INPUT -s '.$_SERVER['REMOTE_ADDR'].' -j DROP'
Команда уходит в очередь заданий и через пару секунд блокирует IP
Плюс все GET, POST, SESSION переменные фильтруются на подозрительные строки
$s=str_replace('/*', 'xx', $s);
$s=str_replace('*/', 'xx', $s);
$s=str_replace('../', 'xxx', $s);
$s=str_replace('..\\', 'xxx', $s);
$s=str_ireplace('file:', 'xxxxx', $s);
$s=str_ireplace('http:', 'xxxx', $s);
$s=str_ireplace('https:', 'xxxxx', $s);
$s=str_ireplace('script', 'xxxxxx', $s);
$s=str_ireplace('delete', 'xxxxxx', $s);
$s=str_ireplace('drop', 'xxxx', $s);
$s=str_ireplace('select', 'xxxxxx', $s);
$s=str_ireplace('update', 'xxxxxx', $s);
$s=str_ireplace('replace', 'xxxxxxx', $s);
$s=str_ireplace('/etc/', '/xxx/', $s);
$s=str_ireplace('/var/', '/xxx/', $s);
$s=str_ireplace('/root/', '/xxxx/', $s);
$s=str_ireplace('/bin/', '/xxx/', $s);
$s=str_ireplace('/usr/', '/xxx/', $s);
$s=str_ireplace('/sys/', '/xxx/', $s);
$s=str_ireplace('/sbin/', '/xxxx/', $s);
$s=str_ireplace('/proc/', '/xxxx/', $s);
$s=str_ireplace('/boot/', '/xxxx/', $s);FTOH
20.07.2019 08:34И добавил в несколько ходовых файлов для атак
index.php, user.php, phpinfo.php elrekt.php, config.php
команду
'iptables -A INPUT -s '.$_SERVER['REMOTE_ADDR'].' -j DROP'В итоге конкурент у себя поставит картинку <img src="//вашсайт.ру/phpinfo.php">, и вы начнете банить своих клиентов
dim2r
20.07.2019 09:54-2До этого надо догадаться. Обычно атакуют просто боты. Вчера из Китая какой-то долбился, перебирал url. При этом я сайт нигде не рекламировал и никому еще ссылку не передавал. Это просто небольшая разработка на пару страниц.
sumanai
20.07.2019 09:04+1И добавил в несколько ходовых файлов для атак
То есть любой записавший произвольный код в эти файлы, сможет выполнить его с рутовыми(?) привелегиями?dim2r
20.07.2019 09:51попробуйте сломать, могу адрес дать.
это не прод, будет интересно, как он переживет…
ваш пост навел на мысль, что надо еще immutable атрибут поставить на файлы, чтобы ломать было сложнее.trapwalker
22.07.2019 10:55
А также что-то ещё и много отваги.
До этого надо догадаться. Обычно атакуют боты
Это ж типичная ошибка: «security through obscurity».
Вы подумайте кто этих ботов пишет. Даже если они ломятся из китая, это не значит, что они китайские, а их автор не читает Хабр.
Короче, крайне непрофессионально надеяться, что взломщик не догадается о какой-то вашей уязвимости. Латать же дыру в палубе туалетной бумагой надеясь, что волна не догадается… Ну так то до первой волны, сударь.
эх.dim2r
22.07.2019 14:14-1Ну так, взломайте, подтвердите свои слова.
Тыщу рублей дам, если достучитесь до базы.trapwalker
22.07.2019 18:29То есть если я не смогу «достучаться» до вашей базы, это будет хорошим для вас свидетельством надежности вашего сервера и отсутствия в нем уязвимостей?
Выглядит, как еще одна ошибка — попытка нанять непрофильного специалиста для пентеста вашего непубличного сайта с плохими архитектурными решениями внутри…
Это слишком маленькая сумма, чтобы оплатить моё время на эту задачу, сударь.
Я утвердился в актуальности картинки из моего комментария выше.
apro
20.07.2019 01:40(именно краш-дампы без информации об айдишнике в телеграме, телефоне, сообщениях и чатах) — сомнительная ценность
А собственно почему, это же креш-дамп клиента,
так и данные из стека и из кучи,
и какие-то переменные вполне могут содержать и ид и ключи
и конфиденциальную переписку.
Или там только backtrace?
Zoomerman
20.07.2019 02:05+2Как можно вообще доверять приложению, безопасность которого подтверждается только словами разработчика и опровергается отчетами специалистов?
Возможно, когда-нибудь телеграмм и станет безопасным, но вот когда…JKot
20.07.2019 07:14А в других месенджерах ситуация принципиально другая?
Eldhenn
20.07.2019 09:17+1Другие мессенджеры никто не позиционирует как единственную настоящую безопасность, анонимность и приватность.
JKot
20.07.2019 09:59+3Лично мне всё равно кто как себя позиционирует, это лишь маркетинг. По факту любой мессенджер может быть однажды взломан. Всё что нам остаётся лишь верить разработчикам. Поэтому я вообще не вижу разницы в этом плане между мессенджерами.
apro
20.07.2019 10:31+3Поэтому я вообще не вижу разницы в этом плане между мессенджерами.
Но "мессенджеры" которым не нужно знать твой номер телефона по-моему
лучше. По крайней мере не так легко связать взломанный аккаунт и конкретного человека.
dim2r
20.07.2019 15:43Как можно вообще доверять приложению, безопасность которого подтверждается только словами разработчика и опровергается отчетами специалистов?
это особая магия — уметь убеждать и пускать пыль в глаза :)
usharik
20.07.2019 08:19Удивительно, насколько простой и очевидной выглядит описанная последовательность действий. Хотя, это только кажущиеся простота и очевидность))
Dekmabot
Я не настоящий сварщик, но всегда было интересно, почему и как в безопасном мессенджере сниффится такой трафик. Существуют же всякие изощрения вроде ssl-pinning, который вроде как не позволит смотреть протокол, и корневой сертификат от root`а тут не должен спасать. Киньтесь плиз keyword`ами кто в курсе)
DarkByte
Просто ничего не мешает модифицировать приложение и отключить ssl-pinning.
x67
Как это делается? Вообще очень не хватает хороших обзорных статей на тему реверс-инжиниринга на современных мобильных ос
nafikovr
конкретно в случае из статьи эта «уязвимость» называется открытым исходным кодом.
svirvlad
На Android любое приложение можно разобрать и пересобрать по щелчку пальца. Привязку к сертификату обычно делают в network_secury_config.xml, указывая SHA отпечаток сертификата или поставляя сам сертификат с приложением, либо в коде (можно делать автоматом инъекции при помощи Frida). Оба варианта легко убираются.
Под iOS не пробовал, но там наверное проблема будет скорее в установке модифицированного приложения, чем в его реверс-инжиниринге, хотя могу ошибаться. Тоже бы хотелось это узнать.
yarbabin
github.com/telegramdesktop/tdesktop/blob/dev/Telegram/SourceFiles/core/crash_report_window.cpp
Revertis
А где тут про сниффинг?
Dekmabot
А, так всё проще =)
firej
так здесь и не снифался трафик самого tdesktop
его исходники открыты. Факт отправки дампов найден в исходниках, а далее запросы подсмотрены на сервере.
devalone
ssl pinning легко обходится, даже если apk подписан и даже если в бинарнике) Но у телеги открытый код и ничего реверсить не надо, собирай свой кастомный клиент и пользуйся.