Пентестинг приложений iPhone – часть 5

Пентестинг приложений iPhone – часть 5

Рассматривается динамический анализ iOS-приложений

Автор: satishb3

В первой статье данной серии мы обсуждали анализ трафика приложений iPhone. Вторая, третья и четвертая части были посвящены подробному анализу небезопасных мест хранения данных на iPhone. В данной статье мы рассмотрим динамический анализ приложений iOS (анализ во время выполнения). Динамический анализ позволяет атакующему манипулировать поведением приложения во время его выполнения, чтобы обойти механизмы безопасности и извлечь из памяти конфиденциальные данные. Перед тем, как перейти собственно к анализу, нам сначала нужно рассмотреть архитектуру приложения iOS и защитные механизмы, действующие во время его выполнения.

Архитектура приложений iOS

Приложение iOS представляет собой zip-архив с расширением .ipa. Архив содержит исполняемый двоичный файл и файл iTunesArtwork, который используется iTunes для управления приложением. Ниже показана типичная структура приложения iOS.

Папка в директории Payload, имя которой заканчивается на .app, содержит двоичный файл приложения, все ресурсы приложения вроде изображений и аудиозаписей, профиль, определяющий разрешения приложения, и подпись кода.

Двоичный файл приложения iOS скомпилирован под архитектуру ARM и использует файловый формат Mach-O (mach object). Данный файловый формат состоит из трех основных разделов: заголовка, загрузочных команд и сегментов/секций. Ниже показана структура файлового формата Mach-O.

Структура Mach-O файлов iOS-приложения может быть просмотрена на подвергшемся джейлбрейку устройстве с помощью утилиты otool. Otool доступен из пакета Darwin CC Tools в Cydia.

Заголовок

Раздел позволяет идентифицировать файл Mach-O и содержит основную информацию о типе файла вроде целевой архитектуры и флагов, влияющих на интерпретацию остальной части файла. Чтобы просмотреть Mach-O заголовок приложения iOS, подключитесь к iPhone через SSH и выполните команду:

otool –h ApplicationBinary

Вот заголовок Mach-O приложения Facebook для iOS.

Значения cputype и subtype в заголовке Mach-O определяют целевую архитектуру приложения. В показанном примере видно, что приложение Facebook имеет архитектуру ARM7.

ARM7s (iPhone 5) = cputype 12/ subtype 11
ARM7 (iPhone 4 & 4S) = cputype 12/ subtype 9
ARM6 (iPhone 3GS) = cputype 12/ subtype 6

Приложения, которые скомпилированы для нескольких архитектур, содержат более одного файла Mach-O. Соответствующие двоичные файлы также называются универсальными или толстыми. Чтобы посмотреть Mach-O заголовок универсального двоичного файла, выполните в SSH-терминале следующую команду:

otool –arch all -h ApplicationBinary

На рисунке выше видно, что приложение CardInfo скомпилировано для процессоров с архитектурами ARM7 и ARM7s.

Загрузочные команды

Загрузочные команды определяют то, как сегменты файла располагаются в памяти, а также линковочные характеристики файла (связи с библиотеками). Они содержат первоначальную разметку файла в виртуальной памяти, расположение таблицы символов, состояние выполнения главного потока программы и информацию о подключаемых разделяемых библиотеках. Загрузочные команды (LC_ENCRYPTION_INFO) также определяют, зашифрован ли файл. Чтобы просмотреть загрузочные команды, выполните в SSH-терминале следующую строку:

otool –Vl ApplicationBinary

Данные:

Файл Mach-O содержит собственно данные приложения в одном или нескольких сегментах. В каждом сегменте может быть некоторое количество секций, в том числе, нулевое. Каждая секция сегмента содержит код или данные определенного типа. Точное количество сегментов, секций и их расположение в памяти описывается в разделе загрузочных команд.

Механизмы защиты приложений iOS во время выполнения

Платформа iOS предоставляет множество защитных механизмов, например, ASLR, защита от повреждения стека и ARC. Понимание этих механизмов защиты важно для выполнения реверсирования и анализа iOS-приложений.

Рандомизация адресного пространства (ASLR)

ASLR – важный метод противодействия эксплоитам, появившийся в iOS 4.3. ASLR значительно усложняет удаленную эксплуатацию уязвимостей к повреждению памяти за счет рандомизации размещения объектов приложения в памяти. По умолчанию приложения iOS используют ограниченную ASLR, которая рандомизирует размещение только части объектов в памяти. Чтобы задействовать ASLR максимально, приложение должно быть скомпилировано с флагом -fPIE -pie (в XCode этому флагу соответствует опция "Генерировать зависимый от расположения код"). В последнем выпуске XCode этот флаг выбран по умолчанию. На рисунке ниже показано состояние различных разделов памяти при частичном и полном применении ASLR.

Чтобы определить, было ли приложение скомпилировано с флагом PIE, подключитесь к iPhone по SSH и выполните команду:

otool –Vh ApplicaitonBinary

На рисунке выше в конце вывода мы видим слово PIE. Это означает, что приложение Facebook было скомпилировано с данным флагом.

Защита от повреждения стека

Защита от повреждения стека – это механизм борьбы с эксплоитами, который защищает от атак переполнения стека путем помещения перед локальными переменными некоторого случайного, но известного значения, называемого стековой канарейкой (по аналогии с живыми канарейками, которых брали с собой шахтеры, чтобы проверить отсутствие взрывоопасных газов). При возврате из функции проверяется значение стековой канарейки. В случае переполнения канарейка будет повреждена, и, узнав об этом, приложение сможет защититься от переполнения. Чтобы включить защиту от повреждения стека, приложение нужно скомпилировать с флагом –fstack-protector-all.

Приложения iOS, которые используют стековых канареек, содержат в двоичном коде строки _stack_chk_fail и _stack_chk_guard. Чтобы определить, использует ли приложение защиту от повреждения стека, подключитесь к iPhone по SSH и выполните следующую команду:

otool –I –v ApplicationBinary | grep stack

Данный снимок экрана свидетельствует о том, что приложение Facebook использует защиту от повреждения стека.

Автоматический подсчет ссылок (ARC)

ARC – еще один механизм для борьбы с эксплоитами, введенный в iOS 5. Он защищает приложения от уязвимостей к повреждению памяти путем перекладывания ответственности за управление памятью с разработчика на компилятор. ARC можно включить, установив значение "yes" для опции "Objective-C Automatic Reference Counting". По умолчанию данный механизм включен.

Приложения iOS с включенным ARC содержат в двоичном файле строку _objc_release. Чтобы определить, использует ли приложение ARC, выполните в SSH-терминале следующую команду:

otool –I –v ApplicationBinary | grep _objc_release

Показанный выше снимок экрана говорит о том, что приложение Facebook скомпилировано с поддержкой ARC.

Механизмы защиты во время выполнения создают дополнительный слой безопасности приложения. Поэтому хорошей практикой является явное включение этих механизмов при компиляции приложения, а в ходе тестирования на проникновение стоит проверить их наличие.

Реверсирование приложений iOS

Чаще всего iOS-приложения пишутся на языке Objective-C. Objective-C – это динамический язык, основанный на принципах передачи сообщений между объектами. Поскольку язык является динамическим, все классы, методы и прочие компоненты хранятся внутри двоичного файла. Данная информация может быть извлечена с помощью утилиты class-dump-z, созданной kennytm.

Установка class-dump-z

  1. На подвергшемся джейлбрейку устройстве установите из Cydia утилиты wget и unzip.
  2. Подключитесь к iPhone по SSH и выполните указанные ниже команды

    wget -U Mozilla/5.0 http://www.securitylearn.net/wp-content/uploads/tools/iOS/class-dump-z.zip
    unzip class-dump-z.zip
    mv class-dump-z /usr/bin

  3. Чтобы выгрузить из приложения iOS информацию о классах, перейдите в поддиректорию приложения, заканчивающуюся на .app, и запустите следующую команду:

    class-dump-z ApplicationBinary

На рисунке ниже показана выгруженная информация о классах приложения Gmail для iOS. Здесь не содержится каких-либо полезных данных, поскольку двоичный файл зашифрован. Приложения, загруженные из AppStore, шифруются с помощью FairPlay DRM для защиты от пиратства.

Чтобы выяснить, является ли приложение зашифрованным, запустите в SSH-терминале следующие команды:

otool –l ApplicationBinary | grep crypt

cryptid 1 говорит о том, что приложение зашифровано. Для незашифрованных приложений значение cryptid равно 0.

Часто первым шагом при реверсировании iOS-приложений является снятие шифрования. Расшифровка приложения позволяет атакующему лучше понять, как работает приложение, внутреннюю структуру его классов, и подготовить двоичный файл для реверсирования. Изначально незашифрованными являются приложения, которые используют модель распространения in-house или являются самоподписанными.

Расшифровка приложений iOS

Когда iOS-приложение запускается, загрузчик расшифровывает его и загружает в память. Данный факт лег в основу хорошо отлаженного метода, позволяющего снимать с приложения защиту от копирования FairPlay. Процесс расшифровки включает в себя следующие шаги:

  1. Нахождение смещения и размера зашифрованных данных внутри двоичного файл приложения.
  2. Нахождение адреса, по которому приложение загружается в память (если оно было скомпилировано с флагом PIE, то этот адрес будет меняться при каждой загрузке).
  3. Выгрузка расшифрованной части приложения из памяти с помощью отладчика (например, gdb).
  4. Замещение зашифрованных данных приложения выгруженными расшифрованными данными.
  5. Изменение значение cryptid на 0.

Весь данный процесс можно автоматизировать с помощью приложений из Cydia, которые называются Clutch и Rasticrac.

Расшифровка iOS-приложения Gmail с помощью Clutch

  1. На подвергшемся джейлбрейку устройстве зайдите в Cydia и добавьте репозиторий http://AppAddict.org/repo, перейдя к пункту Manage->Sources.
  2. Скачайте из Cydia ClutchPatched и IPA Installer.
  3. Подключитесь к iPhone по SSH и наберите команду 'Clutch'. Она перечислит все установленные на iPhone приложения.
  4. Если теперь указать Clutch определенное приложение, он расшифрует его и сохранит расшифрованные данные в файле с расширением ipa внутри папки /var/root/Documents/Cracked/. На рисунке ниже показано, что Clutch взломал приложение Gmail и сохранил расшифрованные данные в файле /var/root/Documents/Cracked/Gmail-v2.2.0.8921.ipa.
  5. Данный файл ipa можно установить на iPhone прямо из SSH-терминала, используя следующую команду:

    installipa –c [iPAPath]

На рисунке ниже показаны выгруженные данные о классах расшифрованного приложения Gmail.

Полный дамп классов расшифрованного приложения позволяет узнать список классов и их методов, что позволяет глубже взглянуть на то, как устроено приложение. Как только дамп классов получен, мы можем искать интересующие нас классы, методы и проводить динамический анализ (анализ во время выполнения).

Динамический анализ через Cycript

Динамический анализ включает в себя реверсирование приложения и анализ его потока управления для обхода блокировок, аутентификации, доступа к конфиденциальной информации в памяти, нарушения логических проверок и доступа к закрытым областям приложения. Objective-C – рефлективный язык, он позволяет модификацию своего поведения во время выполнения. На iPhone поведение приложения во время выполнения можно легко менять с помощью CyCript. CyCript можно найти среди пакетов Cydia.

Cycript – это язык программирования, сочетающий в себе Objective-C и Javascript. Cycript позволяет вмешиваться в процесс ОС и дает доступ ко всем классам, полям и методам выполняющегося приложения.

Перед тем, как приступить к динамическому анализу, необходимо изучить поток выполнения iOS-приложения.

Objective-C по сути является надстройкой над C, поэтому его выполнение начинается с функции main(). Фактически, main() вызывается, когда пользователь нажимает на значок приложения. Главная функция в свою очередь вызывает метод UIApplicationMain. Данный метод инициализирует объект UIApplication, отображает графический интерфейс (окна, представления), создает делегат приложения и запускает цикл обработки сообщений. Делегат приложения отслеживает высокоуровневые действия/события в приложении. С помощью Cycript мы можем подключиться к запущенному процессу и получить доступ к его объекту UIApplication. UIApplication – это синглтон, который представляет приложение и действует как центр управления. Так что, получение доступа к данному объекту – это получение доступа к внутренней структуре приложения.

Возможности Cycript показаны в следующих далее примерах. В целях демонстрации я использовал старую версию приложения Photo Vault. Перед внедрением в процесс с помощью cycript мы сначала выгрузим информацию о классах приложения через class-dump-z.

Доступ к полям объектов через Cycript

Приложение Photo Vault сохраняет конфиденциальность фотографий за счет ограничения доступа по паролю. Когда мы запускаем приложение в первый раз, оно просит пользователя установить пароль. В последующие разы для получения доступа к защищенным фотографиям пользователю нужно ввести правильный пароль. Ниже описаны шаги, как узнать пароль через динамический анализ посредством Cycript.

  1. Запустим приложение Photo Vault. Оно запросит пароль.
  2. Подключимся к iPhone по SSH и получим информацию о процессе с помощью команды ps ax.
  3. Внедримся в процесс, используя команду cycript –p [PID].
    Замечание: Если вы знаете имя приложения, вы можете также внедриться в его процесс, используя команду cycript –p [ApplicationName].
  4. В командной строке cycript мы можем получить доступ к экземпляру приложения либо путем вызова метода [UIApplication sharedApplication], либо используя переменную UIApp.
  5. Чтобы найти делегат приложения, выполним команду UIApp.delegate.
  6. Найдем в выгруженной информации о классах делегат приложения PhotoVaultAppDelegate и рассмотрим секцию @interface (также полезной будет секция @protocol). Секция @interface содержит объявление всех методов и свойств, а @protocol – группу связанных методов, которые объект может вызвать через свой делегат.
  7. В делегате приложения содержится интересующее нас свойство – strPass. Запросим значение, хранимое в этом свойстве, набрав в командной строке UIApp.delegate.strPass.
  8. Ура! Мы получили пароль к фотографиям. Можем ввести его в приложении и получить доступ к защищенным фотографиям пользователя.

Cycript также позволяет модифицировать значения полей, вызывать методы и перезаписывать существующие методы прямо во время выполнения программы.

Это пятая часть серии статей о пентестинге приложений iPhone. В шестой части будет рассмотрен динамический анализ приложений iOS с помощью gdb и подмена методов с помощью Cycript.

Ссылки

  1. Debunking NSLog Misconceptions http://oleb.net/blog/2011/06/app-launch-sequence-ios/
  2. Hacking and Securing iOS Applications by Jonathan Zdziarski
  3. "Apple iOS 4 Security Evaulation" by Dino Dai Zovi

Где кванты и ИИ становятся искусством?

На перекрестке науки и фантазии — наш канал

Подписаться