Не так давно ко мне обратился молодой человек с просьбой помочь в таком вопросе. Дело в том что он столкнулся с проблемой когда единственная резервная копия iPhone не отображается в iTunes, хотя на компьютере присутствует.
Представьте что вам надо восстановить данные на своем iPhone после обновления прошивки, а резервная копия, которую вы сделали час назад, по каким-то причинам уже не доступна. Грусть – печаль… Но решение все же есть… И опять я его подсмотрел у братьев наших меньших из-за океана.
Итак, приступим. На первом этапе возможен один нюанс. То что iTunes не отображает в Настройках в окошке “Резервные копии устройств” необходимую вам копию мы уже усвоили.
Другой вопрос отображается ли там любая другая резервная копия вашего iPhone? Если нет, то начинайте с первого пункта инструкции. Если же в списке резервных копий есть хотя бы одна, тогда сразу переходите к шагу 2.
ШАГ 1 — Если список “Резервные копии устройств” пуст, нам это надо исправить. Для этого прям сейчас берите и создавайте резевную копию iPhone (iPad). Да, я знаю что ваш телефон не содержит в данный момент никакую важную информацию, но нас это сейчас не волнует.
Для нас главное, чтобы в упомянутом списке появилась хотябы одна резервная копия… Давайте для дальнейшего удобства назовем ее “пустая копия”.
ШАГ 2 — На компьютере заходим в папку где хранятся резевные копии (в зависимости он ОС вашего компьютера):
Mac: ~/Библиотеки/Application Support/MobileSync/Backup/
Символ тильды (~) соответствует папке пользователя. По умолчанию папка «Библиотека» скрыта от посторонних глаз. Для ее отображения кликаем в верхнем меню Переход и зажимаем кнопку Option — в открывшемся меню появится строка Библиотека
Windows XP: Documents and Settings(имя пользователя)Application DataApple ComputerMobileSyncBackup
Windows Vista, Windows 7 и Windows 8: Пользователи(имя_пользователя)AppDataRoamingApple ComputerMobileSyncBackup
ШАГ 3 — В этой папке должно быть как минимум две папки с резервными копиями: нужная и пустая. Имена папок состоят из хаотического набора символов, поэтому определить какая из них какая можно только по дате создания (в Свойствах папки).
ШАГ 4 — Откройте папку «пустой копии» (которую вы только что создали или та что отображается в iTunes). Вы увидите длинный список каких-то непонятных файлов. Прокрутите его в самый низ где найдете файл с именем: info.plist.
ШАГ 5 — Откройте файл info.plist при помощи любого html редактора (я пользуюсь Taco HTML Edit) и выделите весь текст с самого начала и до строки <kеy>IC-Info.sidv</kеy>
(где-то в середине файла), включая эту строку тоже.
Скопируйте в буфер обмена выделенный текст (Command + C).
ШАГ 6 — Теперь переходите в папку «нужной копии» и находите такой же файл info.plist. Открывайте его и также выделяйте весь текст с самого начала и до строки <kеу>IC-Info.sidv</kеy>
.
Удаляйте этот текст и вставляйте из буфера обмена, скопированный ранее из «пустой папки».
ШАГ 7 — Сохраните и закройте файл.
ШАГ 8 — Запускайте iTunes. Теперь в Настройках > Устройства должна появится та самая копия, которую вы хотите накатить на свое устройство. Аллилуйя!
А теперь тот кто попробовал данный метод, быстренько спустились в комментарии и написали о своих результатах.
Подписывайтесь на наш Telegram, VK.
I am developing an iPhone app, in which i want use an .plist file to save some config variables.
in my xcode where to create that .plist file and how to access it???
thank you,
asked Jun 4, 2009 at 4:39
You would put in the resources folder. Then use something like this to load it:
NSString *file = [[NSBundle mainBundle] pathForResource:@"TwitterUsers" ofType:@"plist"];
NSArray *Props = [[NSArray alloc] initWithContentsOfFile:file];
Where TwitterUsers is the name of your plist file.
If your plist file contains keys and values you would make the second line an NSDictionary instead of NSArray.
answered Jun 4, 2009 at 4:44
SolmeadSolmead
4,1392 gold badges25 silver badges30 bronze badges
1
To store the plist file in your Documents directory you will have to include plist file in your app and then on first launch copy it to Documents directory.
To get access to the file in Documents directory:
NSArray *paths =
NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0];
// <Application Home>/Documents/foo.plist
NSString *fooPath =
[documentsPath stringByAppendingPathComponent:@“foo.plist”];
answered Jun 4, 2009 at 10:33
stefanBstefanB
76.5k27 gold badges116 silver badges141 bronze badges
1
I would recommend keeping it in the Resources directory in the app bundle, but you can just drag it into the project window. The NSBundle
method pathForResource:ofType:
should give you a path, which you can pass to NSDictionary
‘s dictionaryWithContentsOfFile:
.
Edit: Sorry, full code sample (thought I’d already copied & pasted):
NSString *path = [[NSBundle mainBundle] pathForResource:@"MyConfig" ofType:@"plist"];
NSDictionary *myConfig = [NSDictionary dictionaryWithContentsOfFile:path];
answered Jun 4, 2009 at 4:44
Ross LightRoss Light
4,7011 gold badge25 silver badges36 bronze badges
0
EDIT Just occured to me «config variables» might not be immutable. If that is the case, disregard this answer.
I would recommend you use NSUserDefaults to store configuration variables instead of rolling your own system.
If you are modifying a .plist
inside your application bundle, you will risk invalidating the signature on the bundle, while will not end well.
If you must store and modify your own .plist
, store it in the Documents
directory, which is also where your application should store anything that it downloads, creates, etc. See File and Data Management and NSFileManager.
answered Jun 4, 2009 at 5:13
freespacefreespace
16.4k4 gold badges36 silver badges58 bronze badges
By default if you have included the plist in the project anywhere (under Resources or otherwise) XCode will copy it into the application bundle where you can get to it with the aforementioned pathForResource
call. Just thought I’d mention that as you might prefer a grouping where you do not have it in resources…
answered Jun 4, 2009 at 23:20
you can find the example sqlite book ….. the silte data file was save into the directory ‘Document’ …. you will know the prcess
answered Jun 4, 2009 at 5:21
-
Why would it invalidate the bundle?
-
Would this plist file in the resources folder be backed up in iTunes like files in the documents folder?
answered Sep 23, 2009 at 5:35
Для создания резервной копии iPhone или iPad не нужно никаких особенных знаний. Инженеры Apple сделали этот процесс максимально простым и доступным для обычных пользователей. Но что если вам понадобилось перенести резервную копию с одного компьютера на другой? Или достать из бэкапа в iTunes какие-то определенные данные? Либо же скачать резервную копию iCloud на компьютер целиком? С любой из этих и многими другими нестандартными задачами, связанными с резервными копиями iPhone, поможет справиться данное руководство.
Где хранится резервная копия iPhone
Начнем двигаться от простых операций к сложным. Предположим, вам необходимо скопировать резервную копию iPhone или iPad, сделанную при помощи iTunes. Например, для того чтобы сохранить её на внешнем носителе или в облачном хранилище. Это может быть полезно в случае, если в резервной копии содержится по-настоящему важная информация и вы хотите дополнительно удостовериться, что она никуда не пропадет. Даже в случае поломки компьютера.
Найти резервную копию очень просто, но на разных операционных системах она располагается в различных местах.
- В macOS: в папке ~//Библиотеки/Application Support/MobileSync/Backup/.
- В Windows XP: в папке Documents and Settings(имя_пользователя)Application DataApple ComputerMobileSyncBackup.
- В Windows 7/8/10: в папке Пользователи(имя_пользователя)AppDataRoamingApple ComputerMobileSyncBackup.
На компьютерах под управлением Windows 7/8/10 папка с резервными копиями из iTunes является скрытой. Первоначально вам потребуется сделать её видимой. Для этого перейдите в «Панель управления» → «Параметры папок» → «Вид» и поставьте флажок на пункте «Показывать скрытые файлы, папки и диски».
Отметим, что на новых версиях ОС Microsoft перейти к папке с резервными копиями можно еще проще. Достаточно нажать «Пуск» и ввести в поиске команду «%appdata%/Apple Computer/MobileSync/Backup» (без кавычек). Результатом выполнения запроса станет открытие папки с сохраненными на компьютере резервными копиями iTunes.
Как определить для какого устройства какая копия
Определить местонахождение резервных копий iPhone и iPad удалось, но как теперь разобраться, какую из папок следует скопировать? Папка с бэкапами встретит вас подобным окном, в том случае, если вы создавали резервные копии нескольких iOS-устройств в iTunes.
К счастью, найти нужную папку несложно. Для этого перейдите в одну из папок с резервными копиями и найдите в ней файл Info.plist. Откройте его при помощи текстового редактора, например, WordPad и выполните поиск по запросу Product Name. Под найденной строкой и будет написано к какому из ваших мобильных устройств относится эта копия.
Как правильно перенести резервную копию на другой диск
Найти и скопировать папку с резервной копии с одного диска на другой недостаточно для её правильного переноса. Для того, чтобы бэкап определился в iTunes после переноса, нужно создать символические ссылки.
Для Windows
Шаг 1. Закройте iTunes.
Шаг 2. Скопируйте папку Пользователи(имя_пользователя)AppDataRoamingApple ComputerMobileSyncBackup на другой диск, например, в папку Резервная копияBackup.
Шаг 3. Удалите папку с резервными копиями с диска, с которого выполнялось перемещение. Важно! Обязательно убедитесь в том, что папка была скопирована полностью, чтобы избежать случайной потери данных.
Шаг 4. Запустите командную строку от имени администратора. Для этого перейдите в меню «Пуск», введите в поиске запрос «Командная строка», щелкните по ярлыку утилиты правой кнопкой и нажмите «Запуск от имени администратора».
Шаг 5. В командной строке введите следующую команду:
MKLINK /D «прежний путь до папки с резервными копиями» «новый путь».
Пример:
MKLINK /D «C:Usersимя_ пользователяAppDataRoamingApple ComputerMobileSyncBackup» «D:Резервная копияBackup»,
где:
- C: — буква диска, на которой ранее хранились резервные копии.
- D: — буква диска, на который вы хотите перенести резервные копии.
- Имя_пользователя — ваше имя пользователя.
- Резервная копияBackup — папка, в которую была скопирована резервная копия на шаге 2.
Приведем еще более наглядный пример. Если ваше имя пользователя в Windows «Василий Петров» и вы переносите резервные копии с диска C на диск E, то ввести необходимо следующую команду:
MKLINK /D «C:UsersВасилий ПетровAppDataRoamingApple ComputerMobileSyncBackup» «E:Резервная копияBackup».
Шаг 6. Если все сделано правильно, результатом выполнения операции станет сообщение об успешном создании символических ссылок.
Готово! Вы перенесли резервные копии с одного диска на другой. Убедиться в этом можно запустив iTunes и перейдя в меню «Правка» → «Настройки» → «Устройства». В списке «Резервные копии устройств» будет доступен список всех ваших бэкапов.
Для Mac
Шаг 1. Завершите работу iTunes. Для этого нажмите правой кнопкой мыши на иконке iTunes на панели Dock и выберите пункт «Завершить».
Шаг 2. Перейдите в папку /Library/Application Support/MobileSync/.
Шаг 3. Скопируйте папку Backup на другой диск, после чего удалите оригинальную папку с резервными копиями. Вновь предупредим о том, что нужно дождаться завершения копирования, в ином случае вы можете потерять важные данные.
Шаг 4. Запустите «Терминал». Проще всего это сделать при помощи поиска Spotlight.
Шаг 5. В окне «Терминала» введите команду:
ln -s /Volumes/новая_папка/Backup /Library/Application Support/MobileSync/,
где «новая_папка» — папка, в которую вы ранее переместили резервные копии.
Готово! Проверить успешное проведение операции вы можете запустив iTunes и посмотрев наличие резервных копий на вкладке «Устройства».
Аналогичным образом осуществляется и активизация резервных копий iTunes на компьютере с переустановленной системой, либо на новом компьютере. Для того, чтобы iTunes увидел бэкапы ваших устройств, после его установки на новой системе понадобится ввести одну из указанных выше команд.
Как извлечь данные из бэкапов iPhone и iPad
Довольно часто у пользователей iPhone и iPad возникает необходимость извлечь из старой, а иногда и актуальной резервной копии iOS-устройства какую-то конкретную информацию или файлы. С решением этой задачи помогает хорошо знакомая многим владельцам техники Apple утилита iTools.
Шаг 1. Загрузите последнюю версию iTools с официального сайта программы. Отметим, что утилита является полностью бесплатной.
Шаг 2. Распакуйте архив с утилитой и запустите iTools.exe. Подключать iPhone или iPad к компьютеру необязательно.
Шаг 3. Перейдите на вкладку «Инструменты».
Шаг 4. Выберите инструмент iTunes Backup Manager.
Шаг 5. Щелкните два раза по резервной копии, из которой необходимо извлечь файлы.
Шаг 6. Выберите информацию, которую нужно выгрузить из резервной копии, нажмите «Экспорт» и укажите папку для сохранения файлов.
iTools позволяет вытянуть из резервных копий iPhone и iPad самую разную информацию начиная от контактов и текстовых сообщений, заканчивая документами из приложений и фотографиями. Большинство данных скачиваются традиционным способом, но есть пара исключений.
Во-первых, данные из приложений. Их при помощи iTools найти можно, но придется повозиться. Дело в том, что списка с четким перечислением названий приложений утилита не показывает. Из-за этого быстро найти нужно приложение не удастся, но главное, что это возможно. Для старта поиска понадобится перейти в папку var → mobile → Applications, в которой уже методично искать приложения, данные из которых вам нужны.
Рекомендуем ориентироваться на названия, которые хоть и не конкретные, но содержат информацию о приложении. Вложения мессенджера Viber, например, можно обнаружить в папке com.viber → Attachments.
А во-вторых, не так просто скачать контактную книгу и коллекцию текстовых сообщений. С их обнаружением проблем нет, они находятся в разделе «Общие каталоги» под своими именами, а вот с дальнейшим использованием есть. В резервной копии контакты и SMS хранятся в формате «.sqlitedb», который никакими стандартными утилитами не запускается. Поэтому вам нужно будет воспользоваться специальным конвертером.
Шаг 1. Загрузите бесплатную программу SQLite Browser.
Шаг 2. Установите и запустите программу.
Шаг 3. Нажмите Ctrl + O и выберите файл контактной книги в формате .sqlitedb.
Примечание: в качестве типа файла нужно выбрать пункт «All files».
Шаг 4. Перейдите на вкладку «Выполнение SQL» и вставьте в форму следующую команду:
select ABPerson.prefix,ABPerson.suffix, ABPerson.first,ABPerson.middle,ABPerson.last, ABMultiValue.value, ABPerson.note, ABPerson.nickname, ABPerson.organization, ABPerson.department, ABPerson.jobtitle, ABPerson.birthday from ABPerson,ABMultiValue where ABMultiValue.record_id=ABPerson.ROWID
Шаг 5. Нажмите кнопку Start.
Шаг 6. Нажмите на кнопку сохранения и выберите пункт «Экспортировать в CSV».
Сразу после этого в указанной папке появится ваша контактная книга (либо текстовые сообщения) в удобоваримом для последующего использования формате.
Как скачать резервную копию с iCloud
Шаг 1. Загрузите и установите утилиту Wondershare Dr.Fone for iOS с официального сайта программы. Приложение, увы, платное, как и любые другие средства со схожим набором функций.
Шаг 2. Запустите Wondershare Dr.Fone и перейдите в меню Recover from iCloud Backup File.
Шаг 3. Укажите логин и пароль своей учетной записи Apple ID.
Шаг 4. Дождитесь появления списка резервных копий.
Шаг 5. Выберите необходимую резервную копию и нажмите Download.
Шаг 6. Пометьте флажками данные резервной копии, которые вам необходимо скачать.
Шаг 7. Дождитесь окончания процесса обработки и появления в окне программы списка загруженных из iCloud данных. Выберите необходимые файлы и нажмите Recover.
Шаг 8. В открывшемся окне выберите пункт Recover to Computer и укажите папку, в которую сохранятся файлы.
Если же у вас нет желания тратить деньги на специальные утилиты, то выход один, весьма очевидный. Сделайте резервную копию своего iPhone или iPad в iTunes, выполните полный сброс мобильного устройства и во время первоначальной настройки выберите в качестве бэкапа для восстановления копию из iCloud. Благодаря такому решению на вашем iPhone или iPad окажется та самая резервная копия из iCloud, которая вам нужна. Далее копию гаджета следует сделать в iTunes и описанным нами ранее способом получить к ней доступ. Конечно, не самый удобный в использовании способ, но, тем не менее, он работает.
✅ Подписывайтесь на нас в Telegram, ВКонтакте, и Яндекс.Дзен.
Привет! Меня зовут Гриша, я работаю application security инженером в компании Wrike и отвечаю за безопасность наших мобильных приложений. В этой статье я расскажу про основы безопасности iOS-приложений. Текст будет полезен, если вы только начинаете интересоваться безопасностью мобильных приложений под iOS и хотите разобраться, как все устроено изнутри.
Disclaimer: Материал написан в образовательных целях, чтобы новички могли разобраться в принципах работы безопасности мобильных приложений. Используйте инструкции из статьи только на тестовых устройствах или же с разрешения владельца приложения (например, в рамках программы поиска уязвимостей).
Подготовка окружения
Для начала нужно подготовить окружение.
Вот что для этого необходимо:
-
Компьютер-хост. В идеале это должен быть MacOS, потому что с другой операционной системой возникнут сложности с установкой и запуском специализированного ПО.
-
Джейлбрейкнутый тестовый девайс с желаемой версией iOS. iOS симулятор, который поставляется в комплекте с Xcode, не подойдет, так как он предназначен для запуска приложений, собранных под x86 архитектуру. Релизные версии приложений, предназначенные для запуска на реальном девайсе, собираются под ARM. Поэтому приложения, загруженные из Apple App Store, не получится запустить в симуляторе iOS.
-
Сеть Wi-Fi, которая разрешает трафик от клиента к клиенту (или подход SSH через USB).
-
Перехватывающий прокси (Burp Suite, Charles, mitmproxy и т.д.).
Это набор максимум: на самом деле можно работать и не на MacOS, и не на джейлбрейкнутом устройстве, но будут дополнительные сложности: отсутствие нужных инструментов, необходимость переподписывать приложение с использованием сертификата разработчика и т.д.
Джейлбрейк. Для тестирования желательно сделать джейлбрейк девайса.
Краткая инструкция выглядит так:
-
Найти подходящее тестовое устройство и сделать резервную копию.
-
Проверить, что для установленной версии iOS есть джейлбрейк.
-
Выбрать подходящий вариант (по этой ссылке можете почитать про сравнение между Tethered/Untethered).
-
Джейлбрейкнуть, следуя инструкции к выбранному способу: например, Checkra1n или Unc0ver.
Если хотите узнать подробно о том, как работают джейлбрейки, почитайте статью с техническим анализом эксплойта для checkm8 от Digital Security. Там много интересных подробностей.
Полезные приложения. Теперь на девайс можно поставить приложения, которые нельзя установить на iPhone без джейлбрейка. Для этого нужно установить Cydia. Установка будет отличаться в зависимости от выбранного джейлбрейка, просто следуйте инструкции.
Вот некоторые полезные приложения:
-
Файловый менеджер (Filza File Manager).
-
Терминал (например, NewTerm 2).
-
Sshd (OpenSSH) (нужно поменять стандартный пароль).
-
Обход обнаружения джейлбрейка (например, Liberty Lite).
-
Обход валидации SSL сертификатов / пиннинга (ssl-kill-switch2).
-
Приложение для установки неподписанных IPA файлов (например, AppSync Unified).
Прокси. Следующий обязательный шаг — это настройка прокси для перехвата трафика приложения на устройстве.
Логика этого процесса аналогична настройке перехвата для браузера:
-
Организуем доступность своего хоста (с запущенным прокси) для мобильного устройства: подключаем хост и девайс к одной Wi-Fi сети или используем SSH поверх USB.
-
Конфигурируем прокси в настройках мобильного устройства.
-
Запускаем перехватывающий прокси на компьютере-хосте.
-
Добавляем сертификат от прокси в доверенный на устройстве для перехвата HTTPS-трафика (подробную инструкцию для Burp Suite ищите по этой ссылке).
Перехват трафика мобильного приложения может быть полезен для увеличения поверхности атаки: он покажет новые хосты, сервисы, API, которыми пользуются только мобильные приложения. Разработчики могут уделять меньше внимания безопасности «внутренних» API, которые не видят пользователи. Возможно, будут какие-то ключи, параметры или заголовки, зашитые в код приложения и предоставляющие доступ к этим сервисам. А еще перехват трафика поможет лучше понять логику работы приложения.
IPA файл
Теперь нам нужно приложение для тестирования. Если мобильные приложения и находятся в скоупе для исследования по программе Bug Bounty, то максимум, что мы получим, — ссылку на официальный магазин приложений для платформы.
Мы можем попробовать перехватить трафик запущенного приложения и использовать разного рода инструменты, но для полноценного анализа желательно иметь IPA файл — аналог APK файла для Android. Чем ближе к оригинальному, тем лучше.
Находим IPA файл. Получить IPA файл можно несколькими способами:
-
Использовать приложения для управления устройством с компьютера (например, iTunes или Apple Configurator 2). Они скачивают приложения из App Store, а потом заливают на девайс. Но можно поймать момент, когда файл уже скачан на компьютер из App Store, но еще не залит на девайс, и скопировать его.
-
Установить приложение из App Store, а потом сдампить (например, через frida-ios-dump). Этот способ сработает только с джейлбрейкнутым девайсом, и в данном случае будут отсутствовать файлы с мета-информацией для App Store.
-
Использовать сайты с IPA файлами. Но там вы, скорее всего, найдете уже неоригинальный файл и исследовать его на безопасность будет не так интересно, но все еще полезно для использования.
Как получить IPA файл с помощью Apple Configurator 2:
-
Установить приложение на девайс.
-
Выбрать приложение в Apple Configurator 2, подключить девайс, начать обновление.
-
Отключить девайс после завершения шага загрузки приложения (опционально, так загруженный IPA файл дольше доступен в кеше приложения).
-
Забрать IPA на хосте по пути вида: ~/Library/Group Containers/.group.com.apple.configurator/Library/Caches/Assets/TemporaryItems/MobileApps.
Что находится внутри IPA файла. Теперь файл нужно распаковать и посмотреть, что там внутри. Для IPA пакетов Apple использует LZFSE — алгоритм сжатия данных без потерь с открытым исходным кодом. Для распаковки нужен подходящий инструмент: например, unzip-lzfse.
Что находится внутри IPA файла:
-
Директория Payload — это все, что относится непосредственно к приложению.
-
Payload/Application.app — это скомпилированный код и статические ресурсы:
-
Info.plist — аналог Android-манифеста, который описывает свойства приложения для операционной системы, права, что приложение будет использовать (интернет или камеру и т.д.);
-
Основной исполняемый двоичный файл скомпилирован под ARM либо с использованием формата Mach-O, либо — fat binary;
-
Внешние библиотеки, фреймворки, плагины, ресурсы;
-
Информация о сборке для Apple. Например, embedded.mobileprovision с информацией о разработчике и приложении.
-
-
iTunesArtwork — иконка приложения для AppStore.
-
iTunesMetadata.plist — информация о приложении: жанр, возрастные ограничения, копирайты и т.д.
-
WatchKitSupport/WK — поддержка Apple Watch (если есть).
Файлы с расширением *.plist (property list) — это бинарные файлы, в которых хранятся сериализованные объекты. Открывать их удобнее всего в Xcode или любом hex-редакторе (например, 010 Editor с плагином BPlist.bt).
Посмотрим на информацию для App Store. Для примера возьмем приложение Wrike (файл iTunesMetadata.plist):
Эта информация публично доступна в App Store. Недоступны только данные аккаунта Apple ID, от имени которого скачано.
-
UIRequiredDeviceCapabilities — связанные с устройством функции, необходимые приложению для работы.
-
Apple-id — каждое скачанное из App Store приложение «привязано» к вашему Apple ID.
-
SoftwareSupportedDeviceIds — какие устройства поддерживает это приложение: 1 — классические iPhone, 2 — iPod Touch, 4 — iPad, 9 — современные iPhone.
-
Разного рода мета-информация (авторские права, ограничения по возрасту, информация о разработчике и т.д.), которую можно найти в App Store.
Теперь переходим к просмотру содержимого файла “Info.plist” (на примере приложения DVIA-2):
Здесь можно увидеть информацию об основных правах, разрешениях, URL схемах и т.д.:
-
Camera Usage Description — разрешение на использование камеры с описанием того, для чего именно приложение будет её использовать.
-
NSAllowsArbitraryLoads — разрешает приложению использовать небезопасные HTTP-соединения.
-
Executable file — указывает на основной исполняемый файл, в данном случае — “DVIA-v2”.
-
URL Schemes — кастомная URL схема, зарегистрированная на устройстве и привязанная к приложению. Например, приложение может быть открыто через ссылку в браузере или в почтовом клиенте.
-
Информация об иконках, требуемых версиях iOS, поддерживаемых устройствах (UIDeviceFamily) и т.д.
Кастомные URL-схемы. Рассмотрим кастомные UPL-схемы отдельно, так как они могут быть потенциально опасными. Есть разные сценарии использования таких ссылок, но они могут стать хорошей точкой входа для того, чтобы в них что-то поместить и посмотреть на поведение приложения. Также поведение может быть интересно при эксплуатации XSS уязвимостей на мобильном девайсе.
Например, приложение DVIA-v2 поддерживает схемы “dvia://” и “dviaswift://”, и переход по ссылкам со схемой перенаправляет в приложение.
Приложение может не валидировать входные параметры с кастомной схемой, что приведет к проблемам с безопасностью. Например, вот ссылка на issue по Skype: по клику на ссылку происходил звонок.
Существуют и стандартные URL-схемы: “tel:”, “facetime:”, “facetime-audio:”, “sms:”, “mailto:”. При переходе по ссылкам с заданными схемами происходит перенаправление в соответствующее приложение на девайсе.
Файл embedded.mobileprovision. Приложению требуется файл профиля разработчика (embedded.mobileprovision) как для локальной разработки, так и для размещения в App Store. По-умолчанию он генерируется в Xcode и удаляется при публикации в App Store. В этом файле содержится информация о разработчике и его сертификат в формате PEM (см. DeveloperCertificates), что может быть интересно для сбора дополнительной информации. Однако получить такой файл можно только в том случае, если приложение было получено в обход App Store. Также такой файл может быть использован для переподписания приложения для его модификации и установки на устройство, см. Patching iOS Applications.
Исполняемый файл. Прежде чем приступать к реверсу исполняемого файла, можно попробовать собрать информацию простыми инструментами: вытащить строки, сделать class-dump и увидеть, что в нем есть какой-нибудь токен или секрет. А еще можно посмотреть, какие есть классы, увидеть следы механизмов обнаружения джейлбрейка и то, какие у приложения есть вызовы функций.
Дальнейший анализ возможен с помощью IDA Pro, Ghidra или других похожих инструментов.
Попробуем понять логику проверки девайса на джейлбрейк в приложении DVIA-v2:
Рассмотрим основные шаги:
-
Проверка существования определенных файлов с помощью NSFileManager fileExistsAtPath:
-
”/Applications/Cydia.app” — приложение Cydia (для установки сторонних приложений на джейлбрейкнутом девайсе);
-
“/Library/MobileSubstrate/MobileSubstrate.dylib” — зависимость, используемая во многих расширениях под джейлбрейк;
-
“/bin/bash” — наличие установленного Bash;
-
“/user/sbin/sshd” — проверка наличия SSH демона;
-
“/etc/apt” — файлы приложения Cydia.
-
-
Создание файла со строкой “This is a test” в приватной директории: “/private/jailbreak.txt”.
-
Попытка открыть приложение Cydia через ссылку с кастомной URL схемой: “cydia://package/com.example.package”. Используемое API: NSUrl URLWithString.
Защита бинарных файлов. Бинарные файлы могут быть защищены при распространении через App Store.
Рассмотрим возможные флаги, которые можно указать при сборке приложения для защиты бинарных файлов:
-
ASLR (Address space layout randomization, рандомизация адресного пространства) — флаг PIE.
-
Защита от Stack Smashing (флаг — fstack-protector-all). Приложения, которые используют «канарейки» (стандартный механизм обнаружения переполнения буфера на стеке), будут содержать _stack_chk_fail и _stack_chk_guard в исполняемом файле.
-
ARC (Automatic Reference Counting) — автоматический подсчет ссылок, _objc_release в исполняемом файле.
-
Флаг cryptid — отвечает за шифрование исполняемого файла. Значение 1 указывает, что приложение зашифровано. Для незашифрованных приложений значение cryptid равно 0.
Эти флаги можно проверить, используя команду otool, которая есть на Mac OS. Эта команда умеет отображать указанные части объектных файлов или библиотек.
Исполняемые файлы приложений, которые распространяются через App Store, защищены и зашифрованы. Поэтому сделать анализ строковых констант и декомпилировать код не получится. Но загрузчик расшифровывает iOS- приложение и загружает его в память, когда оно запускается. Этим можно воспользоваться: например, используя frida-ios-dump, сдампить запущенное приложение.
Mobile Security Framework. Вручную прогонять все указанные инструменты для статического анализа и смотреть все флаги интересно только в первый раз, нужно сделать этот процесс быстрым и удобным. Mobile Security Framework — один из фреймворков, который может помочь. Это инструмент для тестирования на проникновение, анализа вредоносных программ и оценки безопасности мобильных приложений. Может выполнять статический и динамический анализ (под iOS есть только статический анализ). Удобно отображает дополнительную информацию о приложении.
Посмотрим на те же флаги для защиты бинарных файлов, но с красивым интерфейсом:
Мы видим URL-схему, разрешение на использование HTTP-трафика, разрешения (permissions), которые могут быть опасны. Все уже собрано в один большой отчет, который можно выгрузить в PDF и изучить.
Установка и запуск
Мы сделали статический анализ. Теперь попробуем запустить приложение на джейлбрейкнутом девайсе и посмотреть, что оно делает.
Первая проблема, с которой мы сталкиваемся, — установка. Для пользователей есть один официальный способ это сделать — App Store. Для организаций существуют разные enterprise-решения, которые могут распространять приложение внутри компании в обход AppStore на девайсах, в которых уже включены MDM и т.д.
Нам это не нужно, поэтому попробуем поставить приложение (например, AppSync Unified), которое позволит устанавливать неподписанные файлы, файлы с невалидной подписью или с возможностью переподписать файл.
Самый простой вариант для этой задачи — Xcode (Window — Devices and Simulators) или Cydia Impactor (но в связи с последними изменениями от Apple у меня он не работает, вот тут есть информация про ошибки).
Также неподписанное приложение можно установить, используя специальное приложение на девайсе. Например, через Filza: загрузить IPA на девайс (например, через SFTP), найти IPA файл и нажать “Install”.
Теперь попробуем запустить. При запуске приложения можно столкнутся с тем, что разработчики попытались заблокировать запуск на джейлбрейкнутом девайсе либо выдают предупреждения при каждом запуске или даже во время работы приложения.
Один из простых способов обхода подобных предупреждений — использование специальных приложений (например, Liberty Lite), но это сработает только в случае простых механизмов обнаружения. Более сложные способы разберем в этой статье в разделе про инструменты динамической инструментализации.
Анализ трафика приложения
На предыдущих этапах мы уже настроили перехватывающий прокси, поэтому информацию об HTTP и HTTPS трафике сразу же сможем увидеть через Burp Suite:
С помощью анализа трафика мобильного приложения можно расширить поверхность атаки и найти больше входных точек. Иногда разработчики считают, что если мобильное приложение использует внутренний API, который не видят пользователи, то защита там может быть хуже, данные для аутентификации сохранены в коде приложения или аутентификация вовсе отсутствует.
SSL пиннинг. В качестве защиты перехвата HTTPS трафика в мобильных приложениях используется SSL пиннинг. В приложение добавляются заранее вычисленные пины — хэш-суммы от серверного сертификата или от отдельных его полей (например, SubjectPublicKeyInfo). Пины сохраняются в коде приложения. При обращениях к серверу приложение снова вычисляет пины сертификата и сравнивает со списком доверенных. Если пины не совпадают, значит сертификат подложный (например, как в случае с перехватывающим прокси) — соединение останавливается.
Для реализации SSL пиннинга существуют готовые решения:
-
TrustKit;
-
Alamofire;
-
NSURLSession — нужно писать самостоятельно свою реализацию защиты на основе данного API.
Разберем на примере TrustKit возможные варианты обхода SSL пиннинга. Например, конфигурация для TrustKit выглядит так:
let googleCom: [String: Any] = [
kTSKReportUris: ["https:///report_url"],
kTSKDisableDefaultReportUri: true,
kTSKEnforcePinning: true,
kTSKIncludeSubdomains: true,
kTSKPublicKeyHashes: [
"Z8geUnmtnmt4ehRyQAOJ4…",
"YZPgTZ+woNCCCIW3LH2…"
]
]
...
let trustKitConfig: [String: Any] = [
kTSKSwizzleNetworkDelegates: true,
kTSKPinnedDomains: [
"google.com": googleCom,
...
]
]
Параметры конфигурации передаются в метод initSharedInstanceWithConfiguration при запуске приложения и инициализируют SSL пиннинг. При попытке установить соединение TrustKit проверит, что хотя бы один из указанных пинов совпадает с пинами, подсчитанными для сертификатов в цепочке сертификатов сервера.
Способы обойти данную проверку:
-
Перехватить вызов метода initSharedInstanceWithConfiguration и выставить TKSEnforcePinning в 0.
-
Перехватить вызов verifyPublicKeyPin и заменить на функцию, которая всегда возвращает 0 (=TSKTrustEvaluationSuccess).
Реализовать этот обход можно как используя готовые инструменты (например, ssl-kill-switch2), так и с помощью инструментов динамической интрументизации.
WebView. Если приложение использует WebView, то при тестировании стоит обратить особое внимание на конфигурацию и значения параметров. UIWebView (старая версия) и WKWebView предназначены для встраивания содержимого веб-страниц прямо в приложение, поддерживая CSS и JS. Также поддерживают базовую логику навигации в веб (переход вперед/назад/гиперссылки и т.д.). Начиная с iOS 8.0 и OS X 10.10, используйте WKWebView для добавления веб-содержимого в ваше приложение и не используйте UIWebView.
У WKWebView есть флаги, которые могут быть для нас интересны:
-
JavaScriptEnabled — включено ли исполнение JS для данного WebView.
-
JavaScriptCanOpenWindowsAutomatically — логическое значение, которое указывает, может ли JavaScript открывать окна без взаимодействия с пользователем.
-
AllowFileAccessFromFileURLs (для WKPreferences, по умолчанию false) — включает JavaScript, работающий в контексте URL-адреса схемы “file://”, для доступа к содержимому из других URL-адресов схемы “file://”.
-
IsFraudulentWebsiteWarningEnabled — логическое значение, которое указывает, отображаются ли предупреждения о мошенническом содержимом: например, о вредоносных программах или попытках фишинга.
Для экспериментов или отладки своего приложения удобно использовать Web Inspector в Safari (для этого приложение должно быть собрано с возможностью отладки). Включив Web Inspector на девайсе, мы сможем подключиться к WebView и посмотреть, что происходит: как выглядит HTML, выполнить какой-то JavaScript и т.д.
Хранение данных на устройстве
Самый простой способ хранения данных на устройстве — NSUserDefaults. Это простое хранилище «ключ — значение». Там обычно хранится информация о настройках приложения, чтобы эти данные сохранялись между запусками. Хранилище NSUserDefaults нельзя использовать для хранения важной информации.
Безопасное хранение данных на iOS-девайсах должно быть реализовано с использованием Keychain. Это хранилище предназначено для хранения паролей, криптографических ключей, сертификатов и другой важной информации. Разработчику предоставляется API для работы с Keychain, при этом все важные операции вынесены в отдельную подсистему безопасности на уровне «железа» — Security Enclave.
У Keychain есть много параметров. При разработке приложения стоит внимательно подойти к тому, какие секреты с какими параметрами будут сохранены. Все параметры можно разделить на атрибуты доступности и параметры контроля доступа.
Атрибуты доступности указывают на то, когда данное значение может быть получено. Возможные модификаторы:
-
kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly
-
kSecAttrAccessibleWhenUnlockedThisDeviceOnly
-
kSecAttrAccessibleWhenUnlocked
-
kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly
-
kSecAttrAccessibleAfterFirstUnlock
-
kSecAttrAccessibleAlwaysThisDeviceOnly
-
kSecAttrAccessibleAlways
Суффиксы указывают на состояние девайса:
-
Always — данные доступны всегда;
-
WhenPasscodeSet — требует наличия пасскода на девайсе;
-
WhenUnlocked — данные доступны, когда устройство разблокировано;
-
AfterFirstUnlock — данные доступны после первой разблокировки девайса и до следующего перезапуска.
Суффикс ThisDeviceOnly указывает на то, что элементы не переносятся на новое устройство (например, после восстановления из резервной копии). У каждого из возможных параметров есть рекомендации на портале разработчика.
Флаги контроля доступа (ACL — access control flags, поддерживают «and» and «or»):
-
devicePasscode — для доступа к данным потребуется ввести пасскод;
-
biometryAny — для доступа к данным потребуется любая валидная биометрия;
-
biometryCurrentSet — biometryAny + если кто-то разблокирует девайс и добавит свой отпечаток пальца, то зайти в приложение уже не получится;
-
userPresence — либо пасскод, либо биометрия;
-
watch — для доступа к данным потребуются Apple Watch, подключенные к девайсу и находящиеся рядом с девайсом;
-
applicationPassword — приложение может задать любой пароль для доступа к данным;
-
privateKeyUsage — требуется приватный ключ, который будет использоваться для подписи блока данных или проверки подписанного блока.
Анализ значений в Keychain для приложений может быть реализован с использованием инструментов:
-
Objection -> ios keychain dump
-
Keychain-Dumper
-
keychaineditor
Попробуем сдампить Keychain для тестового приложения:
Локальная аутентификация
При установке на девайс приложения сначала просят пройти полноценную аутентификацию: ввести имя пользователя, пароль, подтвердить номер по SMS. Дальше пользователь может поставить четырехзначный пароль и использовать биометрию. Такую аутентификацию на устройстве будем называть локальной.
Есть разные варианты локальной аутентификации:
-
Пасскод (обычно 4-6 цифр)
-
Пароль
-
Биометрия (Touch ID, Face ID)
В случае реализации локальной аутентификации с использованием пасскода или пароля данные сохраняются в Keychain, а пользователь должен так или иначе разблокировать Keychain и получить доступ к данным. Также стоит использовать Keychain для других связанных данных: например, для счетчика количества неудачных попыток ввода пароля или пасскода. Советы по реализации локальной аутентификации с использованием биометрии можно посмотреть тут: Logging a User into Your App with Face ID or Touch ID.
При тестировании локальной аутентификации стоит обратить внимание на то, где хранятся пасскод и пароль, какие флаги и атрибуты выставлены для значений в Keychain, как реализован механизм подсчета попыток входа, можно ли обойти аутентификацию, используя кастомные схемы приложения и т.д.
Динамическая инструментализация (Dynamic Insrtumentation)
Вот основные инструменты динамической инструментализации:
-
Frida — набор динамических инструментов для разработчиков, реверс-инженеров и исследователей безопасности.
-
Objection — набор инструментов для мобильных исследований во время выполнения на базе Frida. Создан для того, чтобы помочь оценить уровень безопасности мобильных приложений без необходимости джейлбрейка.
-
Cycript — позволяет исследовать и изменять запущенные приложения на iOS или OS X через интерактивную консоль, используя гибрид синтаксиса Objective-C ++ и JavaScript.
Эти инструменты помогают разбирать приложения в режиме выполнения: смотреть память приложения, используемые ресурсы, локальные хранилища, базы данных, Keychain, тестировать джейлбрейк и SSL пиннинг.
Посмотрим на пример простого обхода джейлбрейка с помощью Frida. Мы уже разобрали реализацию одного из вариантов обнаружения джейлбрейка в приложении DVIA-v2, но на самом деле для его обхода нам достаточно информации из class-dump. В приложении есть класс JailbreakDetection и метод isJailbroken, который возвращает значение типа boolean.
Попробуем заменить возвращаемое значение с помощью кода для Frida:
if (ObjC.available) {
var hook = ObjC.classes.JailbreakDetection["isJailbroken"];
console.log("registering hook");
Interceptor.attach(hook.implementation, {
onLeave: function(retval) {
console.log("replacing return value");
retval.replace(ptr("0x0"));
}
});
}
Cкрипт проверяет доступность API для Objective-C (ObjC.available), ищет метод isJailbroken класса JailbreakDetection и регистрирует его для перехвата. На выходе из метода заменяем возвращаемое значение на 0 (false), что в данном случае будет означать то, что девайс не джейлбрейкнут.
Такие простые вещи обходятся любым готовым инструментом. Если готовый инструмент не подходит, то придется написать свой скрипт.
Например, популярный вопрос на StackOverflow — как распознать джейлбрейк. Можно предположить, что этот или аналогичный код встречается во многих приложениях. В такой ситуации мы просто пишем больше своего кода:
const pathes = [
"/Applications/Cydia.app",
"/Library/MobileSubstrate/MobileSubstrate.dylib",
"/bin/bash",
"/usr/sbin/sshd",
"/etc/apt",
"/private/var/lib/apt/"
];
var fileExistsAtPathHook = ObjC.classes.NSFileManager["- fileExistsAtPath:"];
Interceptor.attach(fileExistsAtPathHook.implementation, {
onEnter: function(args) {
this.bypass = false;
var path = ObjC.Object(args[2]).toString();
for (var i = 0; i < pathes.length; i++) {
if (path.includes(pathes[i])) {
this.bypass = true;
console.log("fileExistsAtPath bypass: " + path);
break;
}
};
},
onLeave: function(retval) {
if (this.bypass) {
console.log("fileExistsAtPath bypassed");
retval.replace(ptr("0x0"));
}
}
});
var canOpenURLHook = ObjC.classes.UIApplication["- canOpenURL:"];
Interceptor.attach(canOpenURLHook.implementation, {
onEnter: function(args) {
this.bypass = false;
var url = ObjC.Object(args[2]).toString();
if (url.includes("cydia")) {
this.bypass = true;
console.log("canOpenURLHook bypass: " + url);
}
},
onLeave: function(retval) {
if (this.bypass) {
console.log("canOpenURLHook bypassed");
retval.replace(ptr("0x0"));
}
}
});
Используя такой подход, можно обойти более продвинутый джейлбрейк, чтобы дальше заниматься исследованием приложения.
Также на джейбрейкнутом девайсе можно попробовать обойти Touch ID с использованием Objection и команды “ios ui biometrics_bypass”.
Это пример использования готового скрипта, но написать такой код самостоятельно тоже можно: мы просто запустили похожий скрипт, используя инструмент с вшитым набором скриптов. Подкладываем неправильный отпечаток и перехватываем его. Операционная система отвечает, что доступа нет, но complete hook заканчивается, и нам удается пройти аутентификацию в приложении. Можно ознакомиться с кодом приложения тут.
Теперь рассмотрим Cycript. Этот инструмент по функциональности похож на предыдущие, но также может помочь связать элементы UI с кодом.
Допустим, что в приложении есть кнопка, и нам нужно понять, какой метод в коде вызывается при ее нажатии. Мы подключаемся к приложению, смотрим, какие кнопки есть в этом UI, находим его по какому-то лейблу и смотрим, какой у него целевой объект (target):
cy# var buttons = choose(UIButton)
cy# buttons[8].titleLabel.text
@"Jailbreak Test 1"
cy# buttons[8].allTargets
[NSSet setWithArray:@[#"<DVIA_v2.JailbreakDetectionViewController: 0x1058308f0>"]]]
cy# buttons[8].allControlEvents
64
cy# target=[buttons[8].allTargets anyObject]
#"<DVIA_v2.JailbreakDetectionViewController: 0x1058308f0>"
cy# [buttons[0] actionsForTarget:target forControlEvent:UIControlEventTouchUpInside]
@["jailbreakTest1Tapped:"]
Рассмотрим подробнее, что же тут происходит:
-
Выбираем все объекты класса UIButton.
-
Находим нужную нам кнопку по надписи на ней (см. titleLabel).
-
Находим, что является целевым объектом для действия по данной кнопке (см. allTargets). Получаем класс JailbreakDetectionViewController.
-
Смотрим, какие типы действий может обрабатывать данная кнопка (см. allControlEvents). Выясняем, что кнопка умеет обрабатывать нажатие, UIControlEventTouchUpInside (UIControlEventTouchUpInside = 1 << 6 = 64).
-
Вызываем метод actionsForTarget с известными нам данными и получаем имя метода: jailbreakTest1Tapped.
При нажатии на кнопку “Jailbreak Test 1” происходит вызов метода jailbreakTest1Tapped класса JailbreakDetectionViewController. Так мы можем соединить элементы интерфейса с соответствующим кодом и заниматься реверсом этих частей приложения.
Полезные ссылки
В статье мы поверхностно рассмотрели инструменты и подходы, используемые при анализе мобильных приложений. Материал основан на подходах и рекомендация из OWASP Mobile Security Testing Guide — это подробное руководство по тестированию безопасности мобильных приложений под iOS и Android.
Практические примеры я взял из Damn Vulnerable iOS App (DVIA-v2) — одного из тестовых приложений, на котором можно оттачивать навыки и экспериментировать.
Также для закрепления материала из статьи советую посмотреть GimmeFlag — iOS приложение с простыми CTF-like заданиями на статический анализ. Для решения заданий достаточно минимального набора инструментов, наличие iOS девайса (как и Mac OS) не требуется.
Буду рад ответить на вопросы и комментарии к статье!
Searching for anti-piracy systems many people answer to check the content of the file iTunesMetadata.plist. This file should be present if it was purchased on iTunes. I’m able to locate it but cannot open it. It seems in binary format.
Trying to open it with Windows doesn’t work (unzip too nothing) but on my Mac it works (Apple binary property list). Seems in a binary format. My questions:
-
How can I open it in xCode and read the content (using Xcode 4.2)?
-
It’s allowed to read the content or would this operation not pass the validation process by Apple?
I know, there are many checks we could implement but it’s only a better of time they would be by-passed. BTW it’s at least a good xCode exercise for me
Thank’s a lot for your help!
Simon
asked Mar 31, 2012 at 12:24
3
plist type files can be read on Windows using ‘plist_editor’ software.
answered Feb 1, 2016 at 5:23