Автор: Андрей Батутин, Senior iOS Developer, DataArt.
Не раз и не два, придя на работу (или просто встав с кровати), я обнаруживал в почте гневное письмо, суть которого сводилось к тому, что в аппсторовской сборке приложения ничего не работает, и все надо срочно чинить.
Иногда причиной были мои косяки. Иногда — моих коллег. А иногда — даже самого Apple Inc.
Но самые убийственные сценарии были связаны с багами, которые воспроизводились только на аппсторовских/релизных сборках. Ничто так не ставит в тупик и не заставляет выть перед макбуком, как невозможность подключить дебагер к собственному приложению и посмотреть, что же там происходит.
Похожие трудности создает APNS и его траблшутинг на релизных/ad-hoc сборках.
На тех сборках, где есть production APNS environment, подключить дебагер нельзя.
На тех сборках, где есть дебагер, нет APNS production-пушей. А ведь они-то обычно и отваливаются.
Apple, наподобие ветхозаветного бога, одной рукой дает платформу, где jailbreak скоро отойдет в историю (и пиратство в App Store остается на уровне статистической погрешности), а другой заставляет разработчика почувствовать себя бедным родственником, маленьким Оливером Твистом, посмевшим попросить еще кашки.
Голос за кадром: «Дядя Эппл, пожалуйста, дай еще один дистрибьюшн-сертификатик...»
Для программиста средней руки сделать что-то с релизной/аппсторовской сборкой iOS-приложения было почти нереально. Проще было уволиться еще до релиза.
Если вкратце:
Релизная сборка подписывается Distribution Certificate и использует Distribution Provisioning Profile. Entitlement запрещают присоединять дебагер к процессу приложения. Плюс при скачивании ipa из App Store бинарник оказывается еще и зашифрованным. App Extensions подписываются отдельно.
Т. е. автор приложения как будто может взять и переподписать App Store-сборку дебажным сертификатом, используя дебажный provisioning profile. Но это еще надо знать как сделать. Но даже после этого вопрос, как подключить дебагер к процессу приложения, остается открытым.
Поэтому приходится делать акцент исключительно на то, чтобы не налажать на этапе разработки. И поймать все баги до того, как приложение уйдет в App Store. И логи, больше логов для бога логов!
Но недавно на горизонте замаячила новая надежда.
В предыдущей части мы познакомились с Frida, замечательным фреймворком для dynamic code injection. И обошли с помощью него SSL-pinning в прекрасном проекте FoodSniffer.
В этой статье мы познакомимся с фреймворком, созданным на основе Frida, который значительно облегчает манипуляции с релизными сборками iOS-приложений.
Objection
Objection позволяет заинжектить FridaGadget в iOS-сборку и переподписать ее с нужными сертификатом и provisioning profile.
Подготовка
Для начала нам нужна релизная сборка FoodSniffer.
Важное замечание — при создании ipa отключите “Include bitcode for iOS content”.
Затем нам понадобится provisioning profile для дебажной сборки.
Чтобы его получить:
- Установите приложение через Xcode на устройство.
- Найдите FoodSniffer.app в Finder.
- Перейдите в FoodSniffer bundle.
- Скопируйте оттуда embedded.mobileprovision в папку с вашим релизным ipa.
У вас должно получиться примерно следующее:
После в этого установите objection согласно инструкции. Настоятельно рекомендую использовать именно virtualenv-вариант.
Помимо objection, нам понадобится ios-deploy для запуска пропатченного приложения на устройстве.
Переподпишем приложение!
В терминале выясним хэш нужного нам code sign identity:
security find-identity -p codesigning -v
Нас интересует 386ХХХ identity, т. к. именно она соответствует дебажному серитификату, которым и было подписано приложение при установке через Xcode, из которого мы достали provisioning profile.
Заинжектим FridaGadget и переподпишем наше приложение:
objection patchipa --source FoodSniffer/FoodSniffer.ipa --codesign-signature 386XXX --provision-file embedded.mobileprovision
В результате мы должны получить FoodSniffer-frida-codesigned.ipa.
Теперь нам нужен ios-deploy для установки и подключения к FridaGadget. Это важный этап — если просто установить ipa на устройство через iTunes или Xcode, подключиться к FridaGadget не выйдет.
Предварительно распаковав FoodSniffer-frida-codesigned.ipa:
unzip FoodSniffer-frida-codesigned.ipa
Запускаем наше пропатченное приложение на устройстве:
ios-deploy --bundle Payload/FoodSniffer.app -W -d
Если все прошло успешно, то на устройстве должно запуститься приложение, а в терминале мы увидим:
Теперь в другой вкладке терминала подключим objection к FridaGadget:
objection explore
Профит!
Плюшки, которые предоставляет objection
Обход SSL Pinning
Тут все просто:
ios sslpinning disable
Теперь можно без проблем использовать Proxy Server для мониторинга трафика нашего приложения, как было описано в первой части.
Дамп UserDefaults
ios nsuserdefaults get
В конце дампа мы должны увидеть “mood_state” = “I’m hungry”
Дамп app keychain
ios keychain dump
А вот и наш суперсекретный пароль.
Выборка данных из SQLite-базы.
В приложение я добавил sqlite-базу chinook.db отсюда.
Objection позволяет делать запросы напрямую к базе следующим образом.
- Подключение к базе:
sqlite connect chinook.db
- Запрос к ней:
sqlite execute query select * from albums
Вывод
Objection и Frida позволяют наконец относительно нормально и просто работать с Ad Hoc и Distribution сборками iOS-приложений. Они возвращают программисту власть над собственным приложением, скрытую за слоями защиты, которыми Apple так бережно окутывает iOS-приложения. Плюс Objection и Frida работают на non-jailbroken устройствах. К тому же, они относительно просты в работе.
С ними у меня есть надежда make iOS development great again. Благополучно избежав подрыва новой штаб-квартиры Apple изнутри.
Гипер(полезные) ссылки
Ресерч амстердамских студентов на тему iOS Code Sign.
https://labs.mwrinfosecurity.com/blog/repacking-and-resigning-ios-applications/
FoodSniffer iOS app source code.
Выражаю особую благодарность @manishrhll.
Примечание. Все вышеописанное стоит применять только к своим приложениям и не пытаться ломать «Тиндер» или еще что-нибудь. Все равно не получится!
Автор: DataArt