# iOS Pentesting {{#include ../../banners/hacktricks-training.md}} ## iOS Основи {{#ref}} ios-basics.md {{#endref}} ## Тестове середовище На цій сторінці ви можете знайти інформацію про **iOS симулятор**, **емулятори** та **джейлбрейк:** {{#ref}} ios-testing-environment.md {{#endref}} ## Початковий аналіз ### Основні операції тестування iOS Під час тестування **буде запропоновано кілька операцій** (підключитися до пристрою, читати/записувати/завантажувати/скачувати файли, використовувати деякі інструменти...). Тому, якщо ви не знаєте, як виконати будь-яку з цих дій, будь ласка, **почніть читати цю сторінку**: {{#ref}} basic-ios-testing-operations.md {{#endref}} > [!TIP] > Для наступних кроків **додаток має бути встановлено** на пристрої та вже має бути отримано **IPA файл** програми.\ > Прочитайте сторінку [Основні операції тестування iOS](basic-ios-testing-operations.md), щоб дізнатися, як це зробити. ### Основний статичний аналіз Деякі цікаві декомпілери iOS - IPA файлів: - [https://github.com/LaurieWired/Malimite](https://github.com/LaurieWired/Malimite) - [https://ghidra-sre.org/](https://ghidra-sre.org/) Рекомендується використовувати інструмент [**MobSF**](https://github.com/MobSF/Mobile-Security-Framework-MobSF) для автоматичного статичного аналізу IPA файлу. Ідентифікація **захистів, присутніх у бінарному файлі**: - **PIE (Position Independent Executable)**: Коли увімкнено, програма завантажується в випадкову адресу пам'яті щоразу при запуску, ускладнюючи передбачення її початкової адреси пам'яті. ```bash otool -hv | grep PIE # Має включати прапор PIE ``` - **Stack Canaries**: Для перевірки цілісності стеку значення «канарки» розміщується на стеку перед викликом функції і перевіряється знову після завершення функції. ```bash otool -I -v | grep stack_chk # Має включати символи: stack_chk_guard та stack_chk_fail ``` - **ARC (Automatic Reference Counting)**: Для запобігання поширеним помилкам корупції пам'яті ```bash otool -I -v | grep objc_release # Має включати символ _objc_release ``` - **Зашифрований бінарний файл**: Бінарний файл має бути зашифрований ```bash otool -arch all -Vl | grep -A5 LC_ENCRYPT # Криптід має бути 1 ``` **Ідентифікація чутливих/незахищених функцій** - **Слабкі алгоритми хешування** ```bash # На iOS пристрої otool -Iv | grep -w "_CC_MD5" otool -Iv | grep -w "_CC_SHA1" # На linux grep -iER "_CC_MD5" grep -iER "_CC_SHA1" ``` - **Ненадійні випадкові функції** ```bash # На iOS пристрої otool -Iv | grep -w "_random" otool -Iv | grep -w "_srand" otool -Iv | grep -w "_rand" # На linux grep -iER "_random" grep -iER "_srand" grep -iER "_rand" ``` - **Ненадійна функція ‘Malloc’** ```bash # На iOS пристрої otool -Iv | grep -w "_malloc" # На linux grep -iER "_malloc" ``` - **Ненадійні та вразливі функції** ```bash # На iOS пристрої otool -Iv | grep -w "_gets" otool -Iv | grep -w "_memcpy" otool -Iv | grep -w "_strncpy" otool -Iv | grep -w "_strlen" otool -Iv | grep -w "_vsnprintf" otool -Iv | grep -w "_sscanf" otool -Iv | grep -w "_strtok" otool -Iv | grep -w "_alloca" otool -Iv | grep -w "_sprintf" otool -Iv | grep -w "_printf" otool -Iv | grep -w "_vsprintf" # На linux grep -R "_gets" grep -iER "_memcpy" grep -iER "_strncpy" grep -iER "_strlen" grep -iER "_vsnprintf" grep -iER "_sscanf" grep -iER "_strtok" grep -iER "_alloca" grep -iER "_sprintf" grep -iER "_printf" grep -iER "_vsprintf" ``` ### Основний динамічний аналіз Ознайомтеся з динамічним аналізом, який виконує [**MobSF**](https://github.com/MobSF/Mobile-Security-Framework-MobSF). Вам потрібно буде переміщатися між різними виглядами та взаємодіяти з ними, але він буде підключати кілька класів під час виконання інших дій і підготує звіт, коли ви закінчите. ### Перелік встановлених додатків Використовуйте команду `frida-ps -Uai`, щоб визначити **ідентифікатор пакета** встановлених додатків: ```bash $ frida-ps -Uai PID Name Identifier ---- ------------------- ----------------------------------------- 6847 Calendar com.apple.mobilecal 6815 Mail com.apple.mobilemail - App Store com.apple.AppStore - Apple Store com.apple.store.Jolly - Calculator com.apple.calculator - Camera com.apple.camera - iGoat-Swift OWASP.iGoat-Swift ``` ### Основна Перерахування та Хукінг Дізнайтеся, як **перерахувати компоненти програми** та як легко **підключати методи та класи** за допомогою objection: {{#ref}} ios-hooking-with-objection.md {{#endref}} ### Структура IPA Структура **IPA файлу** в основному є структурою **запакованого архіву**. Змінивши його розширення на `.zip`, його можна **розпакувати**, щоб виявити його вміст. У цій структурі **Bundle** представляє повністю упаковану програму, готову до встановлення. Всередині ви знайдете каталог з назвою `.app`, який містить ресурси програми. - **`Info.plist`**: Цей файл містить специфічні конфігураційні деталі програми. - **`_CodeSignature/`**: Цей каталог включає файл plist, який містить підпис, що забезпечує цілісність усіх файлів у бандлі. - **`Assets.car`**: Стиснутий архів, який зберігає файли активів, такі як іконки. - **`Frameworks/`**: Ця папка містить рідні бібліотеки програми, які можуть бути у формі файлів `.dylib` або `.framework`. - **`PlugIns/`**: Це може включати розширення програми, відомі як файли `.appex`, хоча вони не завжди присутні. \* [**`Core Data`**](https://developer.apple.com/documentation/coredata): Використовується для збереження постійних даних вашої програми для офлайн-використання, для кешування тимчасових даних та для додавання функціональності скасування в вашій програмі на одному пристрої. Щоб синхронізувати дані між кількома пристроями в одному обліковому записі iCloud, Core Data автоматично віддзеркалює вашу схему в контейнер CloudKit. - [**`PkgInfo`**](https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPRuntimeConfig/Articles/ConfigApplications.html): Файл `PkgInfo` є альтернативним способом вказати тип і коди творця вашої програми або бандлу. - **en.lproj, fr.proj, Base.lproj**: Це мовні пакети, які містять ресурси для цих конкретних мов, а також ресурс за замовчуванням на випадок, якщо мова не підтримується. - **Безпека**: Каталог `_CodeSignature/` відіграє критичну роль у безпеці програми, перевіряючи цілісність усіх упакованих файлів через цифрові підписи. - **Управління активами**: Файл `Assets.car` використовує стиснення для ефективного управління графічними активами, що є важливим для оптимізації продуктивності програми та зменшення її загального розміру. - **Frameworks та PlugIns**: Ці каталоги підкреслюють модульність iOS програм, дозволяючи розробникам включати повторно використовувані бібліотеки коду (`Frameworks/`) та розширювати функціональність програми (`PlugIns/`). - **Локалізація**: Структура підтримує кілька мов, полегшуючи глобальне охоплення програми, включаючи ресурси для специфічних мовних пакетів. **Info.plist** **Info.plist** служить основою для iOS програм, інкапсулюючи ключові конфігураційні дані у формі **пар ключ-значення**. Цей файл є обов'язковим не лише для програм, але й для розширень програм та фреймворків, що входять до складу. Він структурований у форматі XML або бінарному форматі та містить критичну інформацію, починаючи від дозволів програми до конфігурацій безпеки. Для детального вивчення доступних ключів можна звернутися до [**Apple Developer Documentation**](https://developer.apple.com/documentation/bundleresources/information_property_list?language=objc). Для тих, хто хоче працювати з цим файлом у більш доступному форматі, конвертацію в XML можна здійснити без зусиль за допомогою `plutil` на macOS (доступний нативно на версіях 10.2 і пізніше) або `plistutil` на Linux. Команди для конвертації такі: - **Для macOS**: ```bash $ plutil -convert xml1 Info.plist ``` - **Для Linux**: ```bash $ apt install libplist-utils $ plistutil -i Info.plist -o Info_xml.plist ``` Серед безлічі інформації, яку може розкрити файл **Info.plist**, помітні записи включають рядки дозволів додатка (`UsageDescription`), власні URL-схеми (`CFBundleURLTypes`) та конфігурації для App Transport Security (`NSAppTransportSecurity`). Ці записи, разом з іншими, такими як експортовані/імпортовані власні типи документів (`UTExportedTypeDeclarations` / `UTImportedTypeDeclarations`), можна без зусиль знайти, перевіряючи файл або використовуючи просту команду `grep`: ```bash $ grep -i Info.plist ``` **Шляхи даних** У середовищі iOS каталоги призначені спеціально для **системних додатків** та **додатків, встановлених користувачем**. Системні додатки розташовані в каталозі `/Applications`, тоді як додатки, встановлені користувачем, знаходяться в `/var/mobile/containers/Data/Application/`. Цим додаткам присвоюється унікальний ідентифікатор, відомий як **128-бітний UUID**, що ускладнює завдання ручного знаходження папки додатка через випадковість назв каталогів. > [!WARNING] > Оскільки додатки в iOS повинні бути в пісочниці, кожен додаток також матиме папку всередині **`$HOME/Library/Containers`** з **`CFBundleIdentifier`** додатка як назва папки. > > Однак обидві папки (папки даних та контейнерів) мають файл **`.com.apple.mobile_container_manager.metadata.plist`**, який пов'язує обидва файли за ключем `MCMetadataIdentifier`. Щоб полегшити виявлення каталогу встановлення додатка, встановленого користувачем, **інструмент objection** надає корисну команду `env`. Ця команда розкриває детальну інформацію про каталог для відповідного додатка. Нижче наведено приклад використання цієї команди: ```bash OWASP.iGoat-Swift on (iPhone: 11.1.2) [usb] # env Name Path ----------------- ------------------------------------------------------------------------------------------- BundlePath /var/containers/Bundle/Application/3ADAF47D-A734-49FA-B274-FBCA66589E67/iGoat-Swift.app CachesDirectory /var/mobile/Containers/Data/Application/8C8E7EB0-BC9B-435B-8EF8-8F5560EB0693/Library/Caches DocumentDirectory /var/mobile/Containers/Data/Application/8C8E7EB0-BC9B-435B-8EF8-8F5560EB0693/Documents LibraryDirectory /var/mobile/Containers/Data/Application/8C8E7EB0-BC9B-435B-8EF8-8F5560EB0693/Library ``` Альтернативно, ім'я програми можна знайти в `/private/var/containers`, використовуючи команду `find`: ```bash find /private/var/containers -name "Progname*" ``` Команди такі як `ps` та `lsof` також можуть бути використані для ідентифікації процесу програми та переліку відкритих файлів відповідно, надаючи інформацію про активні директорії програми: ```bash ps -ef | grep -i lsof -p | grep -i "/containers" | head -n 1 ``` **Bundle directory:** - **AppName.app** - Це пакет програми, як було показано раніше в IPA, він містить основні дані програми, статичний контент, а також скомпільований бінарний файл програми. - Ця директорія видима для користувачів, але **користувачі не можуть записувати в неї**. - Контент у цій директорії **не резервується**. - Вміст цієї папки використовується для **перевірки підпису коду**. **Data directory:** - **Documents/** - Містить всі дані, створені користувачем. Кінцевий користувач програми ініціює створення цих даних. - Видима для користувачів і **користувачі можуть записувати в неї**. - Контент у цій директорії **резервується**. - Програма може вимкнути шляхи, встановивши `NSURLIsExcludedFromBackupKey`. - **Library/** - Містить всі **файли, які не є специфічними для користувача**, такі як **кеші**, **налаштування**, **куки** та файли конфігурації списку властивостей (plist). - iOS програми зазвичай використовують підкаталоги `Application Support` та `Caches`, але програма може створювати власні підкаталоги. - **Library/Caches/** - Містить **напівпостійні кешовані файли.** - Невидима для користувачів і **користувачі не можуть записувати в неї**. - Контент у цій директорії **не резервується**. - ОС може автоматично видаляти файли цієї директорії, коли програма не працює і місця для зберігання недостатньо. - **Library/Application Support/** - Містить **постійні** **файли**, необхідні для роботи програми. - **Невидима** **для** **користувачів** і користувачі не можуть записувати в неї. - Контент у цій директорії **резервується**. - Програма може вимкнути шляхи, встановивши `NSURLIsExcludedFromBackupKey`. - **Library/Preferences/** - Використовується для зберігання властивостей, які можуть **зберігатися навіть після перезапуску програми**. - Інформація зберігається, нешифрована, всередині пісочниці програми у файлі plist під назвою \[BUNDLE_ID].plist. - Усі пари ключ/значення, збережені за допомогою `NSUserDefaults`, можна знайти в цьому файлі. - **tmp/** - Використовуйте цю директорію для запису **тимчасових файлів**, які не потрібно зберігати між запусками програми. - Містить непостійні кешовані файли. - **Невидима** для користувачів. - Контент у цій директорії не резервується. - ОС може автоматично видаляти файли цієї директорії, коли програма не працює і місця для зберігання недостатньо. Давайте ближче розглянемо пакет програми iGoat-Swift (.app) у директорії Bundle (`/var/containers/Bundle/Application/3ADAF47D-A734-49FA-B274-FBCA66589E67/iGoat-Swift.app`): ```bash OWASP.iGoat-Swift on (iPhone: 11.1.2) [usb] # ls NSFileType Perms NSFileProtection ... Name ------------ ------- ------------------ ... -------------------------------------- Regular 420 None ... rutger.html Regular 420 None ... mansi.html Regular 420 None ... splash.html Regular 420 None ... about.html Regular 420 None ... LICENSE.txt Regular 420 None ... Sentinel.txt Regular 420 None ... README.txt ``` ### Binary Reversing Всередині папки `.app` ви знайдете бінарний файл під назвою ``. Це файл, який буде **виконуватись**. Ви можете виконати базову перевірку бінарного файлу за допомогою інструменту **`otool`**: ```bash otool -Vh DVIA-v2 #Check some compilation attributes magic cputype cpusubtype caps filetype ncmds sizeofcmds flags MH_MAGIC_64 ARM64 ALL 0x00 EXECUTE 65 7112 NOUNDEFS DYLDLINK TWOLEVEL WEAK_DEFINES BINDS_TO_WEAK PIE otool -L DVIA-v2 #Get third party libraries DVIA-v2: /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.1) /usr/lib/libsqlite3.dylib (compatibility version 9.0.0, current version 274.6.0) /usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.11) @rpath/Bolts.framework/Bolts (compatibility version 1.0.0, current version 1.0.0) [...] ``` **Перевірте, чи зашифровано додаток** Перевірте, чи є будь-який вихід для: ```bash otool -l | grep -A 4 LC_ENCRYPTION_INFO ``` **Дизасемблювання бінарного файлу** Дизасемблюйте текстовий розділ: ```bash otool -tV DVIA-v2 DVIA-v2: (__TEXT,__text) section +[DDLog initialize]: 0000000100004ab8 sub sp, sp, #0x60 0000000100004abc stp x29, x30, [sp, #0x50] ; Latency: 6 0000000100004ac0 add x29, sp, #0x50 0000000100004ac4 sub x8, x29, #0x10 0000000100004ac8 mov x9, #0x0 0000000100004acc adrp x10, 1098 ; 0x10044e000 0000000100004ad0 add x10, x10, #0x268 ``` Щоб надрукувати **Objective-C сегмент** зразкової програми, можна використовувати: ```bash otool -oV DVIA-v2 DVIA-v2: Contents of (__DATA,__objc_classlist) section 00000001003dd5b8 0x1004423d0 _OBJC_CLASS_$_DDLog isa 0x1004423a8 _OBJC_METACLASS_$_DDLog superclass 0x0 _OBJC_CLASS_$_NSObject cache 0x0 __objc_empty_cache vtable 0x0 data 0x1003de748 flags 0x80 instanceStart 8 ``` Щоб отримати більш компактний код Objective-C, ви можете використовувати [**class-dump**](http://stevenygard.com/projects/class-dump/): ```bash class-dump some-app // // Generated by class-dump 3.5 (64 bit). // // class-dump is Copyright (C) 1997-1998, 2000-2001, 2004-2013 by Steve Nygard. // #pragma mark Named Structures struct CGPoint { double _field1; double _field2; }; struct CGRect { struct CGPoint _field1; struct CGSize _field2; }; struct CGSize { double _field1; double _field2; }; ``` Однак найкращими варіантами для дизасемблювання бінарного коду є: [**Hopper**](https://www.hopperapp.com/download.html?) та [**IDA**](https://www.hex-rays.com/products/ida/support/download_freeware/). ## Зберігання даних Щоб дізнатися, як iOS зберігає дані на пристрої, прочитайте цю сторінку: {{#ref}} ios-basics.md {{#endref}} > [!WARNING] > Наступні місця для зберігання інформації слід перевірити **відразу після встановлення програми**, **після перевірки всіх функцій** програми і навіть після **виходу з одного користувача та входу в іншого**.\ > Мета полягає в тому, щоб знайти **незахищену чутливу інформацію** програми (паролі, токени), поточного користувача та раніше увійшлих користувачів. ### Plist **plist** файли - це структуровані XML файли, які **містять пари ключ-значення**. Це спосіб зберігати постійні дані, тому іноді ви можете знайти **чутливу інформацію в цих файлах**. Рекомендується перевіряти ці файли після встановлення програми та після інтенсивного використання, щоб побачити, чи записуються нові дані. Найпоширеніший спосіб зберігати дані в plist файлах - це використання **NSUserDefaults**. Цей plist файл зберігається всередині пісочниці програми в **`Library/Preferences/.plist`**. Клас [`NSUserDefaults`](https://developer.apple.com/documentation/foundation/nsuserdefaults) надає програмний інтерфейс для взаємодії з системою за замовчуванням. Система за замовчуванням дозволяє програмі налаштовувати свою поведінку відповідно до **уподобань користувача**. Дані, збережені за допомогою `NSUserDefaults`, можна переглядати в пакеті програми. Цей клас зберігає **дані** в **plist** **файлі**, але призначений для використання з невеликою кількістю даних. Ці дані не можуть бути доступні безпосередньо через надійний комп'ютер, але можуть бути доступні шляхом виконання **резервного копіювання**. Ви можете **вивантажити** інформацію, збережену за допомогою **`NSUserDefaults`**, використовуючи `ios nsuserdefaults get` з objection. Щоб знайти всі plist, які використовуються програмою, ви можете отримати доступ до `/private/var/mobile/Containers/Data/Application/{APPID}` і виконати: ```bash find ./ -name "*.plist" ``` Щоб конвертувати файли з **XML або бінарного (bplist)** формату в XML, доступні різні методи в залежності від вашої операційної системи: **Для користувачів macOS:** Використовуйте команду `plutil`. Це вбудований інструмент в macOS (10.2+), призначений для цієї мети: ```bash $ plutil -convert xml1 Info.plist ``` **Для користувачів Linux:** Спочатку встановіть `libplist-utils`, а потім використовуйте `plistutil` для конвертації вашого файлу: ```bash $ apt install libplist-utils $ plistutil -i Info.plist -o Info_xml.plist ``` **У сесії Objection:** Для аналізу мобільних додатків специфічна команда дозволяє вам безпосередньо конвертувати файли plist: ```bash ios plist cat /private/var/mobile/Containers/Data/Application//Library/Preferences/com.some.package.app.plist ``` ### Core Data [`Core Data`](https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CoreData/nsfetchedresultscontroller.html#//apple_ref/doc/uid/TP40001075-CH8-SW1) — це фреймворк для управління модельним шаром об'єктів у вашому додатку. [Core Data може використовувати SQLite як свій постійний сховище](https://cocoacasts.com/what-is-the-difference-between-core-data-and-sqlite/), але сам фреймворк не є базою даних.\ CoreData за замовчуванням не шифрує свої дані. Однак додатковий шар шифрування може бути доданий до CoreData. Дивіться [GitHub Repo](https://github.com/project-imas/encrypted-core-data) для отримання додаткової інформації. Ви можете знайти інформацію про SQLite Core Data додатку за шляхом `/private/var/mobile/Containers/Data/Application/{APPID}/Library/Application Support` **Якщо ви можете відкрити SQLite і отримати доступ до чутливої інформації, то ви виявили неправильну конфігурацію.** ```objectivec:Code from iGoat -(void)storeDetails { AppDelegate * appDelegate = (AppDelegate *)(UIApplication.sharedApplication.delegate); NSManagedObjectContext *context =[appDelegate managedObjectContext]; User *user = [self fetchUser]; if (user) { return; } user = [NSEntityDescription insertNewObjectForEntityForName:@"User" inManagedObjectContext:context]; user.email = CoreDataEmail; user.password = CoreDataPassword; NSError *error; if (![context save:&error]) { NSLog(@"Error in saving data: %@", [error localizedDescription]); }else{ NSLog(@"data stored in core data"); } } ``` ### YapDatabase [YapDatabase](https://github.com/yapstudios/YapDatabase) - це сховище ключ/значення, побудоване на основі SQLite.\ Оскільки бази даних Yap є базами даних sqlite, ви можете знайти їх, використовуючи запропоновану команду в попередньому розділі. ### Інші бази даних SQLite Звичайно, що програми створюють свої власні бази даних sqlite. Вони можуть **зберігати** **чутливі** **дані** на них і залишати їх незашифрованими. Тому завжди цікаво перевіряти кожну базу даних у каталозі додатків. Тому перейдіть до каталогу програми, де зберігаються дані (`/private/var/mobile/Containers/Data/Application/{APPID}`) ```bash find ./ -name "*.sqlite" -or -name "*.db" ``` ### Firebase Real-Time Databases Розробники можуть **зберігати та синхронізувати дані** в **NoSQL хмарній базі даних** через Firebase Real-Time Databases. Дані, збережені у форматі JSON, синхронізуються з усіма підключеними клієнтами в реальному часі. Ви можете дізнатися, як перевірити неправильно налаштовані Firebase бази даних тут: {{#ref}} ../../network-services-pentesting/pentesting-web/buckets/firebase-database.md {{#endref}} ### Realm databases [Realm Objective-C](https://realm.io/docs/objc/latest/) та [Realm Swift](https://realm.io/docs/swift/latest/) пропонують потужну альтернативу для зберігання даних, яку не надає Apple. За замовчуванням вони **зберігають дані без шифрування**, з можливістю шифрування через специфічну конфігурацію. Бази даних розташовані за адресою: `/private/var/mobile/Containers/Data/Application/{APPID}`. Щоб дослідити ці файли, можна використовувати команди, такі як: ```bash iPhone:/private/var/mobile/Containers/Data/Application/A079DF84-726C-4AEA-A194-805B97B3684A/Documents root# ls default.realm default.realm.lock default.realm.management/ default.realm.note| $ find ./ -name "*.realm*" ``` Для перегляду цих файлів бази даних рекомендується інструмент [**Realm Studio**](https://github.com/realm/realm-studio). Щоб реалізувати шифрування в базі даних Realm, можна використовувати наступний фрагмент коду: ```swift // Open the encrypted Realm file where getKey() is a method to obtain a key from the Keychain or a server let config = Realm.Configuration(encryptionKey: getKey()) do { let realm = try Realm(configuration: config) // Use the Realm as normal } catch let error as NSError { // If the encryption key is wrong, `error` will say that it's an invalid database fatalError("Error opening realm: \(error)") } ``` ### Couchbase Lite Databases [Couchbase Lite](https://github.com/couchbase/couchbase-lite-ios) описується як **легкий** та **вбудований** механізм бази даних, який слідує **документно-орієнтованому** (NoSQL) підходу. Розроблений для **iOS** та **macOS**, він пропонує можливість безперебійної синхронізації даних. Щоб виявити потенційні бази даних Couchbase на пристрої, слід перевірити наступний каталог: ```bash ls /private/var/mobile/Containers/Data/Application/{APPID}/Library/Application Support/ ``` ### Cookies iOS зберігає куки додатків у **`Library/Cookies/cookies.binarycookies`** всередині папки кожного додатку. Однак, розробники іноді вирішують зберігати їх у **keychain**, оскільки згаданий **файл куків може бути доступний у резервних копіях**. Щоб перевірити файл куків, ви можете використовувати [**цей python скрипт**](https://github.com/mdegrazia/Safari-Binary-Cookie-Parser) або використовувати **`ios cookies get`** з objection.\ **Ви також можете використовувати objection, щоб** конвертувати ці файли у формат JSON та перевірити дані. ```bash ...itudehacks.DVIAswiftv2.develop on (iPhone: 13.2.3) [usb] # ios cookies get --json [ { "domain": "highaltitudehacks.com", "expiresDate": "2051-09-15 07:46:43 +0000", "isHTTPOnly": "false", "isSecure": "false", "name": "username", "path": "/", "value": "admin123", "version": "0" } ] ``` ### Cache За замовчуванням NSURLSession зберігає дані, такі як **HTTP запити та відповіді в базі даних Cache.db**. Ця база даних може містити **чутливі дані**, якщо токени, імена користувачів або будь-яка інша чутлива інформація була кешована. Щоб знайти кешовану інформацію, відкрийте каталог даних програми (`/var/mobile/Containers/Data/Application/`) і перейдіть до `/Library/Caches/`. **Кеш WebKit також зберігається у файлі Cache.db**. **Objection** може відкрити та взаємодіяти з базою даних за допомогою команди `sqlite connect Cache.db`, оскільки це є н**ормальною SQLite базою даних**. Рекомендується **відключити кешування цих даних**, оскільки вони можуть містити чутливу інформацію в запиті або відповіді. Нижче наведено різні способи досягнення цього: 1. Рекомендується видаляти кешовані відповіді після виходу з системи. Це можна зробити за допомогою методу, наданого Apple, під назвою [`removeAllCachedResponses`](https://developer.apple.com/documentation/foundation/urlcache/1417802-removeallcachedresponses). Ви можете викликати цей метод наступним чином: `URLCache.shared.removeAllCachedResponses()` Цей метод видалить всі кешовані запити та відповіді з файлу Cache.db. 2. Якщо вам не потрібно використовувати переваги куків, рекомендується просто використовувати [.ephemeral](https://developer.apple.com/documentation/foundation/urlsessionconfiguration/1410529-ephemeral) властивість конфігурації URLSession, яка відключить збереження куків та кешів. [Документація Apple](https://developer.apple.com/documentation/foundation/urlsessionconfiguration/1410529-ephemeral): `Об'єкт конфігурації сесії ephemeral подібний до об'єкта конфігурації сесії за замовчуванням (див. default), за винятком того, що відповідний об'єкт сесії не зберігає кеші, сховища облікових даних або будь-які дані, пов'язані з сесією, на диску. Натомість дані, пов'язані з сесією, зберігаються в оперативній пам'яті. Єдиний раз, коли ephemeral сесія записує дані на диск, це коли ви кажете їй записати вміст URL у файл.` 3. Кеш також можна відключити, встановивши політику кешування на [.notAllowed](https://developer.apple.com/documentation/foundation/urlcache/storagepolicy/notallowed). Це відключить зберігання кешу будь-яким чином, як в пам'яті, так і на диску. ### Snapshots Коли ви натискаєте кнопку "Додому", iOS **знімає знімок поточного екрану**, щоб забезпечити більш плавний перехід до програми. Однак, якщо на поточному екрані присутні **чутливі** **дані**, вони будуть **збережені** в **зображенні** (яке **зберігається** **після** **перезавантажень**). Це знімки, до яких ви також можете отримати доступ, двічі торкнувшись головного екрану для перемикання між програмами. Якщо iPhone не зламаний, **зловмисник** повинен мати **доступ** до **пристрою** **без блокування**, щоб побачити ці знімки екрана. За замовчуванням останній знімок зберігається в пісочниці програми в папці `Library/Caches/Snapshots/` або `Library/SplashBoard/Snapshots` (достовірні комп'ютери не можуть отримати доступ до файлової системи з iOX 7.0). Один зі способів запобігти цій небажаній поведінці - це поставити чорний екран або видалити чутливі дані перед зняттям знімка, використовуючи функцію `ApplicationDidEnterBackground()`. Нижче наведено приклад методу усунення, який встановить знімок за замовчуванням. Swift: ```swift private var backgroundImage: UIImageView? func applicationDidEnterBackground(_ application: UIApplication) { let myBanner = UIImageView(image: #imageLiteral(resourceName: "overlayImage")) myBanner.frame = UIScreen.main.bounds backgroundImage = myBanner window?.addSubview(myBanner) } func applicationWillEnterForeground(_ application: UIApplication) { backgroundImage?.removeFromSuperview() } ``` Objective-C: ``` @property (UIImageView *)backgroundImage; - (void)applicationDidEnterBackground:(UIApplication *)application { UIImageView *myBanner = [[UIImageView alloc] initWithImage:@"overlayImage.png"]; self.backgroundImage = myBanner; self.backgroundImage.bounds = UIScreen.mainScreen.bounds; [self.window addSubview:myBanner]; } - (void)applicationWillEnterForeground:(UIApplication *)application { [self.backgroundImage removeFromSuperview]; } ``` Це встановлює фонове зображення на `overlayImage.png` щоразу, коли додаток переходить у фоновий режим. Це запобігає витоку чутливих даних, оскільки `overlayImage.png` завжди перекриває поточний вигляд. ### Keychain Для доступу та управління iOS keychain доступні інструменти, такі як [**Keychain-Dumper**](https://github.com/ptoomey3/Keychain-Dumper), які підходять для джейлбрейкнутіх пристроїв. Крім того, [**Objection**](https://github.com/sensepost/objection) надає команду `ios keychain dump` для подібних цілей. #### **Зберігання облікових даних** Клас **NSURLCredential** ідеально підходить для збереження чутливої інформації безпосередньо в keychain, обходячи необхідність у NSUserDefaults або інших обгортках. Щоб зберегти облікові дані після входу, використовується наступний код Swift: ```swift NSURLCredential *credential; credential = [NSURLCredential credentialWithUser:username password:password persistence:NSURLCredentialPersistencePermanent]; [[NSURLCredentialStorage sharedCredentialStorage] setCredential:credential forProtectionSpace:self.loginProtectionSpace]; ``` Щоб витягти ці збережені облікові дані, використовується команда Objection `ios nsurlcredentialstorage dump`. ## **Користувацькі клавіатури та кеш клавіатури** Починаючи з iOS 8.0, користувачі можуть встановлювати розширення користувацьких клавіатур, які можна керувати в **Налаштування > Загальні > Клавіатура > Клавіатури**. Хоча ці клавіатури пропонують розширену функціональність, вони несуть ризик реєстрації натискань клавіш і передачі даних на зовнішні сервери, хоча користувачі отримують сповіщення про клавіатури, які потребують доступу до мережі. Додатки можуть і повинні обмежувати використання користувацьких клавіатур для введення чутливої інформації. **Рекомендації з безпеки:** - Рекомендується вимкнути сторонні клавіатури для підвищення безпеки. - Будьте обережні з функціями автокорекції та автоматичних підказок стандартної клавіатури iOS, які можуть зберігати чутливу інформацію у кеш-файлах, розташованих у `Library/Keyboard/{locale}-dynamic-text.dat` або `/private/var/mobile/Library/Keyboard/dynamic-text.dat`. Ці кеш-файли слід регулярно перевіряти на наявність чутливих даних. Рекомендується скинути словник клавіатури через **Налаштування > Загальні > Скинути > Скинути словник клавіатури** для очищення кешованих даних. - Перехоплення мережевого трафіку може виявити, чи передає користувацька клавіатура натискання клавіш віддалено. ### **Запобігання кешуванню текстових полів** Протокол [UITextInputTraits](https://developer.apple.com/reference/uikit/uitextinputtraits) пропонує властивості для управління автокорекцією та безпечним введенням тексту, що є важливим для запобігання кешуванню чутливої інформації. Наприклад, вимкнення автокорекції та увімкнення безпечного введення тексту можна досягти за допомогою: ```objectivec textObject.autocorrectionType = UITextAutocorrectionTypeNo; textObject.secureTextEntry = YES; ``` Крім того, розробники повинні забезпечити, щоб текстові поля, особливо ті, що призначені для введення чутливої інформації, такої як паролі та PIN-коди, вимикали кешування, встановивши `autocorrectionType` на `UITextAutocorrectionTypeNo` та `secureTextEntry` на `YES`. ```objectivec UITextField *textField = [[UITextField alloc] initWithFrame:frame]; textField.autocorrectionType = UITextAutocorrectionTypeNo; ``` ## **Логи** Відлагодження коду часто передбачає використання **логування**. Існує ризик, оскільки **логи можуть містити чутливу інформацію**. Раніше, в iOS 6 та попередніх версіях, логи були доступні всім додаткам, що створювало ризик витоку чутливих даних. **Тепер додатки обмежені у доступі лише до своїх логів**. Незважаючи на ці обмеження, **зловмисник з фізичним доступом** до розблокованого пристрою все ще може скористатися цим, підключивши пристрій до комп'ютера та **прочитавши логи**. Важливо зазначити, що логи залишаються на диску навіть після видалення додатка. Щоб зменшити ризики, рекомендується **ретельно взаємодіяти з додатком**, досліджуючи всі його функціональні можливості та введення, щоб переконатися, що жодна чутлива інформація не записується ненавмисно. При перегляді вихідного коду додатка на предмет потенційних витоків, звертайте увагу як на **попередньо визначені**, так і на **кастомні логуючі оператори**, використовуючи ключові слова, такі як `NSLog`, `NSAssert`, `NSCAssert`, `fprintf` для вбудованих функцій, а також будь-які згадки про `Logging` або `Logfile` для кастомних реалізацій. ### **Моніторинг системних логів** Додатки записують різні фрагменти інформації, які можуть бути чутливими. Для моніторингу цих логів використовують інструменти та команди, такі як: ```bash idevice_id --list # To find the device ID idevicesyslog -u (| grep ) # To capture the device logs ``` є корисними. Додатково, **Xcode** надає спосіб збору консолі логів: 1. Відкрийте Xcode. 2. Підключіть iOS пристрій. 3. Перейдіть до **Window** -> **Devices and Simulators**. 4. Виберіть ваш пристрій. 5. Викличте проблему, яку ви досліджуєте. 6. Використовуйте кнопку **Open Console**, щоб переглянути логи в новому вікні. Для більш просунутого логування, підключення до оболонки пристрою та використання **socat** може забезпечити моніторинг логів в реальному часі: ```bash iPhone:~ root# socat - UNIX-CONNECT:/var/run/lockdown/syslog.sock ``` Слід за командами для спостереження за активністю журналів, що може бути безцінним для діагностики проблем або виявлення потенційного витоку даних у журналах. ## Резервні копії **Функції автоматичного резервного копіювання** інтегровані в iOS, що полегшує створення копій даних пристрою через iTunes (до macOS Catalina), Finder (з macOS Catalina і далі) або iCloud. Ці резервні копії охоплюють майже всі дані пристрою, за винятком дуже чутливих елементів, таких як деталі Apple Pay та налаштування Touch ID. ### Ризики безпеки Включення **встановлених додатків та їх даних** у резервні копії піднімає питання потенційного **витоку даних** та ризик того, що **модифікації резервних копій можуть змінити функціональність додатків**. Рекомендується **не зберігати чутливу інформацію у відкритому вигляді** в будь-якому каталозі додатка або його підкаталогах, щоб зменшити ці ризики. ### Виключення файлів з резервних копій Файли в `Documents/` та `Library/Application Support/` за замовчуванням резервуються. Розробники можуть виключити конкретні файли або каталоги з резервних копій, використовуючи `NSURL setResourceValue:forKey:error:` з `NSURLIsExcludedFromBackupKey`. Ця практика є важливою для захисту чутливих даних від включення в резервні копії. ### Тестування на вразливості Щоб оцінити безпеку резервного копіювання додатка, почніть з **створення резервної копії** за допомогою Finder, а потім знайдіть її, скориставшись вказівками з [офіційної документації Apple](https://support.apple.com/en-us/HT204215). Проаналізуйте резервну копію на наявність чутливих даних або конфігурацій, які можуть бути змінені для впливу на поведінку додатка. Чутливу інформацію можна шукати за допомогою інструментів командного рядка або додатків, таких як [iMazing](https://imazing.com). Для зашифрованих резервних копій наявність шифрування можна підтвердити, перевіривши ключ "IsEncrypted" у файлі "Manifest.plist" в корені резервної копії. ```xml ... Date 2021-03-12T17:43:33Z IsEncrypted ... ``` Для роботи з зашифрованими резервними копіями можуть бути корисні скрипти Python, доступні в [репозиторії DinoSec на GitHub](https://github.com/dinosec/iphone-dataprotection/tree/master/python_scripts), такі як **backup_tool.py** та **backup_passwd.py**, хоча вони можуть вимагати коригувань для сумісності з останніми версіями iTunes/Finder. Іншим варіантом для доступу до файлів у захищених паролем резервних копіях є [**iOSbackup**](https://pypi.org/project/iOSbackup/). ### Модифікація поведінки додатка Приклад зміни поведінки додатка через модифікації резервної копії продемонстровано в [додатку Bither bitcoin wallet](https://github.com/bither/bither-ios), де PIN-код блокування UI зберігається в `net.bither.plist` під ключем **pin_code**. Видалення цього ключа з plist і відновлення резервної копії усуває вимогу PIN-коду, надаючи необмежений доступ. ## Резюме щодо тестування пам'яті для чутливих даних При роботі з чутливою інформацією, що зберігається в пам'яті додатка, важливо обмежити час експозиції цих даних. Існують два основні підходи для дослідження вмісту пам'яті: **створення дампа пам'яті** та **аналіз пам'яті в реальному часі**. Обидва методи мають свої виклики, включаючи можливість пропустити критично важливі дані під час процесу дампа або аналізу. ## **Отримання та аналіз дампа пам'яті** Для пристроїв з джейлбрейком і без нього інструменти, такі як [objection](https://github.com/sensepost/objection) та [Fridump](https://github.com/Nightbringer21/fridump), дозволяють створювати дамп пам'яті процесу додатка. Після створення дампа аналіз цих даних вимагає різних інструментів, залежно від природи інформації, яку ви шукаєте. Щоб витягти рядки з дампа пам'яті, можна використовувати команди, такі як `strings` або `rabin2 -zz`: ```bash # Extracting strings using strings command $ strings memory > strings.txt # Extracting strings using rabin2 $ rabin2 -ZZ memory > strings.txt ``` Для більш детального аналізу, включаючи пошук специфічних типів даних або шаблонів, **radare2** пропонує розширені можливості пошуку: ```bash $ r2 [0x00000000]> /? ... ``` ## **Аналіз пам'яті під час виконання** **r2frida** надає потужну альтернативу для перевірки пам'яті програми в реальному часі, без необхідності в дампі пам'яті. Цей інструмент дозволяє виконувати команди пошуку безпосередньо в пам'яті запущеного додатку: ```bash $ r2 frida://usb// [0x00000000]> /\ ``` ## Зламане Криптографічне Шифрування ### Погані Процеси Управління Ключами Деякі розробники зберігають чутливі дані в локальному сховищі та шифрують їх за допомогою ключа, закодованого в коді. Це не слід робити, оскільки деяке реверсування може дозволити зловмисникам витягти конфіденційну інформацію. ### Використання Небезпечних та/або Застарілих Алгоритмів Розробники не повинні використовувати **застарілі алгоритми** для виконання **перевірок** авторизації, **зберігання** або **відправки** даних. Деякі з цих алгоритмів: RC4, MD4, MD5, SHA1... Якщо **хеші** використовуються для зберігання паролів, наприклад, слід використовувати хеші, стійкі до брутфорсу, з сіллю. ### Перевірка Основні перевірки, які потрібно виконати, це знайти, чи можна знайти **жорстко закодовані** паролі/секрети в коді, або чи вони **передбачувані**, і чи використовує код якісь **слабкі** **криптографічні** алгоритми. Цікаво знати, що ви можете **моніторити** деякі **крипто** **бібліотеки** автоматично, використовуючи **objection** з: ```swift ios monitor crypt ``` Для **додаткової інформації** про криптографічні API та бібліотеки iOS зверніться до [https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06e-testing-cryptography](https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06e-testing-cryptography) ## Локальна аутентифікація **Локальна аутентифікація** відіграє важливу роль, особливо коли йдеться про захист доступу до віддаленого кінцевого пункту за допомогою криптографічних методів. Суть полягає в тому, що без належної реалізації механізми локальної аутентифікації можуть бути обійдені. [**Фреймворк локальної аутентифікації**](https://developer.apple.com/documentation/localauthentication) Apple та [**keychain**](https://developer.apple.com/library/content/documentation/Security/Conceptual/keychainServConcepts/01introduction/introduction.html) надають надійні API для розробників, щоб полегшити діалоги аутентифікації користувачів і безпечно обробляти секретні дані відповідно. Secure Enclave захищає ідентифікацію відбитків пальців для Touch ID, тоді як Face ID покладається на розпізнавання обличчя без компрометації біометричних даних. Для інтеграції Touch ID/Face ID розробники мають два варіанти API: - **`LocalAuthentication.framework`** для високорівневої аутентифікації користувачів без доступу до біометричних даних. - **`Security.framework`** для доступу до сервісів keychain нижчого рівня, що забезпечує захист секретних даних за допомогою біометричної аутентифікації. Різні [open-source обгортки](https://www.raywenderlich.com/147308/secure-ios-user-data-keychain-touch-id) спрощують доступ до keychain. > [!CAUTION] > Однак, як `LocalAuthentication.framework`, так і `Security.framework` мають вразливості, оскільки вони в основному повертають булеві значення без передачі даних для процесів аутентифікації, що робить їх вразливими до обходу (див. [Don't touch me that way, by David Lindner et al](https://www.youtube.com/watch?v=XhXIHVGCFFM)). ### Реалізація локальної аутентифікації Щоб запитати користувачів про аутентифікацію, розробники повинні використовувати метод **`evaluatePolicy`** у класі **`LAContext`**, вибираючи між: - **`deviceOwnerAuthentication`**: Запитує Touch ID або код доступу до пристрою, не вдаючись, якщо жоден з них не активовано. - **`deviceOwnerAuthenticationWithBiometrics`**: Виключно запитує Touch ID. Успішна аутентифікація вказується булевим значенням, повернутим з **`evaluatePolicy`**, що підкреслює потенційний недолік безпеки. ### Локальна аутентифікація за допомогою Keychain Реалізація **локальної аутентифікації** в iOS-додатках передбачає використання **keychain API** для безпечного зберігання секретних даних, таких як токени аутентифікації. Цей процес забезпечує доступ до даних лише для користувача, використовуючи їх код доступу до пристрою або біометричну аутентифікацію, таку як Touch ID. Keychain пропонує можливість встановлювати елементи з атрибутом `SecAccessControl`, який обмежує доступ до елемента, поки користувач успішно не аутентифікується через Touch ID або код доступу до пристрою. Ця функція є важливою для підвищення безпеки. Нижче наведено приклади коду на Swift та Objective-C, які демонструють, як зберігати та отримувати рядок з keychain, використовуючи ці функції безпеки. Приклади конкретно показують, як налаштувати контроль доступу, щоб вимагати аутентифікацію Touch ID та забезпечити доступність даних лише на пристрої, на якому вони були налаштовані, за умови, що код доступу до пристрою налаштовано. {{#tabs}} {{#tab name="Swift"}} ```swift // From https://github.com/mufambisi/owasp-mstg/blob/master/Document/0x06f-Testing-Local-Authentication.md // 1. create AccessControl object that will represent authentication settings var error: Unmanaged? guard let accessControl = SecAccessControlCreateWithFlags(kCFAllocatorDefault, kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly, SecAccessControlCreateFlags.biometryCurrentSet, &error) else { // failed to create AccessControl object return } // 2. define keychain services query. Pay attention that kSecAttrAccessControl is mutually exclusive with kSecAttrAccessible attribute var query: [String: Any] = [:] query[kSecClass as String] = kSecClassGenericPassword query[kSecAttrLabel as String] = "com.me.myapp.password" as CFString query[kSecAttrAccount as String] = "OWASP Account" as CFString query[kSecValueData as String] = "test_strong_password".data(using: .utf8)! as CFData query[kSecAttrAccessControl as String] = accessControl // 3. save item let status = SecItemAdd(query as CFDictionary, nil) if status == noErr { // successfully saved } else { // error while saving } ``` {{#endtab}} {{#tab name="Objective-C"}} ```objectivec // 1. create AccessControl object that will represent authentication settings CFErrorRef *err = nil; SecAccessControlRef sacRef = SecAccessControlCreateWithFlags(kCFAllocatorDefault, kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly, kSecAccessControlUserPresence, err); // 2. define keychain services query. Pay attention that kSecAttrAccessControl is mutually exclusive with kSecAttrAccessible attribute NSDictionary* query = @{ (_ _bridge id)kSecClass: (__bridge id)kSecClassGenericPassword, (__bridge id)kSecAttrLabel: @"com.me.myapp.password", (__bridge id)kSecAttrAccount: @"OWASP Account", (__bridge id)kSecValueData: [@"test_strong_password" dataUsingEncoding:NSUTF8StringEncoding], (__bridge id)kSecAttrAccessControl: (__bridge_transfer id)sacRef }; // 3. save item OSStatus status = SecItemAdd((__bridge CFDictionaryRef)query, nil); if (status == noErr) { // successfully saved } else { // error while saving } ``` {{#endtab}} {{#endtabs}} Тепер ми можемо запитати збережений елемент з ключниці. Служби ключниці відобразять діалог аутентифікації для користувача та повернуть дані або nil в залежності від того, чи було надано відповідний відбиток пальця. {{#tabs}} {{#tab name="Swift"}} ```swift // 1. define query var query = [String: Any]() query[kSecClass as String] = kSecClassGenericPassword query[kSecReturnData as String] = kCFBooleanTrue query[kSecAttrAccount as String] = "My Name" as CFString query[kSecAttrLabel as String] = "com.me.myapp.password" as CFString query[kSecUseOperationPrompt as String] = "Please, pass authorisation to enter this area" as CFString // 2. get item var queryResult: AnyObject? let status = withUnsafeMutablePointer(to: &queryResult) { SecItemCopyMatching(query as CFDictionary, UnsafeMutablePointer($0)) } if status == noErr { let password = String(data: queryResult as! Data, encoding: .utf8)! // successfully received password } else { // authorization not passed } ``` {{#endtab}} {{#tab name="Objective-C"}} ```objectivec // 1. define query NSDictionary *query = @{(__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword, (__bridge id)kSecReturnData: @YES, (__bridge id)kSecAttrAccount: @"My Name1", (__bridge id)kSecAttrLabel: @"com.me.myapp.password", (__bridge id)kSecUseOperationPrompt: @"Please, pass authorisation to enter this area" }; // 2. get item CFTypeRef queryResult = NULL; OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &queryResult); if (status == noErr){ NSData* resultData = ( __bridge_transfer NSData* )queryResult; NSString* password = [[NSString alloc] initWithData:resultData encoding:NSUTF8StringEncoding]; NSLog(@"%@", password); } else { NSLog(@"Something went wrong"); } ``` {{#endtab}} {{#endtabs}} ### Виявлення Використання фреймворків в додатку також можна виявити, аналізуючи список спільних динамічних бібліотек бінарного файлу додатку. Це можна зробити за допомогою `otool`: ```bash $ otool -L .app/ ``` Якщо в додатку використовується `LocalAuthentication.framework`, вихід міститиме обидві наступні рядки (пам'ятайте, що `LocalAuthentication.framework` використовує `Security.framework` під капотом): ```bash /System/Library/Frameworks/LocalAuthentication.framework/LocalAuthentication /System/Library/Frameworks/Security.framework/Security ``` Якщо використовується `Security.framework`, буде показано лише другий варіант. ### Обхід локальної аутентифікації #### **Objection** Через **Objection Biometrics Bypass**, розташований на [цій сторінці GitHub](https://github.com/sensepost/objection/wiki/Understanding-the-iOS-Biometrics-Bypass), доступна техніка для подолання механізму **LocalAuthentication**. Суть цього підходу полягає в використанні **Frida** для маніпуляції функцією `evaluatePolicy`, що забезпечує постійний результат `True`, незалежно від фактичного успіху аутентифікації. Це особливо корисно для обходу ненадійних процесів біометричної аутентифікації. Для активації цього обходу використовується наступна команда: ```bash ...itudehacks.DVIAswiftv2.develop on (iPhone: 13.2.3) [usb] # ios ui biometrics_bypass (agent) Registering job 3mhtws9x47q. Type: ios-biometrics-disable ...itudehacks.DVIAswiftv2.develop on (iPhone: 13.2.3) [usb] # (agent) [3mhtws9x47q] Localized Reason for auth requirement: Please authenticate yourself (agent) [3mhtws9x47q] OS authentication response: false (agent) [3mhtws9x47q] Marking OS response as True instead (agent) [3mhtws9x47q] Biometrics bypass hook complete ``` Ця команда запускає послідовність, в якій Objection реєструє завдання, що ефективно змінює результат перевірки `evaluatePolicy` на `True`. #### Frida Приклад використання **`evaluatePolicy`** з [DVIA-v2 application](https://github.com/prateek147/DVIA-v2): ```swift +(void)authenticateWithTouchID { LAContext *myContext = [[LAContext alloc] init]; NSError *authError = nil; NSString *myLocalizedReasonString = @"Please authenticate yourself"; if ([myContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&authError]) { [myContext evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics localizedReason:myLocalizedReasonString reply:^(BOOL success, NSError *error) { if (success) { dispatch_async(dispatch_get_main_queue(), ^{ [TouchIDAuthentication showAlert:@"Authentication Successful" withTitle:@"Success"]; }); } else { dispatch_async(dispatch_get_main_queue(), ^{ [TouchIDAuthentication showAlert:@"Authentication Failed !" withTitle:@"Error"]; }); } }]; } else { dispatch_async(dispatch_get_main_queue(), ^{ [TouchIDAuthentication showAlert:@"Your device doesn't support Touch ID or you haven't configured Touch ID authentication on your device" withTitle:@"Error"]; }); } } ``` Щоб досягти **bypass** локальної аутентифікації, написано скрипт Frida. Цей скрипт націлений на перевірку **evaluatePolicy**, перехоплюючи її зворотний виклик, щоб забезпечити повернення **success=1**. Змінюючи поведінку зворотного виклику, перевірка аутентифікації ефективно обходиться. Скрипт нижче інжектується для зміни результату методу **evaluatePolicy**. Він змінює результат зворотного виклику, щоб завжди вказувати на успіх. ```swift // from https://securitycafe.ro/2022/09/05/mobile-pentesting-101-bypassing-biometric-authentication/ if(ObjC.available) { console.log("Injecting..."); var hook = ObjC.classes.LAContext["- evaluatePolicy:localizedReason:reply:"]; Interceptor.attach(hook.implementation, { onEnter: function(args) { var block = new ObjC.Block(args[4]); const callback = block.implementation; block.implementation = function (error, value) { console.log("Changing the result value to true") const result = callback(1, null); return result; }; }, }); } else { console.log("Objective-C Runtime is not available!"); } ``` Щоб впровадити скрипт Frida та обійти біометричну аутентифікацію, використовується наступна команда: ```bash frida -U -f com.highaltitudehacks.DVIAswiftv2 --no-pause -l fingerprint-bypass-ios.js ``` ## Витік чутливої функціональності через IPC ### Користувацькі обробники URI / Deeplinks / Користувацькі схеми {{#ref}} ios-custom-uri-handlers-deeplinks-custom-schemes.md {{#endref}} ### Універсальні посилання {{#ref}} ios-universal-links.md {{#endref}} ### Спільний доступ UIActivity {{#ref}} ios-uiactivity-sharing.md {{#endref}} ### UIPasteboard {{#ref}} ios-uipasteboard.md {{#endref}} ### Розширення додатків {{#ref}} ios-app-extensions.md {{#endref}} ### WebViews {{#ref}} ios-webviews.md {{#endref}} ### Серіалізація та кодування {{#ref}} ios-serialisation-and-encoding.md {{#endref}} ## Мережева комунікація Важливо перевірити, що жодна комунікація не відбувається **без шифрування** і що додаток правильно **перевіряє TLS сертифікат** сервера.\ Щоб перевірити ці проблеми, ви можете використовувати проксі, наприклад, **Burp**: {{#ref}} burp-configuration-for-ios.md {{#endref}} ### Перевірка імені хоста Однією з поширених проблем при перевірці TLS сертифіката є перевірка, що сертифікат був підписаний **достовірним** **ЦС**, але **не перевіряється**, чи **ім'я хоста** сертифіката є іменем хоста, до якого звертаються.\ Щоб перевірити цю проблему за допомогою Burp, після довірення CA Burp на iPhone, ви можете **створити новий сертифікат з Burp для іншого імені хоста** і використовувати його. Якщо додаток все ще працює, то щось вразливе. ### Прив'язка сертифіката Якщо додаток правильно використовує SSL Pinning, то він буде працювати лише якщо сертифікат є тим, що очікується. При тестуванні додатка **це може бути проблемою, оскільки Burp буде надавати свій власний сертифікат.**\ Щоб обійти цю захист на джейлбрейкнутому пристрої, ви можете встановити додаток [**SSL Kill Switch**](https://github.com/nabla-c0d3/ssl-kill-switch2) або встановити [**Burp Mobile Assistant**](https://portswigger.net/burp/documentation/desktop/mobile/config-ios-device) Ви також можете використовувати **objection's** `ios sslpinning disable` ## Різне - У **`/System/Library`** ви можете знайти фреймворки, встановлені на телефоні, які використовуються системними додатками - Додатки, встановлені користувачем з App Store, розташовані в **`/User/Applications`** - А **`/User/Library`** містить дані, збережені додатками на рівні користувача - Ви можете отримати доступ до **`/User/Library/Notes/notes.sqlite`**, щоб прочитати нотатки, збережені в додатку. - У папці встановленого додатку (**`/User/Applications//`**) ви можете знайти деякі цікаві файли: - **`iTunesArtwork`**: Іконка, що використовується додатком - **`iTunesMetadata.plist`**: Інформація про додаток, що використовується в App Store - **`/Library/*`**: Містить налаштування та кеш. У **`/Library/Cache/Snapshots/*`** ви можете знайти знімок, виконаний для додатку перед його відправленням у фоновий режим. ### Гаряче патчування/Примусове оновлення Розробники можуть віддалено **поправити всі установки свого додатку миттєво** без необхідності повторно подавати додаток до App Store і чекати, поки його затвердять.\ Для цієї мети зазвичай використовують [**JSPatch**](https://github.com/bang590/JSPatch)**.** Але також є інші варіанти, такі як [Siren](https://github.com/ArtSabintsev/Siren) та [react-native-appstore-version-checker](https://www.npmjs.com/package/react-native-appstore-version-checker).\ **Це небезпечний механізм, який може бути зловжито зловмисними сторонніми SDK, тому рекомендується перевірити, який метод використовується для автоматичного оновлення (якщо є) і протестувати його.** Ви можете спробувати завантажити попередню версію додатку для цієї мети. ### Сторонні програми Суттєвим викликом з **3rd party SDKs** є **відсутність детального контролю** над їх функціональністю. Розробники стикаються з вибором: або інтегрувати SDK і прийняти всі його функції, включаючи потенційні вразливості безпеки та проблеми з конфіденційністю, або зовсім відмовитися від його переваг. Часто розробники не можуть самостійно виправити вразливості в цих SDK. Більше того, оскільки SDK отримують довіру в спільноті, деякі з них можуть почати містити шкідливе ПЗ. Послуги, що надаються сторонніми SDK, можуть включати відстеження поведінки користувачів, показ реклами або покращення користувацького досвіду. Однак це створює ризик, оскільки розробники можуть не повністю усвідомлювати код, виконуваний цими бібліотеками, що призводить до потенційних ризиків конфіденційності та безпеки. Важливо обмежити інформацію, що передається стороннім службам, до необхідного та забезпечити, щоб жодні чутливі дані не були розкриті. Впровадження сторонніх послуг зазвичай відбувається у двох формах: окрема бібліотека або повний SDK. Щоб захистити конфіденційність користувача, будь-які дані, що передаються цим службам, повинні бути **анонімізовані**, щоб запобігти розкриттю особистої ідентифікаційної інформації (PII). Щоб визначити бібліотеки, які використовує додаток, можна використовувати команду **`otool`**. Цей інструмент слід запустити проти додатку та кожної спільної бібліотеки, яку він використовує, щоб виявити додаткові бібліотеки. ```bash otool -L ``` ## Цікаві вразливості та випадки {{#ref}} air-keyboard-remote-input-injection.md {{#endref}} ## **Посилання та додаткові ресурси** - [https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06b-basic-security-testing#information-gathering](https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06b-basic-security-testing#information-gathering) - [iOS & Mobile App Pentesting - INE](https://my.ine.com/CyberSecurity/courses/089d060b/ios-mobile-app-pentesting) - [https://mas.owasp.org/MASTG/techniques/ios/MASTG-TECH-0057/](https://mas.owasp.org/MASTG/techniques/ios/MASTG-TECH-0057/) - [https://mas.owasp.org/MASTG/techniques/ios/MASTG-TECH-0058/](https://mas.owasp.org/MASTG/techniques/ios/MASTG-TECH-0058/) - [https://mas.owasp.org/MASTG/techniques/ios/MASTG-TECH-0059/](https://mas.owasp.org/MASTG/techniques/ios/MASTG-TECH-0059/) - [https://mas.owasp.org/MASTG/iOS/0x06d-Testing-Data-Storage](https://mas.owasp.org/MASTG/iOS/0x06d-Testing-Data-Storage) - [https://coderwall.com/p/kjb3lw/storing-password-in-keychain-the-smart-way](https://coderwall.com/p/kjb3lw/storing-password-in-keychain-the-smart-way) - [https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0055/](https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0055/) - [https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0053](https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0053) - [https://mas.owasp.org/MASTG/techniques/ios/MASTG-TECH-0060/](https://mas.owasp.org/MASTG/techniques/ios/MASTG-TECH-0060/) - [https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0058](https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0058) - [https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0060](https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0060) - [https://mas.owasp.org/MASTG/Android/0x05f-Testing-Local-Authentication/](https://mas.owasp.org/MASTG/Android/0x05f-Testing-Local-Authentication/) - [https://mas.owasp.org/MASTG/tests/ios/MASVS-AUTH/MASTG-TEST-0064](https://mas.owasp.org/MASTG/tests/ios/MASVS-AUTH/MASTG-TEST-0064) - [https://medium.com/securing/bypassing-your-apps-biometric-checks-on-ios-c2555c81a2dc](https://medium.com/securing/bypassing-your-apps-biometric-checks-on-ios-c2555c81a2dc) - [https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0054](https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0054) - [https://github.com/ivRodriguezCA/RE-iOS-Apps/](https://github.com/ivRodriguezCA/RE-iOS-Apps/) IOS безкоштовний курс([https://syrion.me/blog/ios-swift-antijailbreak-bypass-frida/](https://syrion.me/blog/ios-swift-antijailbreak-bypass-frida/)) - [https://www.sans.org/reading-room/whitepapers/testing/ipwn-apps-pentesting-ios-applications-34577](https://www.sans.org/reading-room/whitepapers/testing/ipwn-apps-pentesting-ios-applications-34577) - [https://www.slideshare.net/RyanISI/ios-appsecurityminicourse](https://www.slideshare.net/RyanISI/ios-appsecurityminicourse) - [https://github.com/prateek147/DVIA](https://github.com/prateek147/DVIA) - [https://github.com/prateek147/DVIA-v2](https://github.com/prateek147/DVIA-v2) - [https://github.com/OWASP/MSTG-Hacking-Playground%20](https://github.com/OWASP/MSTG-Hacking-Playground) - OWASP iGoat [_https://github.com/OWASP/igoat_](https://github.com/OWASP/igoat) <<< версія Objective-C [_https://github.com/OWASP/iGoat-Swift_](https://github.com/OWASP/iGoat-Swift) <<< версія Swift - [https://github.com/authenticationfailure/WheresMyBrowser.iOS](https://github.com/authenticationfailure/WheresMyBrowser.iOS) - [https://github.com/nabla-c0d3/ssl-kill-switch2](https://github.com/nabla-c0d3/ssl-kill-switch2) {{#include ../../banners/hacktricks-training.md}}