Статья Пентест iOS приложений: от jailbreak до анализа бинарников и обхода биометрии

Восковая копия лицевой панели смартфона, разрезанная пополам по линии сенсора, лежит на чёрном антистатическом коврике. Жёсткий диагональный свет выхватывает излом с пурпурно-голубым хроматическим...


На пентесте iOS-приложения финтех-сервиса в прошлом квартале мы вытащили auth-токены из Keychain одной командой через objection - разработчики выставили [URL='https://developer.apple.com/documentation/security/ksecattraccessiblealways']kSecAttrAccessibleAlways[/URL], и токены читались на заблокированном устройстве. Обход Face ID занял один Frida-скрипт на шесть строк - Шесть! Строк! Ребята полагались на платформенную безопасность iOS и не закладывали сценарий джейлбрейкнутого устройства в модель угроз - а зря. Эта статья - пошаговое руководство по пентесту iOS приложений: от подготовки устройства через jailbreak до извлечения секретов из бинарников и обхода биометрической аутентификации. Каждый шаг привязан к MITRE ATT&CK и OWASP MASVS, с конкретными командами и объяснением, почему они работают.

Карта атаки: где iOS pentest вписывается в kill chain​

Пентест iOS приложений - цепочка техник, где каждый шаг зависит от результатов предыдущего. Без jailbreak нет runtime-анализа. Без расшифровки IPA нет осмысленного реверса. Вот как это ложится на MITRE ATT&CK:

Этап пентестаMITRE ATT&CKЧто делаем
Jailbreak устройстваExploitation for Privilege Escalation (T1068)Root-доступ через checkra1n / palera1n
Расшифровка IPADeobfuscate/Decode Files or Information (T1140)frida-ios-dump для дампа декриптованного бинарника
Анализ бинарникаObfuscated Files or Information (T1027)Проверка PIE, ARC, stack canaries, реверс в Hopper/Ghidra
Дамп KeychainKeychain (T1555.001, credential-access)Извлечение токенов, паролей, ключей через objection
Анализ файловой системыData from Local System (T1005, collection)Поиск секретов в plist, SQLite, NSUserDefaults
Обход биометрииMulti-Factor Authentication Interception (T1111)Патч LAContext через Frida
Обход jailbreak detectionСвязано с MASVS-RESILIENCERuntime-хуки для обхода проверок среды

Контекст применения, эта цепочка работает при внутреннем пентесте мобильного приложения (grey/white box, есть доступ к IPA или App Store аккаунту). При black box добавляется этап получения IPA - через iTunes-бэкап или перехват загрузки.

Jailbreak для пентеста iOS: выбор инструмента​

1780124566722.webp

Требования к окружению​

  • ОС хоста: macOS (рекомендуется) или GNU\Linux. Windows не поддерживает работу с checkra1n и palera1n
  • Устройство: физический iPhone или iPad. iOS-симулятор Xcode бесполезен - бинарники компилируются под x86, а не ARM, App Store приложения на нём не запускаются. Согласно OWASP MASTG, единственный публичный iOS-эмулятор - Corellium
  • Кабель: USB-A to Lightning. С USB-C кабелем ввод в DFU-режим часто зависает - берите переходник USB-C на USB-A, сэкономите себе нервы
  • На хосте: pip install frida-tools objection. Версии Frida на хосте и устройстве должны совпадать - несовпадение ломает взаимодействие. Проверено на собственных граблях: потратил полчаса на дебаг, пока не понял, что на устройстве 16.1.4, а на хосте 16.2.1

checkra1n vs palera1n: decision tree​

Выбор jailbreak определяется чипом устройства и версией iOS:

УсловиеИнструментТипОсобенности
Чип A5–A11, iOS до 14.xcheckra1nSemi-tetheredАппаратный эксплойт checkm8 в BootROM - Apple не может закрыть софтверным обновлением
Чип A8–A11, iOS 15–16.xpalera1nSemi-tetheredТоже на базе checkm8, поддержка iOS 15–16
Чип A12+ (iPhone XS и новее), iOS 17+Нет публичного jailbreak-Вариант: Corellium или ждать публичного эксплойта

Согласно OWASP MASTG, checkm8 затрагивает BootROM всех процессоров до A12 - аппаратная уязвимость, которая не закрывается обновлениями iOS. Для тестирования безопасности iOS это значит: iPhone 6s через iPhone X - надёжные рабочие лошадки, которые будут джейлбрейкаться при любой версии iOS.

Установка palera1n (для iOS 15–16, с официального сайта и подтверждено RU-источниками):
Bash:
sudo /bin/sh -c "$(curl -fsSL https://static.palera.in/scripts/install.sh)"
palera1n
После jailbreak на устройстве появляется приложение palera1n -> ставим Sileo (менеджер пакетов, аналог Cydia) -> добавляем репозиторий Frida -> ставим frida-server. Версию frida-server подбираем строго под версию frida-tools на хосте!

Критический нюанс: semi-tethered jailbreak слетает при перезагрузке. Для повторной активации нужно подключить устройство к Mac и запустить palera1n заново. После jailbreak SSH-доступ со стандартными credentials: root / alpine - менять на тестовом устройстве не обязательно, но в публичные Wi-Fi сети с таким паролем лезть нельзя.

Статический анализ IPA: что скрывает бинарник​

Статический анализ - fingerprinting приложения до его запуска. Извлекаем бинарник, проверяем защиты, ищем захардкоженные секреты. Это этап T1027/T1140 по MITRE ATT&CK.

Извлечение и расшифровка IPA​

App Store приложения зашифрованы FairPlay DRM. Без расшифровки дизассемблирование покажет мусор. Для расшифровки качаем frida-ios-dump(GitHub - AloneMonkey/frida-ios-dump: pull decrypted ipa from jailbreak device) - Python-скрипт, который через Frida дампит расшифрованный бинарник из памяти работающего приложения: python dump.py com.example.app. Получаем готовый IPA.

IPA - ZIP-архив. Распаковываем: unzip target.ipa -d output/. Структура:
  • Payload/App.app/AppBinary - основной бинарник ARM64
  • Info.plist - конфигурация: URL-схемы, разрешения, адреса бэкендов
  • Frameworks/ - встроенные фреймворки, часто со своими уязвимостями
Файловые пути на устройстве (по данным Bugcrowd): бандлы App Store приложений лежат в /var/containers/Bundle/Application/<UID>/, данные - в /var/mobile/Containers/Data/Application/<UID>/, shared data - в /var/mobile/Containers/Shared/AppGroup/<UID>/. UID генерируется при установке и меняется при переустановке - для поиска нужного приложения сортируйте по дате создания.

Анализ бинарников iOS: проверка защит и реверс-инжиниринг​

Перед глубоким реверсом проверяем бинарные защиты. Занимает минуту с otool (стандартная утилита Xcode Command Line Tools):
Bash:
otool -hv AppBinary | grep PIE        # ASLR: Position Independent Executable
otool -Iv AppBinary | grep stack_chk  # Stack canaries
otool -l AppBinary | grep cryptid     # cryptid 0 = расшифровано
Что говорят результаты: PIE - бинарник поддерживает ASLR, если флага нет - адреса функций предсказуемы, и это подарок для эксплуатации; stack canaries (__stack_chk_fail) - защита от buffer overflow, отсутствие - повод копнуть глубже; cryptid 0 - frida-ios-dump отработал, cryptid 1 - бинарник ещё зашифрован.

Для извлечения Objective-C интерфейсов: class-dump -H AppBinary -o headers/ генерирует заголовочные файлы всех классов. Имена методов часто напрямую выдают логику: isJailbroken, validatePurchase, checkBiometricAuth. Для Swift-бинарников class-dump менее эффективен - Swift-символы обфусцированы по умолчанию, тут нужен дизассемблер.

Инструменты для глубокого reverse engineering iOS:
  • Hopper Disassembler (~$100, macOS) - нативная поддержка Objective-C и Swift, удобная навигация по классам. Мой основной инструмент для ios pentest работы (активно поддерживается, версия 5.x)
  • Ghidra (бесплатно, NSA) - мощный декомпилятор ARM64. По данным Corellium, Ghidra восстанавливает логику обфусцированного кода через mapping control flow и реверс Objective-C class structures (активно поддерживается, версия 11.x). Бесплатный - и очень хорош
  • R2Frida - связка radare2 и Frida. Одновременно читаем дизассемблированный код и трейсим вызовы функций на живом устройстве. Штука специфическая, но когда нужно разобраться в обфусцированной логике на лету - незаменима
Что искать в дизассемблированном коде? - Строковые литералы с API-ключами, токенами и URL бэкендов; имена методов, связанные с jailbreak-проверками (canOpenURL: c cydia://); криптографические константы - слабые алгоритмы, хардкод IV и ключей; логику проверки подписки на клиенте вместо сервера.

Динамический анализ iOS приложений: Frida и objection в деле​

Динамический анализ - работа с запущенным приложением: перехват трафика, дамп хранилищ, runtime manipulation. Ключевая часть mobile pentest iOS.

SSL Pinning bypass​

1780124725664.webp

Без обхода SSL Pinning мы не увидим трафик приложения. Последовательность:
  1. В Burp Suite Pro: Proxy → Options → Bind to address: All interfaces - открываем прокси в локальной сети
  2. На устройстве: Settings → Wi-Fi → HTTP Proxy → Manual → IP_хоста : порт_Burp
  3. Установка сертификата: в Safari идём по http://burp, скачиваем CA Certificate, доверяем в Settings → General → VPN & Device Management
  4. Проверяем связь: frida-ps -Uia на хосте - должен показать список процессов на устройстве
  5. Подключаемся к приложению: objection -g com.target.app explore
  6. В консоли objection: ios sslpinning disable
После этого весь трафик виден в Burp Suite. Приложение работает штатно, но сертификат бэкенда больше не валидируется на стороне клиента.

Альтернатива - tweak SSL Kill Switch 2 через Sileo: отключает pinning на системном уровне для всех приложений, не требует запуска objection каждый раз. Но менее контролируемый: нельзя включать/отключать для конкретного приложения.

По классификации OWASP MASVS-NETWORK, certificate pinning - обязательное требование. На самом деле, примерно половина приложений, попадавших ко мне на тестирование безопасности iOS, либо не реализуют его, либо проверяют только leaf-сертификат и ломаются при подмене intermediate. Грустная статистика.

Дамп Keychain и анализ хранилища данных​

Keychain - рекомендованное Apple хранилище для чувствительных данных. Но как оно всегда и бывает рекомендация и реализация - разные вещи. В консоли objection: ios keychain dump - выводит все доступные элементы с атрибутами доступности.

Что искать (по MASVS-STORAGE):
  • kSecAttrAccessibleAlways - данные доступны даже на заблокированном устройстве. Самая частая ошибка в финтех-приложениях
  • Пароли и токены в открытом виде - без дополнительного шифрования поверх Keychain
  • Элементы без привязки к биометрии - если разработчик не задал kSecAccessControlBiometryAny, данные читаются без аутентификации пользователя
Помимо Keychain проверяем: NSUserDefaults (ios nsuserdefaults get в objection - часто тут лежат feature flags, а иногда и токены), SQLite базы в директории данных приложения (незашифрованные), plist-файлы с кэшем и конфигурацией. Всё это - T1005 (Data from Local System) и T1555.001 (Keychain) по MITRE ATT&CK.

Обход биометрии iOS: патчим LAContext через Frida​

Touch ID и Face ID используют фреймворк LocalAuthentication - метод LAContext.evaluatePolicy:localizedReason:reply:. Метод принимает reply block с двумя аргументами: success (Bool) и error (NSError?). Если success == true - пользователь аутентифицирован.

Атака:
📚 Часть контента скрыта. Этот материал доступен участникам сообщества с рангом One Level или выше
Получить доступ просто — достаточно зарегистрироваться и проявить активность на форуме
Скрипт перехватывает вызов evaluatePolicy, подменяет callback и вызывает оригинал с result = 1. Приложение считает, что биометрия пройдена. По MITRE ATT&CK - Multi-Factor Authentication Interception (T1111).

Где обход биометрии iOS не работает​

РеализацияОбходится FridaПочему
LAContext.evaluatePolicy (UI-проверка)ДаЛогика целиком в userland, патчится хуком
Keychain + kSecAccessControlBiometryAnyНетВалидация в Secure Enclave, Frida не имеет доступа к TEE
CryptoKit + LAContext bindingНетКлюч разблокируется только после аппаратной биометрии

Большинство приложений используют первый вариант - чистый LAContext без привязки к Keychain. Проверка «прошёл ли пользователь биометрию» сводится к boolean в userland. Архитектурная ошибка, которую я вижу раз за разом: любая проверка, результат которой - true/false в клиентском коде - обходится runtime-хуком - всегда.

Jailbreak detection и его обход​

1780124833604.webp

MASVS-RESILIENCE требует от приложений проверять целостность среды. Типичные методы: проверка файлов (/Applications/Cydia.app, /usr/sbin/sshd, /etc/apt), URL-схемы (cydia:// через canOpenURL:), попытка записи вне sandbox, проверка dyld на инъецированные библиотеки, сканирование порта 27042 (дефолтный порт frida-server).

Метод обходаПодходКогда использоватьОграничения
ios jailbreak disable (objection)Runtime-хуки через FridaПервый шаг, работает для большинства приложенийРаботает пока активна сессия, слетает при рестарте
Liberty LiteСистемный tweakПерсистентный обход без ручных действийДавно не обновлялся, конфликтует с другими tweaks
A-BypassСовременный tweakКогда Liberty Lite не справляетсяПоддержка ограничена конкретными версиями iOS
Кастомный Frida-скриптТочечные хуки конкретных проверокНестандартные проверки (socket-based, dyld-based)Требует реверса логики детекта в конкретном приложении

По данным Corellium, одна из техник обхода port-based detection - запуск frida-server на нестандартном порту: frida-server -l 0.0.0.0:1337. Приложение проверяет 27042 - а frida-server слушает на другом. Примитивно, но работает.

Мой подход на практике: начинаю с ios jailbreak disable в objection. Если приложение продолжает детектить jailbreak - через class-dump ищу методы с характерными именами (isJailbroken, detectJailbreak), потом пишу точечный Frida-скрипт для их патча. Тот же подход работает для anti-debugging: если приложение вызывает приватный API ptrace с PT_DENY_ATTACH, это видно в Hopper и патчится аналогично.

Большинство iOS-приложений, которые попадают на пентест, реализуют один-два пункта из OWASP MASVS-RESILIENCE. Jailbreak detection есть - но обходится objection за секунду. SSL Pinning есть - но только на leaf-сертификат. Биометрия есть - но через LAContext без привязки к Keychain.

Разработчики воспринимают iOS как безопасную платформу из коробки и не закладывают adversary model с root-доступом к устройству. На джейлбрейкнутом iPhone каждый из описанных шагов отрабатывает без серьёзного сопротивления. Единственное, что реально усложняет работу - Keychain items с привязкой к Secure Enclave и биометрией на аппаратном уровне. Таких реализаций за последние два года я встретил три из двадцати с лишним проектов.

Frida и objection работают отлично - не в них проблема. Проблема в архитектуре приложений, где безопасность делегируется платформе вместо того, чтобы закладываться в код. Пока защита сводится к проверке isJailbroken() и boolean-флагу от LAContext, iOS-пентест будет оставаться предсказуемо результативным - и для охотников за уязвимостями, и для тех, кто попробует собрать описанную цепочку самостоятельно. На WAPT эту цепочку проходят в течение двух модулей с лабами.
 
Последнее редактирование модератором:
Мы в соцсетях:

Взломай свой первый сервер и прокачай скилл — Начни игру на HackerLab

🚀 Первый раз на Codeby?
Гайд для новичков: что делать в первые 15 минут, ключевые разделы, правила
Начать здесь →
🔴 Свежие CVE, 0-day и инциденты
То, о чём ChatGPT ещё не знает — обсуждаем в реальном времени
Threat Intel →
💼 Вакансии и заказы в ИБ
Pentest, SOC, DevSecOps, bug bounty — работа и проекты от проверенных компаний
Карьера в ИБ →

HackerLab