iOS runtime mobile exploration with Objection, или Хакаем собственное приложение

  • Tutorial


Автор: Андрей Батутин, 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 для дебажной сборки.

Чтобы его получить:

  1. Установите приложение через Xcode на устройство.
  2. Найдите FoodSniffer.app в Finder.

  3. Перейдите в FoodSniffer bundle.

  4. Скопируйте оттуда 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 позволяет делать запросы напрямую к базе следующим образом.

  1. Подключение к базе:

    sqlite connect chinook.db

  2. Запрос к ней:

    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/

https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2016/october/ios-instrumentation-without-jailbreak/.

FoodSniffer iOS app source code.

Frida telegram.

Выражаю особую благодарность @manishrhll.

Примечание. Все вышеописанное стоит применять только к своим приложениям и не пытаться ломать «Тиндер» или еще что-нибудь. Все равно не получится!

DataArt

117,00

Технологический консалтинг и разработка ПО

Поделиться публикацией

Похожие публикации

Комментарии 12
    –1

    Оффтопик, но: что у вас за шрифт в консоли?

      0
      Здравствуйте! Это Meslo LG L DZ Regular.
        0

        Спасибо!

      0
      А почему просто не собрать приложение в релизной конфигурации, но с дев сертификатом? Если у вас проблема с APNS в релизной сборке, то вы же все равно переподписываете приложение и весь смысл затеи теряется.
      Оффтоп, был раз кейс когда в релизной конфигурации (максимально агрессивные оптимизации) почему-то объект в одном месте внезапно умирал и приложение падало в segmentation fault. Добавление строчки print(object) перед обращением к объекту решило проблему. Swift был 2-ой или 3-ий.
        0
        что то напомнило как вылечить через NSLog
        0
        Можно.
        В моем случае сборка с APNS багом была уже относительно старой, и чтобы ее собрать, надо было откатится довольно далеко по коммитам назад, что тоже не проблема.
        Просто я находился в таком положении, когда мне надо было максимально точно показать, что косяк на стороне приложения (сначала я хотел показать, что косяк не на стороне приложения, но потом это оказалось не так).
        И если бы я пересобрал сборку заново, то мои вышестоящие коллеги могли бы сказать, что это разные приложения: «Может, вы там может что-то починили/поменяли, пока пересобирали».
        Мне нужо было работоть с тем, что максимально близко ушло в релиз.
        Довольно специфическая ситуация :)
        0
        Дорогой автор, вы не могли б менее провокационной картинкой открывать статью?
          0
          Автор не виноват! Виноваты мы, его коллеги. Спасибо за критику, учтём!
          –1

          Есть же готовое решение — FireBase. Там есть хендлер ошибок. Там же готовый фреймворк под ios. Пара шагов и перехватчик ошибок у вас в релизе

            0
            У меня есть несколько вопросов:

            1. Разве у вас тестировщики не тестируют релизную версию перед тем как ей попасть в appstore?
            2. Почему не просто Bug tracker’ы? Тот же firebase. По логам в принципе все можно прочитать и понять в чем дело.
              0
              1. Тестировщики? А это кто? (шутка). Нет, в этом случае не тестировал, т. к. жизн-бол.

              2. В 90% случаев  — да.
              В 10 % случаев  — нет. Frida  — это инструмент как раз для таких 10 процентов.
              + у нас не было как такового креша, у нас была ошибка в логике обработки пушей.

            Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

            Самое читаемое