daemon-sec-cheatsheet

The cheatsheet vault for operators: AD, enumeration, exploitation, priv-esc, web, DFIR
git clone https://git.daemon-sec.xyz/daemon-sec-cheatsheet.git
Log | Files | Refs | README | LICENSE

overview.md (66895B)


      1 ---
      2 title: "iOS Pentesting"
      3 section: "Mobile"
      4 sectionSlug: "mobile-pentesting"
      5 sourcePath: "src/mobile-pentesting/ios-pentesting/README.md"
      6 sourceUrl: "https://github.com/HackTricks-wiki/hacktricks/blob/188de82beb54e70956b2952367a0af91d26758b8/src/mobile-pentesting/ios-pentesting/README.md"
      7 sha: "188de82beb54e70956b2952367a0af91d26758b8"
      8 isIndex: true
      9 modified: true
     10 license: "CC-BY-NC-4.0"
     11 ---
     12 
     13 # iOS Pentesting
     14 
     15 ## iOS Basics
     16 
     17 
     18 [Ios Basics](/hacktricks/mobile-pentesting/ios-pentesting/ios-basics)
     19 
     20 ## Testing Environment
     21 
     22 In this page you can find information about the **iOS simulator**, **emulators** and **jailbreaking:**
     23 
     24 
     25 [Ios Testing Environment](/hacktricks/mobile-pentesting/ios-pentesting/ios-testing-environment)
     26 
     27 For structured practice, useful training material includes the INE iOS course, RE:iOS Apps, the *iPwn Apps* paper, and an introductory iOS application-security course.<sup>[[3]](#references)[[17]](#references)[[19]](#references)[[20]](#references)</sup> Deliberately vulnerable targets include DVIA/DVIA-v2, the OWASP MSTG Hacking Playground, iGoat, and WheresMyBrowser.iOS; they provide concrete binaries and source code for reproducing the techniques described below.<sup>[[21]](#references)[[22]](#references)[[23]](#references)[[24]](#references)[[26]](#references)</sup>
     28 
     29 ## Initial Analysis
     30 
     31 ### Basic iOS Testing Operations
     32 
     33 During the testing **several operations are going to be suggested** (connect to the device, read/write/upload/download files, use some tools...). Therefore, if you don't know how to perform any of these actions please, **start reading the page**:
     34 
     35 
     36 [Basic Ios Testing Operations](/hacktricks/mobile-pentesting/ios-pentesting/basic-ios-testing-operations)
     37 
     38 > [!TIP]
     39 > For the following steps **the app should be installed** in the device and should have already obtained the **IPA file** of the application.\
     40 > Read the [Basic iOS Testing Operations](/hacktricks/mobile-pentesting/ios-pentesting/basic-ios-testing-operations) page to learn how to do this.
     41 
     42 ### Basic Static Analysis
     43 
     44 Some interesting iOS - IPA files decompilers:
     45 
     46 - [https://github.com/LaurieWired/Malimite](https://github.com/LaurieWired/Malimite)
     47 - [https://ghidra-sre.org/](https://ghidra-sre.org/)
     48 
     49 It's recommended to use the tool [**MobSF**](https://github.com/MobSF/Mobile-Security-Framework-MobSF) to perform an automatic Static Analysis to the IPA file.
     50 
     51 Identification of **protections are present in the binary**:
     52 
     53 - **PIE (Position Independent Executable)**: When enabled, the application loads into a random memory address every-time it launches, making it harder to predict its initial memory address.
     54 
     55   ```bash
     56   otool -hv <app-binary> | grep PIE   # It should include the PIE flag
     57   ```
     58 
     59 - **Stack Canaries**: To validate the integrity of the stack, a ‘canary’ value is placed on the stack before calling a function and is validated again once the function ends.
     60 
     61   ```bash
     62   otool -I -v <app-binary> | grep stack_chk   # It should include the symbols: stack_chk_guard and stack_chk_fail
     63   ```
     64 
     65 - **ARC (Automatic Reference Counting)**: To prevent common memory corruption flaws
     66 
     67   ```bash
     68   otool -I -v <app-binary> | grep objc_release   # It should include the _objc_release symbol
     69   ```
     70 
     71 - **Encrypted Binary**: The binary should be encrypted
     72 
     73   ```bash
     74   otool -arch all -Vl <app-binary> | grep -A5 LC_ENCRYPT   # The cryptid should be 1
     75   ```
     76 
     77 **Identification of Sensitive/Insecure Funcions**
     78 
     79 - **Weak Hashing Algorithms**
     80 
     81   ```bash
     82   # On the iOS device
     83   otool -Iv <app> | grep -w "_CC_MD5"
     84   otool -Iv <app> | grep -w "_CC_SHA1"
     85 
     86   # On linux
     87   grep -iER "_CC_MD5"
     88   grep -iER "_CC_SHA1"
     89   ```
     90 
     91 - **Insecure Random Functions**
     92 
     93   ```bash
     94   # On the iOS device
     95   otool -Iv <app> | grep -w "_random"
     96   otool -Iv <app> | grep -w "_srand"
     97   otool -Iv <app> | grep -w "_rand"
     98 
     99   # On linux
    100   grep -iER "_random"
    101   grep -iER "_srand"
    102   grep -iER "_rand"
    103   ```
    104 
    105 - **Insecure ‘Malloc’ Function**
    106 
    107   ```bash
    108   # On the iOS device
    109   otool -Iv <app> | grep -w "_malloc"
    110 
    111   # On linux
    112   grep -iER "_malloc"
    113   ```
    114 
    115 - **Insecure and Vulnerable Functions**
    116 
    117   ```bash
    118   # On the iOS device
    119   otool -Iv <app> | grep -w "_gets"
    120   otool -Iv <app> | grep -w "_memcpy"
    121   otool -Iv <app> | grep -w "_strncpy"
    122   otool -Iv <app> | grep -w "_strlen"
    123   otool -Iv <app> | grep -w "_vsnprintf"
    124   otool -Iv <app> | grep -w "_sscanf"
    125   otool -Iv <app> | grep -w "_strtok"
    126   otool -Iv <app> | grep -w "_alloca"
    127   otool -Iv <app> | grep -w "_sprintf"
    128   otool -Iv <app> | grep -w "_printf"
    129   otool -Iv <app> | grep -w "_vsprintf"
    130 
    131   # On linux
    132   grep -R "_gets"
    133   grep -iER "_memcpy"
    134   grep -iER "_strncpy"
    135   grep -iER "_strlen"
    136   grep -iER "_vsnprintf"
    137   grep -iER "_sscanf"
    138   grep -iER "_strtok"
    139   grep -iER "_alloca"
    140   grep -iER "_sprintf"
    141   grep -iER "_printf"
    142   grep -iER "_vsprintf"
    143   ```
    144 
    145 #### Common Jailbreak detection methods
    146 
    147 - **File System Checks**: Look for the presence of common jailbreak files and directories, such as `/Applications/Cydia.app` or `/Library/MobileSubstrate/MobileSubstrate.dylib`.<sup>[[18]](#references)[[30]](#references)</sup>
    148 - **Sandbox Violations**: Attempt to access restricted areas of the file system, which should be blocked on non-jailbroken devices.
    149 - **API Checks**: Check if it's possible to use forbidden calls like `fork()` to create a child process or `system()` to see if /bin/sh exists.
    150 - **Process Checks**: Monitor for the presence of known jailbreak-related processes, such as `Cydia`, `Substrate`, or `ssh`.
    151 - **Kernel Exploits**: Check for the presence of kernel exploits that are commonly used in jailbreaks.
    152 - **Environment Variables**: Inspect environment variables for signs of a jailbreak, such as `DYLD_INSERT_LIBRARIES`.
    153 - **Libraries Check**: Check the libs that are loaded into the app process.
    154 - **Check schemes**: Like `canOpenURL(URL(string: "cydia://"))`.
    155 
    156 #### Common Anti-Debugging detection methods
    157 
    158 - **Check for Debugger Presence**: Use `sysctl` or other methods to check if a debugger is attached.
    159 - **Anti-Debugging APIs**: Look for calls to anti-debugging APIs like `ptrace` or `SIGSTOP` like `ptrace(PT_DENY_ATTACH, 0, 0, 0)`.
    160 - **Timing Checks**: Measure the time taken for certain operations and look for discrepancies that may indicate debugging.
    161 - **Memory Checks**: Inspect memory for known debugger artifacts or modifications.
    162 - **Environment Variables**: Check for environment variables that may indicate a debugging session.
    163 - **Mach Ports**: Detect if mach exception ports are being used by debuggers.
    164 
    165 
    166 #### Anti-Debugging & Anti-Tamper Techniques (Layered Checks)
    167 
    168 Real-world apps often layer pre-exec, on-attach, and continuous checks. Common patterns to look for (and how to neutralize them during testing):<sup>[[1]](#references)</sup>
    169 
    170 - **Private API side-channel fingerprinting**: private launch APIs (e.g., `SBSLaunchApplicationWithIdentifierAndURLAndLaunchOptions`) are abused to probe for installed bundle IDs (`com.opa334.TrollStore`, `org.coolstar.SileoStore`, `com.tigisoftware.Filza`, etc.) based on return codes/logging. Hook the call and sanitize arguments/return values to emulate a clean device.
    171 - **Self-attestation via code-signing state**: `csops()` with `CS_OPS_ENTITLEMENTS_BLOB` reads entitlements; unexpected values trigger exit. Pair this with integrity checks (CRC32/MD5 of resources, certificate validation, Mach-O metadata like `LC_ENCRYPTION_INFO_64`) to detect re-signing or patching. Instrument these routines and force "expected" results during analysis.
    172 - **Kill-on-attach**: `ptrace(PT_DENY_ATTACH)` combined with `abort()`/`exit()` on attach. Bypass by neutralizing the termination path or hooking `ptrace` to succeed without enforcing denial.
    173 - **Crash forensics sabotage**: overwrite CPU registers before crashing to destroy backtraces. Prefer breakpoints/hooks earlier in the detection path instead of relying on crash logs.
    174 - **Jetsam-based termination**: deliberate memory pressure to trigger jetsam, which yields no normal crash log. Look for large allocations around detection logic and cap/short-circuit them to keep logs.
    175 - **Continuous checks with delayed enforcement**: heartbeat timers re-run detection and enforce later. Trace timers/dispatch sources and keep the process alive by bypassing the delayed kill path.
    176 
    177 ### Basic Dynamic Analysis
    178 
    179 Check out the dynamic analysis that [**MobSF**](https://github.com/MobSF/Mobile-Security-Framework-MobSF) perform. You will need to navigate through the different views and interact with them but it will be hooking several classes on doing other things and will prepare a report once you are done.
    180 
    181 ### Listing Installed Apps
    182 
    183 Use the command `frida-ps -Uai` to determine the **bundle identifier** of the installed apps:<sup>[[4]](#references)</sup>
    184 
    185 ```bash
    186 $ frida-ps -Uai
    187  PID  Name                 Identifier
    188 ----  -------------------  -----------------------------------------
    189 6847  Calendar             com.apple.mobilecal
    190 6815  Mail                 com.apple.mobilemail
    191    -  App Store            com.apple.AppStore
    192    -  Apple Store          com.apple.store.Jolly
    193    -  Calculator           com.apple.calculator
    194    -  Camera               com.apple.camera
    195    -  iGoat-Swift          OWASP.iGoat-Swift
    196 ```
    197 
    198 ### Basic Enumeration & Hooking
    199 
    200 Learn how to **enumerate the components of the application** and how to easily **hook methods and classes** with objection:
    201 
    202 
    203 [Ios Hooking With Objection](/hacktricks/mobile-pentesting/ios-pentesting/ios-hooking-with-objection)
    204 
    205 ### IPA Structure
    206 
    207 The structure of an **IPA file** is essentially that of a **zipped package**. By renaming its extension to `.zip`, it can be **decompressed** to reveal its contents. Within this structure, a **Bundle** represents a fully packaged application ready for installation. Inside, you will find a directory named `<NAME>.app`, which encapsulates the application's resources.<sup>[[5]](#references)</sup>
    208 
    209 - **`Info.plist`**: This file holds specific configuration details of the application.
    210 - **`_CodeSignature/`**: This directory includes a plist file that contains a signature, ensuring the integrity of all files in the bundle.
    211 - **`Assets.car`**: A compressed archive that stores asset files like icons.
    212 - **`Frameworks/`**: This folder houses the application's native libraries, which may be in the form of `.dylib` or `.framework` files.
    213 - **`PlugIns/`**: This may include extensions to the application, known as `.appex` files, although they are not always present. \* [**`Core Data`**](https://developer.apple.com/documentation/coredata): It is used to save your application’s permanent data for offline use, to cache temporary data, and to add undo functionality to your app on a single device. To sync data across multiple devices in a single iCloud account, Core Data automatically mirrors your schema to a CloudKit container.
    214 - [**`PkgInfo`**](https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPRuntimeConfig/Articles/ConfigApplications.html): The `PkgInfo` file is an alternate way to specify the type and creator codes of your application or bundle.
    215 - **en.lproj, fr.proj, Base.lproj**: Are the language packs that contains resources for those specific languages, and a default resource in case a language isn' t supported.
    216 - **Security**: The `_CodeSignature/` directory plays a critical role in the app's security by verifying the integrity of all bundled files through digital signatures.
    217 - **Asset Management**: The `Assets.car` file uses compression to efficiently manage graphical assets, crucial for optimizing application performance and reducing its overall size.
    218 - **Frameworks and PlugIns**: These directories underscore the modularity of iOS applications, allowing developers to include reusable code libraries (`Frameworks/`) and extend app functionality (`PlugIns/`).
    219 - **Localization**: The structure supports multiple languages, facilitating global application reach by including resources for specific language packs.
    220 
    221 **Info.plist**
    222 
    223 The **Info.plist** serves as a cornerstone for iOS applications, encapsulating key configuration data in the form of **key-value** pairs. This file is a requisite for not only applications but also for app extensions and frameworks bundled within. It's structured in either XML or a binary format and holds critical information ranging from app permissions to security configurations. For a detailed exploration of available keys, one can refer to the [**Apple Developer Documentation**](https://developer.apple.com/documentation/bundleresources/information_property_list?language=objc).
    224 
    225 For those looking to work with this file in a more accessible format, the XML conversion can be achieved effortlessly through the use of `plutil` on macOS (available natively on versions 10.2 and later) or `plistutil` on Linux. The commands for conversion are as follows:
    226 
    227 - **For macOS**:
    228 
    229 ```bash
    230 $ plutil -convert xml1 Info.plist
    231 ```
    232 
    233 - **For Linux**:
    234 
    235 ```bash
    236 $ apt install libplist-utils
    237 $ plistutil -i Info.plist -o Info_xml.plist
    238 ```
    239 
    240 Among the myriad of information that the **Info.plist** file can divulge, notable entries include app permission strings (`UsageDescription`), custom URL schemes (`CFBundleURLTypes`), and configurations for App Transport Security (`NSAppTransportSecurity`). These entries, along with others like exported/imported custom document types (`UTExportedTypeDeclarations` / `UTImportedTypeDeclarations`), can be effortlessly located by inspecting the file or employing a simple `grep` command:
    241 
    242 ```bash
    243 $ grep -i <keyword> Info.plist
    244 ```
    245 
    246 **Data Paths**
    247 
    248 In the iOS environment, directories are designated specifically for **system applications** and **user-installed applications**. System applications reside in the `/Applications` directory, while user-installed apps are placed under `/var/mobile/containers/Data/Application/`. These applications are assigned a unique identifier known as a **128-bit UUID**, making the task of manually locating an app's folder challenging due to the randomness of the directory names.<sup>[[6]](#references)</sup>
    249 
    250 > [!WARNING]
    251 > As applications in iOS must be sandboxed, each app will have also a folder inside **`$HOME/Library/Containers`** with app's **`CFBundleIdentifier`** as the folder name.
    252 >
    253 > However, both folders (data & container folders) have the file **`.com.apple.mobile_container_manager.metadata.plist`** that links both files in the key `MCMetadataIdentifier`).
    254 
    255 To facilitate the discovery of a user-installed app's installation directory, the **objection tool** provides a useful command, `env`. This command reveals detailed directory information for the app in question. Below is an example of how to use this command:
    256 
    257 ```bash
    258 OWASP.iGoat-Swift on (iPhone: 11.1.2) [usb] # env
    259 
    260 Name               Path
    261 -----------------  -------------------------------------------------------------------------------------------
    262 BundlePath         /var/containers/Bundle/Application/3ADAF47D-A734-49FA-B274-FBCA66589E67/iGoat-Swift.app
    263 CachesDirectory    /var/mobile/Containers/Data/Application/8C8E7EB0-BC9B-435B-8EF8-8F5560EB0693/Library/Caches
    264 DocumentDirectory  /var/mobile/Containers/Data/Application/8C8E7EB0-BC9B-435B-8EF8-8F5560EB0693/Documents
    265 LibraryDirectory   /var/mobile/Containers/Data/Application/8C8E7EB0-BC9B-435B-8EF8-8F5560EB0693/Library
    266 ```
    267 
    268 Alternatively, the app name can be searched within the `/private/var/containers` using the `find` command:
    269 
    270 ```bash
    271 find /private/var/containers -name "Progname*"
    272 ```
    273 
    274 Commands such as `ps` and `lsof` can also be utilized to identify the app's process and list open files, respectively, providing insights into the application's active directory paths:
    275 
    276 ```bash
    277 ps -ef | grep -i <app-name>
    278 lsof -p <pid> | grep -i "/containers" | head -n 1
    279 ```
    280 
    281 **Bundle directory:**
    282 
    283 - **AppName.app**
    284   - This is the Application Bundle as seen before in the IPA, it contains essential application data, static content as well as the application's compiled binary.
    285   - This directory is visible to users, but **users can't write to it**.
    286   - Content in this directory is **not backed up**.
    287   - The contents of this folder are used to **validate the code signature**.
    288 
    289 **Data directory:**
    290 
    291 - **Documents/**
    292   - Contains all the user-generated data. The application end user initiates the creation of this data.
    293   - Visible to users and **users can write to it**.
    294   - Content in this directory is **backed up**.
    295   - The app can disable paths by setting `NSURLIsExcludedFromBackupKey`.
    296 - **Library/**
    297   - Contains all **files that aren't user-specific**, such as **caches**, **preferences**, **cookies**, and property list (plist) configuration files.
    298   - iOS apps usually use the `Application Support` and `Caches` subdirectories, but the app can create custom subdirectories.
    299 - **Library/Caches/**
    300   - Contains **semi-persistent cached files.**
    301   - Invisible to users and **users can't write to it**.
    302   - Content in this directory is **not backed up**.
    303   - The OS may delete this directory's files automatically when the app is not running and storage space is running low.
    304 - **Library/Application Support/**
    305   - Contains **persistent** **files** necessary for running the app.
    306   - **Invisible** **to** **users** and users can't write to it.
    307   - Content in this directory is **backed** **up**.
    308   - The app can disable paths by setting `NSURLIsExcludedFromBackupKey`.
    309 - **Library/Preferences/**
    310   - Used for storing properties that can **persist even after an application is restarted**.
    311   - Information is saved, unencrypted, inside the application sandbox in a plist file called \[BUNDLE_ID].plist.
    312   - All the key/value pairs stored using `NSUserDefaults` can be found in this file.
    313 - **tmp/**
    314   - Use this directory to write **temporary files** that do not need to persist between app launches.
    315   - Contains non-persistent cached files.
    316   - **Invisible** to users.
    317   - Content in this directory is not backed up.
    318   - The OS may delete this directory's files automatically when the app is not running and storage space is running low.
    319 
    320 Let's take a closer look at iGoat-Swift's Application Bundle (.app) directory inside the Bundle directory (`/var/containers/Bundle/Application/3ADAF47D-A734-49FA-B274-FBCA66589E67/iGoat-Swift.app`):<sup>[[25]](#references)</sup>
    321 
    322 ```bash
    323 OWASP.iGoat-Swift on (iPhone: 11.1.2) [usb] # ls
    324 NSFileType      Perms  NSFileProtection    ...  Name
    325 ------------  -------  ------------------  ...  --------------------------------------
    326 Regular           420  None                ...  rutger.html
    327 Regular           420  None                ...  mansi.html
    328 Regular           420  None                ...  splash.html
    329 Regular           420  None                ...  about.html
    330 
    331 Regular           420  None                ...  LICENSE.txt
    332 Regular           420  None                ...  Sentinel.txt
    333 Regular           420  None                ...  README.txt
    334 ```
    335 
    336 ### Binary Reversing
    337 
    338 Inside the `<application-name>.app` folder you will find a binary file called `<application-name>`. This is the file that will be **executed**. You can perform a basic inspection of the binary with the tool **`otool`**:
    339 
    340 ```bash
    341 otool -Vh DVIA-v2 #Check some compilation attributes
    342       magic  cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
    343 MH_MAGIC_64    ARM64        ALL  0x00     EXECUTE    65       7112   NOUNDEFS DYLDLINK TWOLEVEL WEAK_DEFINES BINDS_TO_WEAK PIE
    344 
    345 otool -L DVIA-v2 #Get third party libraries
    346 DVIA-v2:
    347     /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.1)
    348     /usr/lib/libsqlite3.dylib (compatibility version 9.0.0, current version 274.6.0)
    349     /usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.11)
    350     @rpath/Bolts.framework/Bolts (compatibility version 1.0.0, current version 1.0.0)
    351 [...]
    352 ```
    353 
    354 **Check if the app is encrypted**
    355 
    356 See if there is any output for:
    357 
    358 ```bash
    359 otool -l <app-binary> | grep -A 4 LC_ENCRYPTION_INFO
    360 ```
    361 
    362 **Disassembling the binary**
    363 
    364 Disassemble the text section:
    365 
    366 ```bash
    367 otool -tV DVIA-v2
    368 DVIA-v2:
    369 (__TEXT,__text) section
    370 +[DDLog initialize]:
    371 0000000100004ab8    sub    sp, sp, #0x60
    372 0000000100004abc    stp    x29, x30, [sp, #0x50]   ; Latency: 6
    373 0000000100004ac0    add    x29, sp, #0x50
    374 0000000100004ac4    sub    x8, x29, #0x10
    375 0000000100004ac8    mov    x9, #0x0
    376 0000000100004acc    adrp    x10, 1098 ; 0x10044e000
    377 0000000100004ad0    add    x10, x10, #0x268
    378 ```
    379 
    380 To print the **Objective-C segment** of the sample application one can use:
    381 
    382 ```bash
    383 otool -oV DVIA-v2
    384 DVIA-v2:
    385 Contents of (__DATA,__objc_classlist) section
    386 00000001003dd5b8 0x1004423d0 _OBJC_CLASS_$_DDLog
    387     isa        0x1004423a8 _OBJC_METACLASS_$_DDLog
    388     superclass 0x0 _OBJC_CLASS_$_NSObject
    389     cache      0x0 __objc_empty_cache
    390     vtable     0x0
    391     data       0x1003de748
    392         flags          0x80
    393         instanceStart  8
    394 ```
    395 
    396 In order to obtain a more compact Objective-C code you can use [**class-dump**](http://stevenygard.com/projects/class-dump/):
    397 
    398 ```bash
    399 class-dump some-app
    400 //
    401 //     Generated by class-dump 3.5 (64 bit).
    402 //
    403 //     class-dump is Copyright (C) 1997-1998, 2000-2001, 2004-2013 by Steve Nygard.
    404 //
    405 
    406 #pragma mark Named Structures
    407 
    408 struct CGPoint {
    409     double _field1;
    410     double _field2;
    411 };
    412 
    413 struct CGRect {
    414     struct CGPoint _field1;
    415     struct CGSize _field2;
    416 };
    417 
    418 struct CGSize {
    419     double _field1;
    420     double _field2;
    421 };
    422 ```
    423 
    424 However, the best options to disassemble the binary are: [**Hopper**](https://www.hopperapp.com/download.html?) and [**IDA**](https://www.hex-rays.com/products/ida/support/download_freeware/).
    425 
    426 ## Data Storage
    427 
    428 To learn about how iOS stores data in the device read this page:
    429 
    430 
    431 [Ios Basics](/hacktricks/mobile-pentesting/ios-pentesting/ios-basics)
    432 
    433 > [!WARNING]
    434 > The following places to store information should be checked **right after installing the application**, **after checking all the functionalities** of the application and even after **login out from one user and login into a different one**.\
    435 > The goal is to find **unprotected sensitive information** of the application (passwords, tokens), of the current user and of previously logged users.
    436 
    437 ### Plist
    438 
    439 **plist** files are structured XML files that **contains key-value pairs**. It's a way to store persistent data, so sometimes you may find **sensitive information in these files**. It's recommended to check these files after installing the app and after using intensively it to see if new data is written.
    440 
    441 The most common way to persist data in plist files is through the usage of **NSUserDefaults**. This plist file is saved inside the app sandbox in **`Library/Preferences/<appBundleID>.plist`**
    442 
    443 The [`NSUserDefaults`](https://developer.apple.com/documentation/foundation/nsuserdefaults) class provides a programmatic interface for interacting with the default system. The default system allows an application to customize its behaviour according to **user preferences**. Data saved by `NSUserDefaults` can be viewed in the application bundle. This class stores **data** in a **plist** **file**, but it's meant to be used with small amounts of data.<sup>[[7]](#references)</sup>
    444 
    445 This data cannot be longer accessed directly via a trusted computer, but can be accessed performing a **backup**.
    446 
    447 You can **dump** the information saved using **`NSUserDefaults`** using objection's `ios nsuserdefaults get`
    448 
    449 To find all the plist of used by the application you can access to `/private/var/mobile/Containers/Data/Application/{APPID}` and run:
    450 
    451 ```bash
    452 find ./ -name "*.plist"
    453 ```
    454 
    455 To convert files from **XML or binary (bplist)** format to XML, various methods depending on your operating system are available:
    456 
    457 **For macOS Users:** Utilize the `plutil` command. It's a built-in tool in macOS (10.2+), designed for this purpose:
    458 
    459 ```bash
    460 $ plutil -convert xml1 Info.plist
    461 ```
    462 
    463 **For Linux Users:** Install `libplist-utils` first, then use `plistutil` to convert your file:
    464 
    465 ```bash
    466 $ apt install libplist-utils
    467 $ plistutil -i Info.plist -o Info_xml.plist
    468 ```
    469 
    470 **Within an Objection Session:** For analyzing mobile applications, a specific command allows you to convert plist files directly:
    471 
    472 ```bash
    473 ios plist cat /private/var/mobile/Containers/Data/Application/<Application-UUID>/Library/Preferences/com.some.package.app.plist
    474 ```
    475 
    476 ### Core Data
    477 
    478 [`Core Data`](https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CoreData/nsfetchedresultscontroller.html#//apple_ref/doc/uid/TP40001075-CH8-SW1) is a framework for managing the model layer of objects in your application. [Core Data can use SQLite as its persistent store](https://cocoacasts.com/what-is-the-difference-between-core-data-and-sqlite/), but the framework itself is not a database.\
    479 Core Data does not encrypt its data by default. However, an additional encryption layer can be added. See the [encrypted-core-data repository](https://github.com/project-imas/encrypted-core-data) for an example.
    480 
    481 You can find the SQLite Core Data information of an application in the path `/private/var/mobile/Containers/Data/Application/{APPID}/Library/Application Support`
    482 
    483 **If you can open the SQLite and access sensitive information, then you found a miss-configuration.**
    484 
    485 ```text
    486 -(void)storeDetails {
    487     AppDelegate * appDelegate = (AppDelegate *)(UIApplication.sharedApplication.delegate);
    488 
    489     NSManagedObjectContext *context =[appDelegate managedObjectContext];
    490 
    491     User *user = [self fetchUser];
    492     if (user) {
    493         return;
    494     }
    495     user = [NSEntityDescription insertNewObjectForEntityForName:@"User"
    496                                                   inManagedObjectContext:context];
    497     user.email = CoreDataEmail;
    498     user.password = CoreDataPassword;
    499     NSError *error;
    500     if (![context save:&error]) {
    501         NSLog(@"Error in saving data: %@", [error localizedDescription]);
    502 
    503     }else{
    504         NSLog(@"data stored in core data");
    505     }
    506 }
    507 ```
    508 
    509 ### YapDatabase
    510 
    511 [YapDatabase](https://github.com/yapstudios/YapDatabase) is a key/value store built on top of SQLite.\
    512 As the Yap databases are sqlite databases you can find them using the purposed commend in the previous section.
    513 
    514 ### Other SQLite Databases
    515 
    516 It's common for applications to create their own sqlite database. They may be **storing** **sensitive** **data** on them and leaving it unencrypted. Therefore, it's always interesting to check every database inside the applications directory. Therefore go to the application directory where the data is saved (`/private/var/mobile/Containers/Data/Application/{APPID}`)
    517 
    518 ```bash
    519 find ./ -name "*.sqlite" -or -name "*.db"
    520 ```
    521 
    522 ### Firebase Real-Time Databases
    523 
    524 Developers are enabled to **store and sync data** within a **NoSQL cloud-hosted database** through Firebase Real-Time Databases. Stored in JSON format, the data gets synchronized to all connected clients in real time.
    525 
    526 You can find how to check for misconfigured Firebase databases here:
    527 
    528 
    529 [Firebase Database](/hacktricks/network-services-pentesting/pentesting-web/buckets/firebase-database)
    530 
    531 ### Realm databases
    532 
    533 [Realm Objective-C](https://realm.io/docs/objc/latest/) and [Realm Swift](https://realm.io/docs/swift/latest/) offer a powerful alternative for data storage, not provided by Apple. By default, they **store data unencrypted**, with encryption available through specific configuration.
    534 
    535 The databases are located at: `/private/var/mobile/Containers/Data/Application/{APPID}`. To explore these files, one can utilize commands like:
    536 
    537 ```bash
    538 iPhone:/private/var/mobile/Containers/Data/Application/A079DF84-726C-4AEA-A194-805B97B3684A/Documents root# ls
    539 default.realm  default.realm.lock  default.realm.management/  default.realm.note|
    540 
    541 $ find ./ -name "*.realm*"
    542 ```
    543 
    544 For viewing these database files, the [**Realm Studio**](https://github.com/realm/realm-studio) tool is recommended.
    545 
    546 To implement encryption within a Realm database, the following code snippet can be used:
    547 
    548 ```swift
    549 // Open the encrypted Realm file where getKey() is a method to obtain a key from the Keychain or a server
    550 let config = Realm.Configuration(encryptionKey: getKey())
    551 do {
    552   let realm = try Realm(configuration: config)
    553   // Use the Realm as normal
    554 } catch let error as NSError {
    555   // If the encryption key is wrong, `error` will say that it's an invalid database
    556   fatalError("Error opening realm: \(error)")
    557 }
    558 ```
    559 
    560 ### Couchbase Lite Databases
    561 
    562 [Couchbase Lite](https://github.com/couchbase/couchbase-lite-ios) is described as a **lightweight** and **embedded** database engine that follows the **document-oriented** (NoSQL) approach. Designed to be native to **iOS** and **macOS**, it offers the capability to sync data seamlessly.
    563 
    564 To identify potential Couchbase databases on a device, the following directory should be inspected:
    565 
    566 ```bash
    567 ls /private/var/mobile/Containers/Data/Application/{APPID}/Library/Application Support/
    568 ```
    569 
    570 ### Cookies
    571 
    572 iOS store the cookies of the apps in the **`Library/Cookies/cookies.binarycookies`** inside each apps folder. However, developers sometimes decide to save them in the **keychain** as the mentioned **cookie file can be accessed in backups**.
    573 
    574 To inspect the cookies file you can use [**this python script**](https://github.com/mdegrazia/Safari-Binary-Cookie-Parser) or use objection's **`ios cookies get`.**\
    575 **You can also use objection to** convert these files to a JSON format and inspect the data.
    576 
    577 ```bash
    578 ...itudehacks.DVIAswiftv2.develop on (iPhone: 13.2.3) [usb] # ios cookies get --json
    579 [
    580     {
    581         "domain": "highaltitudehacks.com",
    582         "expiresDate": "2051-09-15 07:46:43 +0000",
    583         "isHTTPOnly": "false",
    584         "isSecure": "false",
    585         "name": "username",
    586         "path": "/",
    587         "value": "admin123",
    588         "version": "0"
    589     }
    590 ]
    591 ```
    592 
    593 ### Cache
    594 
    595 By default NSURLSession stores data, such as **HTTP requests and responses in the Cache.db** database. This database can contain **sensitive data**, if tokens, usernames or any other sensitive information has been cached. To find the cached information open the data directory of the app (`/var/mobile/Containers/Data/Application/<UUID>`) and go to `/Library/Caches/<Bundle Identifier>`. The **WebKit cache is also being stored in the Cache.db** file. **Objection** can open and interact with the database with the command `sqlite connect Cache.db`, as it is a n**ormal SQLite database**.
    596 
    597 It is **recommended to disable Caching this data**, as it may contain sensitive information in the request or response. The following list below shows different ways of achieving this:
    598 
    599 1.  It is recommended to remove Cached responses after logout. This can be done with the provided method by Apple called [`removeAllCachedResponses`](https://developer.apple.com/documentation/foundation/urlcache/1417802-removeallcachedresponses) You can call this method as follows:
    600 
    601     `URLCache.shared.removeAllCachedResponses()`
    602 
    603     This method will remove all cached requests and responses from Cache.db file.
    604 
    605 2.  If you don't need to use the advantage of cookies it would be recommended to just use the [.ephemeral](https://developer.apple.com/documentation/foundation/urlsessionconfiguration/1410529-ephemeral) configuration property of URLSession, which will disable saving cookies and Caches.
    606 
    607     [Apple documentation](https://developer.apple.com/documentation/foundation/urlsessionconfiguration/1410529-ephemeral):
    608 
    609     `An ephemeral session configuration object is similar to a default session configuration (see default), except that the corresponding session object doesn’t store caches, credential stores, or any session-related data to disk. Instead, session-related data is stored in RAM. The only time an ephemeral session writes data to disk is when you tell it to write the contents of a URL to a file.`
    610 
    611 3.  Cache can be also disabled by setting the Cache Policy to [.notAllowed](https://developer.apple.com/documentation/foundation/urlcache/storagepolicy/notallowed). It will disable storing Cache in any fashion, either in memory or on disk.
    612 
    613 ### Snapshots
    614 
    615 Whenever you press the home button, iOS **takes a snapshot of the current screen** to be able to do the transition to the application on a much smoother way. However, if **sensitive** **data** is present in the current screen, it will be **saved** in the **image** (which **persists** **across** **reboots**). These are the snapshots that you can also access double tapping the home screen to switch between apps.
    616 
    617 Unless the iPhone is jailbroken, the **attacker** needs to have **access** to the **device** **unblocked** to see these screenshots. By default the last snapshot is stored in the application's sandbox in `Library/Caches/Snapshots/` or `Library/SplashBoard/Snapshots` folder (the trusted computers can' t access the filesystem from iOX 7.0).
    618 
    619 Once way to prevent this bad behaviour is to put a blank screen or remove the sensitive data before taking the snapshot using the `ApplicationDidEnterBackground()` function.
    620 
    621 The following is a sample remediation method that will set a default screenshot.
    622 
    623 Swift:
    624 
    625 ```swift
    626 private var backgroundImage: UIImageView?
    627 
    628 func applicationDidEnterBackground(_ application: UIApplication) {
    629     let myBanner = UIImageView(image: #imageLiteral(resourceName: "overlayImage"))
    630     myBanner.frame = UIScreen.main.bounds
    631     backgroundImage = myBanner
    632     window?.addSubview(myBanner)
    633 }
    634 
    635 func applicationWillEnterForeground(_ application: UIApplication) {
    636     backgroundImage?.removeFromSuperview()
    637 }
    638 ```
    639 
    640 Objective-C:
    641 
    642 ```text
    643 @property (UIImageView *)backgroundImage;
    644 
    645 - (void)applicationDidEnterBackground:(UIApplication *)application {
    646     UIImageView *myBanner = [[UIImageView alloc] initWithImage:@"overlayImage.png"];
    647     self.backgroundImage = myBanner;
    648     self.backgroundImage.bounds = UIScreen.mainScreen.bounds;
    649     [self.window addSubview:myBanner];
    650 }
    651 
    652 - (void)applicationWillEnterForeground:(UIApplication *)application {
    653     [self.backgroundImage removeFromSuperview];
    654 }
    655 ```
    656 
    657 This sets the background image to `overlayImage.png` whenever the application is backgrounded. It prevents sensitive data leaks because `overlayImage.png` will always override the current view.
    658 
    659 ### Keychain
    660 
    661 For accessing and managing the iOS keychain, tools like [**Keychain-Dumper**](https://github.com/ptoomey3/Keychain-Dumper) are available, suitable for jailbroken devices. Additionally, [**Objection**](https://github.com/sensepost/objection) provides the command `ios keychain dump` for similar purposes.<sup>[[2]](#references)</sup>
    662 
    663 #### **Storing Credentials**
    664 
    665 The **NSURLCredential** class is ideal for saving sensitive information directly in the keychain, bypassing the need for NSUserDefaults or other wrappers. To store credentials after login, the following Swift code is used:<sup>[[8]](#references)</sup>
    666 
    667 ```swift
    668 NSURLCredential *credential;
    669 credential = [NSURLCredential credentialWithUser:username password:password persistence:NSURLCredentialPersistencePermanent];
    670 [[NSURLCredentialStorage sharedCredentialStorage] setCredential:credential forProtectionSpace:self.loginProtectionSpace];
    671 ```
    672 
    673 To extract these stored credentials, Objection's command `ios nsurlcredentialstorage dump` is utilized.
    674 
    675 ## **Custom Keyboards and Keyboard Cache**
    676 
    677 With iOS 8.0 onwards, users can install custom keyboard extensions, which are manageable under **Settings > General > Keyboard > Keyboards**. While these keyboards offer extended functionality, they pose a risk of keystroke logging and transmitting data to external servers, though users are notified about keyboards requiring network access. Apps can, and should, restrict the use of custom keyboards for sensitive information entry.<sup>[[9]](#references)</sup>
    678 
    679 **Security Recommendations:**
    680 
    681 - It's advised to disable third-party keyboards for enhanced security.
    682 - Be aware of the autocorrect and auto-suggestions features of the default iOS keyboard, which could store sensitive information in cache files located in `Library/Keyboard/{locale}-dynamic-text.dat` or `/private/var/mobile/Library/Keyboard/dynamic-text.dat`. These cache files should be regularly checked for sensitive data. Resetting the keyboard dictionary via **Settings > General > Reset > Reset Keyboard Dictionary** is recommended for clearing cached data.
    683 - Intercepting network traffic can reveal whether a custom keyboard is transmitting keystrokes remotely.
    684 
    685 ### **Preventing Text Field Caching**
    686 
    687 The [UITextInputTraits protocol](https://developer.apple.com/reference/uikit/uitextinputtraits) offers properties to manage autocorrection and secure text entry, essential for preventing sensitive information caching. For example, disabling autocorrection and enabling secure text entry can be achieved with:
    688 
    689 ```text
    690 textObject.autocorrectionType = UITextAutocorrectionTypeNo;
    691 textObject.secureTextEntry = YES;
    692 ```
    693 
    694 Additionally, developers should ensure that text fields, especially those for entering sensitive information like passwords and PINs, disable caching by setting `autocorrectionType` to `UITextAutocorrectionTypeNo` and `secureTextEntry` to `YES`.
    695 
    696 ```text
    697 UITextField *textField = [[UITextField alloc] initWithFrame:frame];
    698 textField.autocorrectionType = UITextAutocorrectionTypeNo;
    699 ```
    700 
    701 ## **Logs**
    702 
    703 Debugging code often involves the use of **logging**. There's a risk involved as **logs may contain sensitive information**. Previously, in iOS 6 and earlier versions, logs were accessible to all apps, posing a risk of sensitive data leakage. **Now, applications are restricted to accessing only their logs**.<sup>[[10]](#references)</sup>
    704 
    705 Despite these restrictions, an **attacker with physical access** to an unlocked device can still exploit this by connecting the device to a computer and **reading the logs**. It is important to note that logs remain on the disk even after the app's uninstallation.
    706 
    707 To mitigate risks, it is advised to **thoroughly interact with the app**, exploring all its functionalities and inputs to ensure no sensitive information is being logged inadvertently.
    708 
    709 When reviewing the app's source code for potential leaks, look for both **predefined** and **custom logging statements** using keywords such as `NSLog`, `NSAssert`, `NSCAssert`, `fprintf` for built-in functions, and any mentions of `Logging` or `Logfile` for custom implementations.
    710 
    711 ### **Monitoring System Logs**
    712 
    713 Apps log various pieces of information which can be sensitive.<sup>[[11]](#references)</sup> To monitor these logs, tools and commands like:
    714 
    715 ```bash
    716 idevice_id --list   # To find the device ID
    717 idevicesyslog -u <id> (| grep <app>)   # To capture the device logs
    718 ```
    719 
    720 are useful. Additionally, **Xcode** provides a way to collect console logs:
    721 
    722 1. Open Xcode.
    723 2. Connect the iOS device.
    724 3. Navigate to **Window** -> **Devices and Simulators**.
    725 4. Select your device.
    726 5. Trigger the issue you're investigating.
    727 6. Use the **Open Console** button to view logs in a new window.
    728 
    729 For more advanced logging, connecting to the device shell and using **socat** can provide real-time log monitoring:
    730 
    731 ```bash
    732 iPhone:~ root# socat - UNIX-CONNECT:/var/run/lockdown/syslog.sock
    733 ```
    734 
    735 Followed by commands to observe log activities, which can be invaluable for diagnosing issues or identifying potential data leakage in logs.
    736 
    737 ## Backups
    738 
    739 **Auto-backup features** are integrated into iOS, facilitating the creation of device data copies through iTunes (up to macOS Catalina), Finder (from macOS Catalina onward), or iCloud. These backups encompass almost all device data, excluding highly sensitive elements like Apple Pay details and Touch ID configurations.<sup>[[12]](#references)</sup>
    740 
    741 ### Security Risks
    742 
    743 The inclusion of **installed apps and their data** in backups raises the issue of potential **data leakage** and the risk that **backup modifications could alter app functionality**. It's advised to **not store sensitive information in plaintext** within any app's directory or its subdirectories to mitigate these risks.
    744 
    745 ### Excluding Files from Backups
    746 
    747 Files in `Documents/` and `Library/Application Support/` are backed up by default. Developers can exclude specific files or directories from backups using `NSURL setResourceValue:forKey:error:` with the `NSURLIsExcludedFromBackupKey`. This practice is crucial for protecting sensitive data from being included in backups.
    748 
    749 ### Testing for Vulnerabilities
    750 
    751 To assess an app's backup security, start by **creating a backup** using Finder, then locate it using guidance from [Apple's official documentation](https://support.apple.com/en-us/HT204215). Analyze the backup for sensitive data or configurations that could be altered to affect app behavior.
    752 
    753 Sensitive information can be sought out using command-line tools or applications like [iMazing](https://imazing.com). For encrypted backups, the presence of encryption can be confirmed by checking the "IsEncrypted" key in the "Manifest.plist" file at the backup's root.
    754 
    755 ```xml
    756 <?xml version="1.0" encoding="UTF-8"?>
    757 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    758 <plist version="1.0">
    759 ...
    760  <key>Date</key>
    761  <date>2021-03-12T17:43:33Z</date>
    762  <key>IsEncrypted</key>
    763  <true/>
    764 ...
    765 </plist>
    766 ```
    767 
    768 For dealing with encrypted backups, Python scripts available in [DinoSec's GitHub repo](https://github.com/dinosec/iphone-dataprotection/tree/master/python_scripts), like **backup_tool.py** and **backup_passwd.py**, may be useful, albeit potentially requiring adjustments for compatibility with the latest iTunes/Finder versions. The [**iOSbackup** tool](https://pypi.org/project/iOSbackup/) is another option for accessing files within password-protected backups.
    769 
    770 ### Modifying App Behavior
    771 
    772 An example of altering app behavior through backup modifications is demonstrated in the [Bither bitcoin wallet app](https://github.com/bither/bither-ios), where the UI lock PIN is stored within `net.bither.plist` under the **pin_code** key. Removing this key from the plist and restoring the backup removes the PIN requirement, providing unrestricted access.
    773 
    774 ## Summary on Memory Testing for Sensitive Data
    775 
    776 When dealing with sensitive information stored in an application's memory, it is crucial to limit the exposure time of this data. There are two primary approaches to investigate memory content: **creating a memory dump** and **analyzing the memory in real time**. Both methods have their challenges, including the potential to miss critical data during the dump process or analysis.<sup>[[13]](#references)</sup>
    777 
    778 ## **Retrieving and Analyzing a Memory Dump**
    779 
    780 For both jailbroken and non-jailbroken devices, tools like [objection](https://github.com/sensepost/objection) and [Fridump](https://github.com/Nightbringer21/fridump) allow for the dumping of an app's process memory. Once dumped, analyzing this data requires various tools, depending on the nature of the information you're searching for.
    781 
    782 To extract strings from a memory dump, commands such as `strings` or `rabin2 -zz` can be used:
    783 
    784 ```bash
    785 # Extracting strings using strings command
    786 $ strings memory > strings.txt
    787 
    788 # Extracting strings using rabin2
    789 $ rabin2 -ZZ memory > strings.txt
    790 ```
    791 
    792 For more detailed analysis, including searching for specific data types or patterns, **radare2** offers extensive search capabilities:
    793 
    794 ```bash
    795 $ r2 <name_of_your_dump_file>
    796 [0x00000000]> /?
    797 ...
    798 ```
    799 
    800 ## **Runtime Memory Analysis**
    801 
    802 **r2frida** provides a powerful alternative for inspecting an app's memory in real time, without needing a memory dump. This tool enables the execution of search commands directly on the running application's memory:
    803 
    804 ```bash
    805 $ r2 frida://usb//<name_of_your_app>
    806 [0x00000000]> /\ <search_command>
    807 ```
    808 
    809 ## Broken Cryptography
    810 
    811 ### Poor Key Management Processes
    812 
    813 Some developers save sensitive data in the local storage and encrypt it with a key hardcoded/predictable in the code. This shouldn't be done as some reversing could allow attackers to extract the confidential information.
    814 
    815 ### Use of Insecure and/or Deprecated Algorithms
    816 
    817 During an iOS review, flag RC4, MD4, MD5, and SHA-1 when they are used for authorization or to protect stored or transmitted data. Password storage should use a unique salt and a deliberately expensive password KDF rather than a fast general-purpose digest.
    818 
    819 ### Check
    820 
    821 The main checks are whether the code contains **hardcoded** or **predictable** passwords and secrets, and whether it uses **weak cryptographic algorithms**.
    822 
    823 It's interesting to know that you can **monitor** some **crypto** **libraries** automatically using **objection** with:
    824 
    825 ```swift
    826 ios monitor crypt
    827 ```
    828 
    829 For **more information** about iOS cryptographic APIs and libraries, see the [OWASP iOS cryptography testing guide](https://mas.owasp.org/MASTG/0x06e-Testing-Cryptography/).<sup>[[29]](#references)</sup>
    830 
    831 ## Local Authentication
    832 
    833 **Local authentication** plays a crucial role, especially when it concerns safeguarding access at a remote endpoint through cryptographic methods. The essence here is that without proper implementation, local authentication mechanisms can be circumvented.<sup>[[14]](#references)</sup>
    834 
    835 Apple's [**Local Authentication framework**](https://developer.apple.com/documentation/localauthentication) and the [**keychain**](https://developer.apple.com/library/content/documentation/Security/Conceptual/keychainServConcepts/01introduction/introduction.html) provide robust APIs for developers to facilitate user authentication dialogs and securely handle secret data, respectively. The Secure Enclave secures fingerprint ID for Touch ID, whereas Face ID relies on facial recognition without compromising biometric data.
    836 
    837 To integrate Touch ID/Face ID, developers have two API choices:
    838 
    839 - **`LocalAuthentication.framework`** for high-level user authentication without access to biometric data.
    840 - **`Security.framework`** for lower-level keychain services access, securing secret data with biometric authentication. Various [open-source wrappers](https://www.raywenderlich.com/147308/secure-ios-user-data-keychain-touch-id) make keychain access simpler.
    841 
    842 > [!CAUTION]
    843 > However, both `LocalAuthentication.framework` and `Security.framework` present vulnerabilities, as they primarily return boolean values without transmitting data for authentication processes, making them susceptible to bypassing (refer to [Don't touch me that way, by David Lindner et al](https://www.youtube.com/watch?v=XhXIHVGCFFM)).
    844 
    845 ### Implementing Local Authentication
    846 
    847 To prompt users for authentication, developers should utilize the **`evaluatePolicy`** method within the **`LAContext`** class, choosing between:
    848 
    849 - **`deviceOwnerAuthentication`**: Prompts for Touch ID or device passcode, failing if neither is enabled.
    850 - **`deviceOwnerAuthenticationWithBiometrics`**: Exclusively prompts for Touch ID.
    851 
    852 A successful authentication is indicated by a boolean return value from **`evaluatePolicy`**, highlighting a potential security flaw.
    853 
    854 ### Local Authentication using Keychain
    855 
    856 Implementing **local authentication** in iOS apps involves the use of **keychain APIs** to securely store secret data such as authentication tokens. This process ensures that the data can only be accessed by the user, using their device passcode or biometric authentication like Touch ID.
    857 
    858 The keychain offers the capability to set items with the `SecAccessControl` attribute, which restricts access to the item until the user successfully authenticates via Touch ID or device passcode. This feature is crucial for enhancing security.
    859 
    860 Below are code examples in Swift and Objective-C demonstrating how to save and retrieve a string to/from the keychain, leveraging these security features. The examples specifically show how to set up access control to require Touch ID authentication and ensure the data is accessible only on the device it was set up on, under the condition that a device passcode is configured.
    861 
    862 ### Swift
    863 ```swift
    864 // From https://github.com/mufambisi/owasp-mstg/blob/master/Document/0x06f-Testing-Local-Authentication.md
    865 
    866 // 1. create AccessControl object that will represent authentication settings
    867 
    868 var error: Unmanaged<CFError>?
    869 
    870 guard let accessControl = SecAccessControlCreateWithFlags(kCFAllocatorDefault,
    871                                                           kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly,
    872                                                           SecAccessControlCreateFlags.biometryCurrentSet,
    873                                                           &error) else {
    874     // failed to create AccessControl object
    875 
    876     return
    877 }
    878 
    879 // 2. define keychain services query. Pay attention that kSecAttrAccessControl is mutually exclusive with kSecAttrAccessible attribute
    880 
    881 var query: [String: Any] = [:]
    882 
    883 query[kSecClass as String] = kSecClassGenericPassword
    884 query[kSecAttrLabel as String] = "com.me.myapp.password" as CFString
    885 query[kSecAttrAccount as String] = "OWASP Account" as CFString
    886 query[kSecValueData as String] = "test_strong_password".data(using: .utf8)! as CFData
    887 query[kSecAttrAccessControl as String] = accessControl
    888 
    889 // 3. save item
    890 
    891 let status = SecItemAdd(query as CFDictionary, nil)
    892 
    893 if status == noErr {
    894     // successfully saved
    895 } else {
    896     // error while saving
    897 }
    898 ```
    899 
    900 ### Objective-C
    901 ```text
    902     // 1. create AccessControl object that will represent authentication settings
    903     CFErrorRef *err = nil;
    904 
    905     SecAccessControlRef sacRef = SecAccessControlCreateWithFlags(kCFAllocatorDefault,
    906         kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly,
    907         kSecAccessControlUserPresence,
    908         err);
    909 
    910     // 2. define keychain services query. Pay attention that kSecAttrAccessControl is mutually exclusive with kSecAttrAccessible attribute
    911     NSDictionary* query = @{
    912         (_ _bridge id)kSecClass: (__bridge id)kSecClassGenericPassword,
    913         (__bridge id)kSecAttrLabel: @"com.me.myapp.password",
    914         (__bridge id)kSecAttrAccount: @"OWASP Account",
    915         (__bridge id)kSecValueData: [@"test_strong_password" dataUsingEncoding:NSUTF8StringEncoding],
    916         (__bridge id)kSecAttrAccessControl: (__bridge_transfer id)sacRef
    917     };
    918 
    919     // 3. save item
    920     OSStatus status = SecItemAdd((__bridge CFDictionaryRef)query, nil);
    921 
    922     if (status == noErr) {
    923         // successfully saved
    924     } else {
    925         // error while saving
    926     }
    927 ```
    928 
    929 
    930 Now we can request the saved item from the keychain. Keychain services will present the authentication dialog to the user and return data or nil depending on whether a suitable fingerprint was provided or not.
    931 
    932 ### Swift
    933 ```swift
    934 // 1. define query
    935 var query = [String: Any]()
    936 query[kSecClass as String] = kSecClassGenericPassword
    937 query[kSecReturnData as String] = kCFBooleanTrue
    938 query[kSecAttrAccount as String] = "My Name" as CFString
    939 query[kSecAttrLabel as String] = "com.me.myapp.password" as CFString
    940 query[kSecUseOperationPrompt as String] = "Please, pass authorisation to enter this area" as CFString
    941 
    942 // 2. get item
    943 var queryResult: AnyObject?
    944 let status = withUnsafeMutablePointer(to: &queryResult) {
    945     SecItemCopyMatching(query as CFDictionary, UnsafeMutablePointer($0))
    946 }
    947 
    948 if status == noErr {
    949     let password = String(data: queryResult as! Data, encoding: .utf8)!
    950     // successfully received password
    951 } else {
    952     // authorization not passed
    953 }
    954 ```
    955 
    956 ### Objective-C
    957 ```text
    958 // 1. define query
    959 NSDictionary *query = @{(__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword,
    960     (__bridge id)kSecReturnData: @YES,
    961     (__bridge id)kSecAttrAccount: @"My Name1",
    962     (__bridge id)kSecAttrLabel: @"com.me.myapp.password",
    963     (__bridge id)kSecUseOperationPrompt: @"Please, pass authorisation to enter this area" };
    964 
    965 // 2. get item
    966 CFTypeRef queryResult = NULL;
    967 OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &queryResult);
    968 
    969 if (status == noErr){
    970     NSData* resultData = ( __bridge_transfer NSData* )queryResult;
    971     NSString* password = [[NSString alloc] initWithData:resultData encoding:NSUTF8StringEncoding];
    972     NSLog(@"%@", password);
    973 } else {
    974     NSLog(@"Something went wrong");
    975 }
    976 ```
    977 
    978 
    979 ### Detection
    980 
    981 Usage of frameworks in an app can also be detected by analyzing the app binary's list of shared dynamic libraries. This can be done by using `otool`:
    982 
    983 ```bash
    984 $ otool -L <AppName>.app/<AppName>
    985 ```
    986 
    987 If `LocalAuthentication.framework` is used in an app, the output will contain both of the following lines (remember that `LocalAuthentication.framework` uses `Security.framework` under the hood):
    988 
    989 ```bash
    990 /System/Library/Frameworks/LocalAuthentication.framework/LocalAuthentication
    991 /System/Library/Frameworks/Security.framework/Security
    992 ```
    993 
    994 If `Security.framework` is used, only the second one will be shown.
    995 
    996 ### Local Authentication Framework Bypass
    997 
    998 #### **Objection**
    999 
   1000 Through the **Objection Biometrics Bypass**, located at [this GitHub page](https://github.com/sensepost/objection/wiki/Understanding-the-iOS-Biometrics-Bypass), a technique is available for overcoming the **LocalAuthentication** mechanism. The core of this approach involves leveraging **Frida** to manipulate the `evaluatePolicy` function, ensuring it consistently yields a `True` outcome, irrespective of the actual authentication success. This is particularly useful for circumventing flawed biometric authentication processes.
   1001 
   1002 To activate this bypass, the following command is employed:
   1003 
   1004 ```bash
   1005 ...itudehacks.DVIAswiftv2.develop on (iPhone: 13.2.3) [usb] # ios ui biometrics_bypass
   1006 (agent) Registering job 3mhtws9x47q. Type: ios-biometrics-disable
   1007 ...itudehacks.DVIAswiftv2.develop on (iPhone: 13.2.3) [usb] # (agent) [3mhtws9x47q] Localized Reason for auth requirement: Please authenticate yourself
   1008 (agent) [3mhtws9x47q] OS authentication response: false
   1009 (agent) [3mhtws9x47q] Marking OS response as True instead
   1010 (agent) [3mhtws9x47q] Biometrics bypass hook complete
   1011 ```
   1012 
   1013 This command sets off a sequence where Objection registers a task that effectively alters the outcome of the `evaluatePolicy` check to `True`.
   1014 
   1015 #### Frida
   1016 
   1017 An example of a use of **`evaluatePolicy`** from [DVIA-v2 application](https://github.com/prateek147/DVIA-v2):<sup>[[22]](#references)</sup>
   1018 
   1019 ```swift
   1020 +(void)authenticateWithTouchID {
   1021     LAContext *myContext = [[LAContext alloc] init];
   1022     NSError *authError = nil;
   1023     NSString *myLocalizedReasonString = @"Please authenticate yourself";
   1024 
   1025     if ([myContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&authError]) {
   1026         [myContext evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics
   1027                   localizedReason:myLocalizedReasonString
   1028                             reply:^(BOOL success, NSError *error) {
   1029                                 if (success) {
   1030                                     dispatch_async(dispatch_get_main_queue(), ^{
   1031                                     [TouchIDAuthentication showAlert:@"Authentication Successful" withTitle:@"Success"];
   1032                                     });
   1033                                 } else {
   1034                                     dispatch_async(dispatch_get_main_queue(), ^{
   1035                                        [TouchIDAuthentication showAlert:@"Authentication Failed !" withTitle:@"Error"];
   1036                                     });
   1037                                 }
   1038                             }];
   1039     } else {
   1040         dispatch_async(dispatch_get_main_queue(), ^{
   1041             [TouchIDAuthentication showAlert:@"Your device doesn't support Touch ID or you haven't configured Touch ID authentication on your device" withTitle:@"Error"];
   1042         });
   1043     }
   1044 }
   1045 ```
   1046 
   1047 To achieve the **bypass** of Local Authentication, a Frida script is written. This script targets the **evaluatePolicy** check, intercepting its callback to ensure it returns **success=1**. By altering the callback's behavior, the authentication check is effectively bypassed.<sup>[[15]](#references)</sup>
   1048 
   1049 The script below is injected to modify the result of the **evaluatePolicy** method. It changes the callback's result to always indicate success.<sup>[[28]](#references)</sup>
   1050 
   1051 ```swift
   1052 // from https://securitycafe.ro/2022/09/05/mobile-pentesting-101-bypassing-biometric-authentication/
   1053 if(ObjC.available) {
   1054     console.log("Injecting...");
   1055     var hook = ObjC.classes.LAContext["- evaluatePolicy:localizedReason:reply:"];
   1056     Interceptor.attach(hook.implementation, {
   1057         onEnter: function(args) {
   1058             var block = new ObjC.Block(args[4]);
   1059             const callback = block.implementation;
   1060             block.implementation = function (error, value)  {
   1061 
   1062                 console.log("Changing the result value to true")
   1063                 const result = callback(1, null);
   1064                 return result;
   1065             };
   1066         },
   1067     });
   1068 } else {
   1069     console.log("Objective-C Runtime is not available!");
   1070 }
   1071 ```
   1072 
   1073 To inject the Frida script and bypass the biometric authentication, the following command is used:
   1074 
   1075 ```bash
   1076 frida -U -f com.highaltitudehacks.DVIAswiftv2 --no-pause -l fingerprint-bypass-ios.js
   1077 ```
   1078 
   1079 ## Sensitive Functionality Exposure Through IPC
   1080 
   1081 ### Custom URI Handlers / Deeplinks / Custom Schemes
   1082 
   1083 
   1084 [Ios Custom Uri Handlers Deeplinks Custom Schemes](/hacktricks/mobile-pentesting/ios-pentesting/ios-custom-uri-handlers-deeplinks-custom-schemes)
   1085 
   1086 ### Universal Links
   1087 
   1088 
   1089 [Ios Universal Links](/hacktricks/mobile-pentesting/ios-pentesting/ios-universal-links)
   1090 
   1091 ### UIActivity Sharing
   1092 
   1093 
   1094 [Ios Uiactivity Sharing](/hacktricks/mobile-pentesting/ios-pentesting/ios-uiactivity-sharing)
   1095 
   1096 ### UIPasteboard
   1097 
   1098 
   1099 [Ios Uipasteboard](/hacktricks/mobile-pentesting/ios-pentesting/ios-uipasteboard)
   1100 
   1101 ### App Extensions
   1102 
   1103 
   1104 [Ios App Extensions](/hacktricks/mobile-pentesting/ios-pentesting/ios-app-extensions)
   1105 
   1106 ### WebViews
   1107 
   1108 
   1109 [Ios Webviews](/hacktricks/mobile-pentesting/ios-pentesting/ios-webviews)
   1110 
   1111 ### Serialisation and Encoding
   1112 
   1113 
   1114 [Ios Serialisation And Encoding](/hacktricks/mobile-pentesting/ios-pentesting/ios-serialisation-and-encoding)
   1115 
   1116 ## Network Communication
   1117 
   1118 ### BLE application protocols
   1119 
   1120 For iOS applications using BLE mesh transports, see the application-protocol cache-poisoning methodology:
   1121 
   1122 [Pentesting Ble Bluetooth Low Energy.Md#Ble Mesh And Gossip Protocol Cache Poisoning](../../todo/radio-hacking/pentesting-ble-bluetooth-low-energy.md%23ble-mesh-and-gossip-protocol-cache-poisoning)
   1123 
   1124 It's important to check that no communication is occurring **without encryption** and also that the application is correctly **validating the TLS certificate** of the server.\
   1125 To check these kind of issues you can use a proxy like **Burp**:
   1126 
   1127 
   1128 [Burp Configuration For Ios](/hacktricks/mobile-pentesting/ios-pentesting/burp-configuration-for-ios)
   1129 
   1130 ### Hostname check
   1131 
   1132 One common issue validating the TLS certificate is to check that the certificate was signed by a **trusted** **CA**, but **not check** if **the hostname** of the certificate is the hostname being accessed.\
   1133 In order to check this issue using Burp, after trusting Burp CA in the iPhone, you can **create a new certificate with Burp for a different hostname** and use it. If the application still works, then, something it's vulnerable.
   1134 
   1135 ### Certificate Pinning
   1136 
   1137 If an application is correctly using SSL Pinning, then the application will only works if the certificate is the once expected to be. When testing an application **this might be a problem as Burp will serve it's own certificate.**\
   1138 In order to bypass this protection inside a jailbroken device, you can install the application [**SSL Kill Switch**](https://github.com/nabla-c0d3/ssl-kill-switch2) or install [**Burp Mobile Assistant**](https://portswigger.net/burp/documentation/desktop/mobile/config-ios-device)<sup>[[27]](#references)</sup>
   1139 
   1140 You can also use **objection's** `ios sslpinning disable`
   1141 
   1142 ## Misc
   1143 
   1144 - In **`/System/Library`** you can find the frameworks installed in the phone used by system applications
   1145 - The applications installed by the user from the App Store are located inside **`/User/Applications`**
   1146 - And the **`/User/Library`** contains data saved by the user level applications
   1147 - You can access **`/User/Library/Notes/notes.sqlite`** to read the notes saved inside the application.
   1148 - Inside the folder of an installed application (**`/User/Applications/<APP ID>/`**) you can find some interesting files:
   1149   - **`iTunesArtwork`**: The icon used by the app
   1150   - **`iTunesMetadata.plist`**: Info of the app used in the App Store
   1151   - **`/Library/*`**: Contains the preferences and cache. In **`/Library/Cache/Snapshots/*`** you can find the snapshot performed to the application before sending it to the background.
   1152 
   1153 ### Hot Patching/Enforced Updating
   1154 
   1155 Frameworks such as [**JSPatch**](https://github.com/bang590/JSPatch) have been used to deliver script-based patches to deployed installations without waiting for another App Store review. Update-enforcement libraries such as [Siren](https://github.com/ArtSabintsev/Siren) and [react-native-appstore-version-checker](https://www.npmjs.com/package/react-native-appstore-version-checker) serve a different purpose: they detect or require a newer App Store version rather than hot-patching code.\
   1156 **A remote patch channel can change behavior across many installations quickly and can be abused by a malicious or compromised third-party SDK or update service. Identify each remote-update mechanism, test transport authenticity, payload integrity, signing and rollback behavior, and compare it with an older app version when possible.**
   1157 
   1158 ### Third Parties
   1159 
   1160 A significant challenge with **3rd party SDKs** is the **lack of granular control** over their functionalities. Developers are faced with a choice: either integrate the SDK and accept all its features, including potential security vulnerabilities and privacy concerns, or forego its benefits entirely. Often, developers are unable to patch vulnerabilities within these SDKs themselves. Furthermore, as SDKs gain trust within the community, some may start to contain malware.
   1161 
   1162 The services provided by third-party SDKs may include user behavior tracking, advertisement displays, or user experience enhancements. However, this introduces a risk as developers may not be fully aware of the code executed by these libraries, leading to potential privacy and security risks. It's crucial to limit the information shared with third-party services to what is necessary and ensure that no sensitive data is exposed.<sup>[[16]](#references)</sup>
   1163 
   1164 Implementation of third-party services usually comes in two forms: a standalone library or a full SDK. To protect user privacy, any data shared with these services should be **anonymized** to prevent the disclosure of Personal Identifiable Information (PII).
   1165 
   1166 To identify the libraries an application uses, the **`otool`** command can be employed. This tool should be run against the application and each shared library it uses to discover additional libraries.
   1167 
   1168 ```bash
   1169 otool -L <application_path>
   1170 ```
   1171 
   1172 ## Interesting Vulnerabilities & Case Studies
   1173 
   1174 
   1175 [Air Keyboard Remote Input Injection](/hacktricks/mobile-pentesting/ios-pentesting/air-keyboard-remote-input-injection)
   1176 
   1177 [Itunesstored Bookassetd Sandbox Escape](/hacktricks/mobile-pentesting/ios-pentesting/itunesstored-bookassetd-sandbox-escape)
   1178 
   1179 [Zero Click Messaging Image Parser Chains](/hacktricks/mobile-pentesting/ios-pentesting/zero-click-messaging-image-parser-chains)
   1180 
   1181 ## References
   1182 
   1183 - [1] [Taking Apart iOS Apps: Anti-Debugging and Anti-Tampering in the Wild](https://blog.calif.io/p/taking-apart-ios-apps-anti-debugging)
   1184 - [2] [OWASP MASTG – iOS Security Testing](https://mas.owasp.org/MASTG/0x06b-iOS-Security-Testing/)
   1185 - [3] [iOS & Mobile App Pentesting - INE](https://my.ine.com/CyberSecurity/courses/089d060b/ios-mobile-app-pentesting)
   1186 - [4] [OWASP MASTG-TECH-0057: Listing Installed Apps](https://mas.owasp.org/MASTG/techniques/ios/MASTG-TECH-0057/)
   1187 - [5] [OWASP MASTG-TECH-0058: Exploring the App Package](https://mas.owasp.org/MASTG/techniques/ios/MASTG-TECH-0058/)
   1188 - [6] [OWASP MASTG-TECH-0059: Accessing App Data Directories](https://mas.owasp.org/MASTG/techniques/ios/MASTG-TECH-0059/)
   1189 - [7] [OWASP MASTG – iOS Testing Data Storage](https://mas.owasp.org/MASTG/0x06d-Testing-Data-Storage/)
   1190 - [8] [Storing password in keychain the smart way](https://coderwall.com/p/kjb3lw/storing-password-in-keychain-the-smart-way)
   1191 - [9] [OWASP MASTG-TEST-0055: Finding Sensitive Data in the Keyboard Cache](https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0055/)
   1192 - [10] [OWASP MASTG-TEST-0053: Checking Logs for Sensitive Data](https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0053)
   1193 - [11] [OWASP MASTG-TECH-0060: Monitoring System Logs](https://mas.owasp.org/MASTG/techniques/ios/MASTG-TECH-0060/)
   1194 - [12] [OWASP MASTG-TEST-0058: Testing Backups for Sensitive Data](https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0058)
   1195 - [13] [OWASP MASTG-TEST-0060: Testing Memory for Sensitive Data](https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0060)
   1196 - [14] [OWASP MASTG-TEST-0064: Testing Biometric Authentication](https://mas.owasp.org/MASTG/tests/ios/MASVS-AUTH/MASTG-TEST-0064)
   1197 - [15] [Bypassing your apps' biometric checks on iOS](https://medium.com/securing/bypassing-your-apps-biometric-checks-on-ios-c2555c81a2dc)
   1198 - [16] [OWASP MASTG-TEST-0054: Determining Whether Sensitive Data Is Shared with Third Parties](https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0054)
   1199 - [17] [RE:iOS Apps – reverse engineering iOS applications course](https://github.com/ivRodriguezCA/RE-iOS-Apps/)
   1200 - [18] [OWASP MASTG-TECH-0152 – Bypassing Jailbreak Detection](https://mas.owasp.org/MASTG/techniques/ios/MASTG-TECH-0152/)
   1201 - [19] [iPwn Apps: Pentesting iOS Applications](https://www.sans.org/reading-room/whitepapers/testing/ipwn-apps-pentesting-ios-applications-34577)
   1202 - [20] [iOS Application Penetration Testing for Beginners](https://www.slideshare.net/RyanISI/ios-appsecurityminicourse)
   1203 - [21] [prateek147/DVIA – Damn Vulnerable iOS App (GitHub)](https://github.com/prateek147/DVIA)
   1204 - [22] [prateek147/DVIA-v2 – Damn Vulnerable iOS App v2 (GitHub)](https://github.com/prateek147/DVIA-v2)
   1205 - [23] [OWASP MSTG Hacking Playground (GitHub)](https://github.com/OWASP/MSTG-Hacking-Playground)
   1206 - [24] [OWASP iGoat – Objective-C version (GitHub)](https://github.com/OWASP/igoat)
   1207 - [25] [OWASP iGoat-Swift – Swift version (GitHub)](https://github.com/OWASP/iGoat-Swift)
   1208 - [26] [WheresMyBrowser.iOS (GitHub)](https://github.com/authenticationfailure/WheresMyBrowser.iOS)
   1209 - [27] [SSL Kill Switch 2 (GitHub)](https://github.com/nabla-c0d3/ssl-kill-switch2)
   1210 - [28] [Mobile Pentesting 101 – Bypassing Biometric Authentication](https://securitycafe.ro/2022/09/05/mobile-pentesting-101-bypassing-biometric-authentication/)
   1211 - [29] [OWASP MASTG – iOS Testing Cryptography](https://mas.owasp.org/MASTG/0x06e-Testing-Cryptography/)
   1212 - [30] [iOS (Swift) Anti-Jailbreak Bypass Using Frida – syrion (Internet Archive)](https://web.archive.org/web/20200514192843/https://syrion.me/blog/ios-swift-antijailbreak-bypass-frida/)