Мы уже писали, как раскурочить одно-два iOS-приложения с целью их анализа. Теперь мне пришла в голову другая идея. Как насчет того, чтобы взять количество и проанализировать тысячи или, еще лучше, десятки тысяч приложений, проверив их на типичные баги — вшитые в бинарник токены, ключи авторизации и прочие секреты? Эксперимент оказался интересным.
WARNING
Вся информация предоставлена исключительно в ознакомительных целях. Ни редакция, ни автор не несут ответственности за любой возможный вред, причиненный материалами данной статьи.Цель — App Store
Про анализ мобильных приложений написано уже много, разработаны методики проверки, составлены чеклисты. Однако большая часть этих проверок касается безопасности пользователя: как хранятся его данные, как они передаются и как к ним можно получить доступ, используя уязвимости приложения.
Но зачем злоумышленнику копаться с тем, как работает приложение на устройстве конкретного пользователя, если возможно попробовать напасть на серверную часть и увести данные ВСЕХ пользователей? Чем мобильное приложение может быть полезно для нападения непосредственно на вендора?
Если мы заглянем в Mobile OWASP top 10 (азбуку всех софтверных аудиторов), то на десятом месте стоит пункт с туманным названием Sensitive Information Disclosure. В нем подразумевается наличие в дистрибутиве приложения данных, которые можно использовать против пользователя или инфраструктуры поставщика. Тогда почему бы обстоятельно не поисследовать приложения на наличие таких данных?
Магазин App Store фактически стал мировым стандартом, так что выбирать, с кем работать, особенно не приходится. Скачивать приложения с него можно как непосредственно с устройства, так и через iTunes, установленный на рабочую станцию. В наших целях применим второй способ, так как на устройстве для доступа к App Store используется SSL pinning, в то время как в iTunes для рабочей станции его нет и SSL MITM легко устанавливается штатными средствами. А если есть доступ к протоколу, со слезами, кровью, снифером и питоном, но все-таки пишется скрипт для поточного скачивания бесплатных приложений :).
Имея на руках такой инструмент, грех не узнать, как дела с косяками не в том или ином приложении, а в какой-нибудь статистически значимой выборке, то есть в тысячах и десятках тысяч приложений.
Почти в любой статье, где описан процесс дистрибуции через App Store, мы читаем, что
- Приложение зашифровано.
- Приложение защищено DRM.
- Устанавливаемое приложение привязывается к устройству.
Все эти утверждения базируются на том, что в дистрибутиве приложения (которое представляет собой обычный ZIP-архив) скомпилированный код шифруется с привязкой к устройству. Все остальное содержимое передается в открытом виде!
С чего начать ?
Многочисленные мануалы, которые без труда можно найти в Сети, пестрят красивыми примерами того, как найти секреты (то есть захардкоженные данные, которые не должны были попасть туда в отрытом виде: токены авторизации, ключи и тому подобное), используя инструменты strings и grep. В реальном же мире это не работает. Тупой поиск строк создает такое количество мусора, требующего ручного разбора, что автоматизация теряет всякий смысл. Чтобы написать приемлемую систему автоматического анализа, нужно внимательно посмотреть на то, из чего состоит дистрибутив. Распаковав дистрибутивы для ~15 000 приложений и отбросив заведомо неинтересный мусор (картинки, аудио, видео, ресурсы), мы получим 224 061 файл 1396 типов.
Хакер #179. Интернет вещей — новый вектор атак
*.m и *.h (исходники и хидеры) — это, конечно, интересно, но все самое интересное обычно хранится в конфигах, а если точнее, то в XML-, PList- и SQLite-контейнерах, а сертификаты и ключи зачастую хранятся отдельными файлами. Приняв это упрощение, построим TOP интересных нам типов по популярности. Суммарное количество интересных нам файлов 94 452, что составляет 42% от изначального.
В подавляющем большинстве случаев, которые мы условно назовем нормальными, в приложении находятся:
- медийный контент: картинки, аудио, ресурсы интерфейса;
- бинарник приложения (который зашифрован);
- контейнеры с данными — SQLite, XML, PList, BРList;
- кучи бесполезного хлама, которые попали в дистрибутив по неизвестной причине.
Итого, задача сводится к двум:
- Рекурсивному поиску различных секретов в SQLite, XML, PList.
- Поиску всякого «необычного» хлама и сертификатов.
Гипотезы гипотезами, но что про результаты? Оказалось, что ни много ни мало 4% от 15 000 исследованных приложений были с захардкоженнымми секретами… Забегая вперед, скажу, что среди таких данных я увидел и то, что, в общем-то, ожидал увидеть, и такие разработческие недоразумения, которых даже не мог себе представить. Разберем самые показательные.
Как получить бинарник приложения
Скачать iOS-приложение проще всего через десктопную версию iTunes, достаточно зайти в соответствующий раздел и кликнуть Install -> Download, и приложение будет сохранено на диск в файл с расширением ipa, по сути ZIP-архив.
Keep this token in secret
По-видимому, для многих разработчиков не является очевидным, что опубликованное приложение становится публичным. Так, периодически встречаются Oauth-токены твиттера и прочих популярных сервисов. Показательным случаем было приложение, которое собирало контакты, фотки, видео и deviceID пользователей и сохраняло их в амазоновском облаке, и да — используя при этом токен, зашитый в одном из PList-файлов. Используя этот токен, без особого труда можно слить данные по всем пользователям (кстати, для работы с Амазоном есть удобный Python-фреймворк — mobo).
Еще достойна внимания популярная библиотека Urban Airship, которая позволяет гибко управлять push-уведомлениями через одноименный сервис. В мануалах ясно написано, что ни в коем случае master secret в приложении хранить нельзя, так как в опубликованном приложении не может быть секретов. Но мастер-секреты все равно встречаются :).
Кажется, что оба эти примера просто промахи разработчика. Однако проблема, по-видимому, глобальнее. В ряде случаев можно обнаружить токены, которые используются приложениями для работы с платным API сторонних сервисов (SMS-шлюзы, карты Bing и прочее). Другими словами, в дистрибутивах приложения находятся секреты, которые стоят реальных денег.
И похоже, что сейчас нет никакого официально рекомендованного Apple способа их защиты от тех, кто захочет эти ключи использовать по своему усмотрению.
TEST DEV
Большой интерес представляют также различные артефакты процесса тестирования и разработки, то есть ссылки на отладочные интерфейсы, системы контроля версий и ссылки на dev-окружения. Эта информация может быть крайне интересна злоумышленникам, ведь время от времени в них можно найти SQL-дампы баз данных с реально существующими пользователями. Разработчики, как правило, не занимаются безопасностью тестового окружения (оставляя, к примеру, пароли по умолчанию), при этом часто используют реальные данные пользователей для более качественного тестирования.
Вот лишь несколько примеров:
- http://test.mmf.berlingskemedia.net
- http://dev.openstreetmap.de/
- http://dev.aleph-labs.com
Как снять DRM с iOS-приложения
Для того чтобы исследовать приложение более глубоко, необходимо снять с него DRM. В настоящее время известен способ снятия DRM с приложения, но, к сожалению, возможен он только на устройстве с jailbreak, то есть о поточном снятии говорить здесь не приходится. Для этого широко применяются две техники:
- с использованием отладчика (pauldotcom.com/wiki/index.php/Episode226);
- с использованием динамически подгружаемой библиотеки (https://github.com/KJCracks/FAULTYCrack).
Для тех, кто не хочет разбираться, есть полностью автоматический инструмента clutch (https://github.com/ieswxia/clutch).
Tap to enter
То, что в дистрибутивах попадается информация о тестовом окружении, информация о системах контроля версий, не откровение. Но базы данных и конфиги с уже заведенными пользователями стали для меня полным сюрпризом. Встречались и PList с захардкоженными паролями в приложении-визитке. Более того, иногда это не просто пароли, а, натурально, никак не защищенные приватные ключи.
Что это делает здесь?!
Как уже было сказано, в условно нормальном приложении все файлы можно поделить на три группы. Но «ненормальных» приложений тоже великое множество. Первое, на что стоит обращать внимание, — это сертификаты, среди которых можно найти как вполне безобидные корневые сертификаты, так и PKCS-контейнер с сертификатом разработчика…
Еще среди всего этого мусора можно найти вещи, которые вообще непонятно как попадают в приложение. Нужно быть готовым ко всему! Например, куски PHP-кода с захардкоженной учеткой для доступа к базе данных. Или еще пример — рабочий клиентский конфиг OpenVPN.
Что, кроме секретов?
Как бы по своей сути ни был мерзок вопрос лицензирования, но он нашел свое место и здесь. Многие разработчики используют в своих программах код фреймворков, которые бывают под лицензией GPL, требующей раскрытия кода. А как GPL работает с платными и бесплатными приложениями в App Store — вопрос, на который пока нет определенного ответа. И самое, наверное, минорное — базовая проверка параметров безопасной сборки: PIE (Position Independent Executable — аналог ASLR в Windows, когда код приложения при каждом старте размещается по случайному адресу) и SSP (Stack Smash Protection — контроль целостности стека). Само по себе их отсутствие багом не считается, но в случае обнаружения бага в самом бинарнике теоретически можно создать эксплойт. Правда, случаев такой эксплуатации in the wild пока не зафиксировано.
Is there an App for that? Hackapp.com!
После анализа тысяч приложений, когда стали ясны масштабы бедствия, появилось желание создать user-friendly движок, который будет достаточно прост и понятен для того, чтобы любой вендор, даже совершенно не искушенный в безопасности, мог проверить свое приложение. Так родился сервис hackapp.com, которым можно пользоваться абсолютно бесплатно.
Получая на вход ссылку, он сам скачивает приложение, анализирует его, прогоняя описанные выше тесты, и генерирует отчет, который не ранит глаз. То есть теперь ничего не стоит оперативно проверить любое приложение на захардкоженные секреты. У сервиса пока нет поддержки Android (мы работаем над этим) и нет API для проверки приложений пачками.
Заключение
Итого, у нас есть тысячи приложений, в которых находятся тупейшие баги, и это только в App Store. А что происходит в мире Android, еще только предстоит разобраться. Из-за отсутствия DRM для андроидных приложений как минимум возможно автоматизировать декомпиляцию и работать со статическим анализом уже псевдоисходного. Еще нужно как-то «приучать к лотку» разработчиков, чтоб они проверялись перед релизом хотя бы с помощью сервисов вроде hackapp.
Это большие планы, и hackapp.com очень рассчитывает на фидбек, предложения с дополнительными проверками, автоматизация которых сделает вселенную мобильных приложений хотя бы чуточку безопасней. Я их жду!