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

ios-basics.md (17867B)


      1 ---
      2 title: "iOS Basics"
      3 section: "Mobile"
      4 sectionSlug: "mobile-pentesting"
      5 sourcePath: "src/mobile-pentesting/ios-pentesting/ios-basics.md"
      6 sourceUrl: "https://github.com/HackTricks-wiki/hacktricks/blob/188de82beb54e70956b2952367a0af91d26758b8/src/mobile-pentesting/ios-pentesting/ios-basics.md"
      7 sha: "188de82beb54e70956b2952367a0af91d26758b8"
      8 isIndex: false
      9 modified: true
     10 license: "CC-BY-NC-4.0"
     11 ---
     12 
     13 # iOS Basics
     14 
     15 ## Filesystem Folders
     16 
     17 - `/Applications`: Contains the installed native system applications on the device (for example `/Applications/Calculator.app`).
     18 - `/private/var/containers/Bundle/Application/<UUID>`: Contains the application bundles for installed apps. In practice you will also see the shortened `/var/containers/...` path in logs and tools.
     19 - `/private/var/mobile/Containers/Data/Application/<UUID>`: Contains the private data container for each installed app.
     20 - `/private/var/mobile/Containers/Shared/AppGroup/<UUID>`: Shared container used by apps, widgets, and extensions that belong to the same **App Group**. Shared `UserDefaults`, SQLite DBs, caches, exported files, and token hand-off artifacts often end up here.
     21 - `/private/var/mobile/Containers/Data/PluginKitPlugin/<UUID>`: Per-extension / PluginKit data. This is especially interesting when testing share extensions, widgets, document pickers, or temporary imported media.
     22 - `/System`: Contains the core system files and libraries.
     23 - `/Library`: Contains system-wide resources and settings.
     24 - `/User`: Contains user-specific data and settings.
     25 - `/Development`: Empty unless you press the "Use for development" button.
     26 - `/dev`: Contains device files.
     27 - `/Core`: Contains OS core dumps.
     28 - `/private/var/mobile/Library/Logs/CrashReporter/<appname-date>*`: Contains crash logs for the specified application.
     29 - `/var/jb`: On modern **rootless jailbreaks**, this usually points to the writable jailbreak bootstrap under `/private/preboot/<hash>/...`; many modern tweaks, binaries, and jailbreak indicators live here instead of directly under `/`.<sup>[[5]](#references)</sup>
     30 - Many other common Unix folders...
     31 
     32 ### SQLite DBs
     33 
     34 SQLite DBs are widely used in iOS and Android applications for local data storage. They provide a lightweight, serverless database solution that is easy to integrate and use within mobile apps.
     35 
     36 A SQLite DB usually generates 3 files:
     37 - `<name>.db`: The main database file.
     38 - `<name>.db-shm`: The journal file which stores data before a transaction change (for DB restoration if needed).
     39 - `<name>.db-wal`: The write-ahead log file which stores the new data until it's ready to commit to the DB for faster processing.
     40 
     41 When extracting data, copy the **three files together**. Recent rows often live only in the WAL file, so pulling just `<name>.db` can produce an incomplete or misleading snapshot.<sup>[[1]](#references)</sup>
     42 
     43 ## Privilege Separation and Sandbox
     44 
     45 In iOS, a distinction in privilege exists between the user-accessible applications and the system's core processes. Applications run under the **`mobile`** user identity, while the crucial system processes operate as **`root`**. This separation is enhanced by a sandbox mechanism, which imposes strict limitations on what actions applications can undertake. For instance, even if applications share the same user identity, they are prohibited from accessing or modifying each other's data.
     46 
     47 Applications are installed in a specific directory (`private/var/mobile/Applications/{random ID}`) and have restricted read access to certain system areas and functionalities, such as SMS and phone calls. Access to protected areas triggers a pop-up request for user permission.<sup>[[3]](#references)[[6]](#references)</sup>
     48 
     49 From a pentester's perspective, **extensions and widgets are separate sandboxes** with their own `Info.plist`, entitlements, and storage. The main app normally exchanges state with them through **App Groups** and **Keychain access groups**, so inspect the shared containers and every `.appex` inside `PlugIns/` instead of assuming all sensitive state lives only in the main app sandbox. For extension-specific attack surface, check [iOS App Extensions](/hacktricks/mobile-pentesting/ios-pentesting/ios-app-extensions).
     50 
     51 ## Data Protection
     52 
     53 iOS offers developers the **Data Protection APIs**, built atop the Secure Enclave Processor (SEP) — a dedicated coprocessor for cryptographic operations and key management. The SEP ensures data protection integrity via a unique device-specific key, the device UID, embedded within it.
     54 
     55 Upon file creation, a unique 256-bit AES encryption key is generated, encrypting the file's content. This encryption key, alongside a class ID, is then encrypted using a class key and stored within the file's metadata. Decrypting a file involves using the system's key to access the metadata, retrieving the class key with the class ID, and then decrypting the file's unique encryption key.
     56 
     57 iOS defines **four protection classes** for data security, which determine when and how data can be accessed:
     58 
     59 - **Complete Protection (NSFileProtectionComplete)**: Data is inaccessible until the device is unlocked using the user's passcode.
     60 - **Protected Unless Open (NSFileProtectionCompleteUnlessOpen)**: Allows file access even after the device is locked, provided the file was opened when the device was unlocked.
     61 - **Protected Until First User Authentication (NSFileProtectionCompleteUntilFirstUserAuthentication)**: Data is accessible after the first user unlock post-boot, remaining accessible even if the device is locked again.
     62 - **No Protection (NSFileProtectionNone)**: Data is only protected by the device UID, facilitating quick remote data wiping.
     63 
     64 The encryption of all classes, except for `NSFileProtectionNone`, involves a key derived from both the device UID and the user's passcode, ensuring decryption is only possible on the device with the correct passcode. From iOS 7 onwards, the default protection class is **`NSFileProtectionCompleteUntilFirstUserAuthentication`**. Apps can change the default for newly created files with the entitlement **`com.apple.developer.default-data-protection`** or per-file via `NSFileProtectionKey`.<sup>[[1]](#references)</sup>
     65 
     66 During a review, inspect both the **private app container** and any **App Group shared container**. Teams often protect the main login database correctly but leave shared `UserDefaults`, exported documents, caches, or helper SQLite files with a weaker protection class.
     67 
     68 A quick runtime check from inside the app is:
     69 
     70 ```swift
     71 let attrs = try FileManager.default.attributesOfItem(atPath: path)
     72 print(attrs[.protectionKey] ?? "no protection")
     73 ```
     74 
     75 Developers can use [**FileDP**](https://github.com/abjurato/FileDp-Source), a tool for inspecting the data protection class of files on an iPhone.
     76 
     77 ```python
     78 # Example code to use FileDP for checking file protection class
     79 # Note: Ensure your device is jailbroken and has Python installed to use FileDP.
     80 # Installation and usage of FileDP:
     81 git clone https://github.com/abjurato/FileDp-Source
     82 cd FileDp-Source
     83 python filedp.py /path/to/check
     84 ```
     85 
     86 ### **The Keychain**
     87 
     88 In iOS, a **Keychain** serves as a secure **encrypted container** for storing **sensitive information**, accessible only by the application that stored it or those explicitly authorized. This encryption is fortified by a unique **password generated by iOS**, which itself is encrypted with **AES**. This encryption process leverages a **PBKDF2 function**, combining the user's passcode with a salt derived from the device's **UID**, a component only the **secure enclave chipset** can access. Consequently, even if the user's passcode is known, the Keychain contents remain inaccessible on any device other than the one where they were originally encrypted.<sup>[[1]](#references)</sup>
     89 
     90 **Management and access** to the Keychain data are handled by the **`securityd` daemon**, based on specific app entitlements like `Keychain-access-groups` and `application-identifier`.<sup>[[1]](#references)</sup>
     91 
     92 From a tester's perspective, **shared Keychain access groups widen the trust boundary**: every app, extension, widget, or companion target that is entitled for the same group can potentially read or write those entries. Review the whole app suite, not just the main bundle.
     93 
     94 #### **Keychain API Operations**
     95 
     96 The Keychain API, detailed at [Apple's Keychain Services documentation](https://developer.apple.com/library/content/documentation/Security/Conceptual/keychainServConcepts/02concepts/concepts.html), provides essential functions for secure storage management:<sup>[[1]](#references)</sup>
     97 
     98 - **`SecItemAdd`**: Adds a new item to the Keychain.
     99 - **`SecItemUpdate`**: Updates an existing item in the Keychain.
    100 - **`SecItemCopyMatching`**: Retrieves an item from the Keychain.
    101 - **`SecItemDelete`**: Removes an item from the Keychain.
    102 
    103 Brute-forcing the Keychain password involves either attacking the encrypted key directly or attempting to guess the passcode on the device itself, hindered significantly by secure enclave's enforcement of a delay between failed attempts.<sup>[[1]](#references)</sup>
    104 
    105 #### **Configuring Keychain Item Data Protection**
    106 
    107 Data protection levels for Keychain items are set using the `kSecAttrAccessible` attribute during item creation or update. These levels, [as specified by Apple](https://developer.apple.com/documentation/security/keychain_services/keychain_items/item_attribute_keys_and_values#1679100), determine when and how Keychain items are accessible:<sup>[[1]](#references)[[4]](#references)</sup>
    108 
    109 - **`kSecAttrAccessibleAlways`**: Accessible anytime, regardless of device lock status.
    110 - **`kSecAttrAccessibleAlwaysThisDeviceOnly`**: Always accessible, but not included in backups.
    111 - **`kSecAttrAccessibleAfterFirstUnlock`**: Accessible after the first unlock post-restart.
    112 - **`kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly`**: Same as above, but not transferable to new devices.
    113 - **`kSecAttrAccessibleWhenUnlocked`**: Only accessible when the device is unlocked.
    114 - **`kSecAttrAccessibleWhenUnlockedThisDeviceOnly`**: Accessible when unlocked, not included in backups.
    115 - **`kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly`**: Requires device passcode, not included in backups.
    116 - **`kSecAttrSynchronizable`**: Optional flag that syncs an item through **iCloud Keychain** to the user's other devices. Great for usability, but usually a bad place for device-bound secrets, jailbreak indicators, or local database keys.
    117 
    118 **`AccessControlFlags`** further refine access methods, allowing for biometric authentication or passcode use.<sup>[[1]](#references)[[4]](#references)</sup> During a review, pay special attention to the difference between **`userPresence`** (biometric _or_ passcode) and **`biometryCurrentSet`** (bound to the currently enrolled biometrics and invalidated when the biometric set changes). For high-value local secrets, `kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly` plus a restrictive access-control flag is the high-water mark; weaker combinations like `AfterFirstUnlock` deserve extra scrutiny.
    119 
    120 #### **Jailbroken Devices Warning**
    121 
    122 > [!WARNING]
    123 > On **jailbroken devices**, the Keychain's protections are compromised, posing a significant security risk.
    124 
    125 #### **Persistence of Keychain Data**
    126 
    127 Unlike app-specific data deleted upon app uninstallation, **Keychain data persists** on the device. This characteristic could enable new owners of a second-hand device to access the previous owner's application data simply by reinstalling apps. Developers are advised to proactively clear Keychain data upon app installation or during logout to mitigate this risk.<sup>[[1]](#references)</sup> Here's a Swift code example demonstrating how to clear Keychain data upon the first app launch:
    128 
    129 ```swift
    130 let userDefaults = UserDefaults.standard
    131 
    132 if userDefaults.bool(forKey: "hasRunBefore") == false {
    133     // Remove Keychain items here
    134 
    135     // Update the flag indicator
    136     userDefaults.set(true, forKey: "hasRunBefore")
    137     userDefaults.synchronize() // Forces the app to update UserDefaults
    138 }
    139 ```
    140 
    141 ## **App Capabilities**
    142 
    143 In the realm of app development, **sandboxing** plays a crucial role in enhancing security. This process ensures that each app operates within its own unique home directory, thus preventing it from accessing system files or data belonging to other apps. The enforcement of these restrictions is carried out through sandbox policies, which are a part of the **Trusted BSD (MAC) Mandatory Access Control Framework**.<sup>[[3]](#references)</sup>
    144 
    145 Developers have the ability to configure certain **capabilities or permissions** for their apps, such as **Data Protection** or **Keychain Sharing**. These permissions are applied immediately after the app is installed. Nonetheless, for accessing certain protected resources, the app must obtain explicit consent from the user at the time of the first attempt. This is achieved through the use of _purpose strings_ or _usage description strings_, which are presented to users in a permission request alert.<sup>[[2]](#references)</sup>
    146 
    147 For those with access to the source code, verification of permissions included in the `Info.plist` file can be done by:
    148 
    149 1. Opening the project in Xcode.
    150 2. Locating and opening the `Info.plist` file.
    151 3. Searching for keys prefixed with `"Privacy -"`, with the option to view raw keys/values for clarity.
    152 
    153 When dealing with an IPA file, the following steps can be followed:
    154 
    155 1. Unzip the IPA.
    156 2. Locate the `Info.plist` file within `Payload/<appname>.app/`.
    157 3. Convert the file to XML format if necessary, for easier inspection.
    158 
    159 For example, the purpose strings in the `Info.plist` file might look like this:
    160 
    161 ```xml
    162 <plist version="1.0">
    163 <dict>
    164     <key>NSLocationWhenInUseUsageDescription</key>
    165     <string>Your location is used to provide turn-by-turn directions to your destination.</string>
    166 ```
    167 
    168 ### Quick triage from an IPA
    169 
    170 A fast first pass against an IPA usually answers most of the "what should I inspect next?" questions:
    171 
    172 ```bash
    173 unzip -q app.ipa -d /tmp/app
    174 APP=$(find /tmp/app/Payload -maxdepth 1 -name '*.app' | head -n 1)
    175 plutil -p "$APP/Info.plist" | rg 'UsageDescription|NSAppTransportSecurity|CFBundleURLTypes|LSApplicationQueriesSchemes|UIRequiredDeviceCapabilities'
    176 codesign -d --entitlements :- "$APP" 2>/dev/null
    177 test -f "$APP/embedded.mobileprovision" && security cms -D -i "$APP/embedded.mobileprovision" | plutil -p -
    178 find "$APP/PlugIns" -maxdepth 2 \( -name '*.appex' -o -name Info.plist \) 2>/dev/null
    179 ```
    180 
    181 This is a great place to spot:
    182 
    183 - **ATS exceptions** via `NSAppTransportSecurity`
    184 - **Cross-app interaction pivots** via `CFBundleURLTypes` or `LSApplicationQueriesSchemes`
    185 - **Extra attack surface** in extensions under `PlugIns/`
    186 - **Interesting entitlements** such as `get-task-allow`, `com.apple.security.application-groups`, `keychain-access-groups`, or `com.apple.developer.associated-domains`
    187 
    188 Those keys are excellent pivots into [custom URL schemes](/hacktricks/mobile-pentesting/ios-pentesting/ios-custom-uri-handlers-deeplinks-custom-schemes), [Universal Links](/hacktricks/mobile-pentesting/ios-pentesting/ios-universal-links), and [app extensions](/hacktricks/mobile-pentesting/ios-pentesting/ios-app-extensions).
    189 
    190 ### Device Capabilities
    191 
    192 The `Info.plist` file of an app specifies **device capabilities** that help the App Store filter apps for device compatibility. These are defined under the **`UIRequiredDeviceCapabilities`** key. For instance:
    193 
    194 ```xml
    195 <key>UIRequiredDeviceCapabilities</key>
    196 <array>
    197     <string>armv7</string>
    198 </array>
    199 ```
    200 
    201 This example indicates that the app is compatible with the armv7 instruction set. Developers may also specify capabilities like nfc to ensure their app is only available to devices supporting NFC.
    202 
    203 ### Entitlements
    204 
    205 **Entitlements** are another critical aspect of iOS app development, serving as key-value pairs that grant apps permission to perform certain operations beyond runtime checks. For example, enabling **Data Protection** in an app involves adding a specific entitlement in the Xcode project, which is then reflected in the app's entitlements file or the embedded mobile provision file for IPAs.<sup>[[2]](#references)</sup>
    206 
    207 For quick triage, the most interesting entitlement checks are usually:
    208 
    209 - **`get-task-allow`**: Development/debug build; especially interesting if you are assessing a test build or a re-signed IPA.
    210 - **`com.apple.security.application-groups`**: Shared file container across app/extension boundaries.
    211 - **`keychain-access-groups`**: Cross-target Keychain sharing.
    212 - **`com.apple.developer.associated-domains`**: Universal Links, web credentials, and related domain trust.
    213 - **Networking / VPN / extension entitlements**: Often indicate privileged OS integration or a larger attack surface than the main UI suggests.
    214 
    215 If the entitlements file isn't directly present in the package, extract it from the Mach-O as explained in [Extracting Entitlements from Compiled Application](/hacktricks/mobile-pentesting/ios-pentesting/extracting-entitlements-from-compiled-application).
    216 
    217 
    218 ## References
    219 
    220 - [1] [iOS Data Storage - OWASP MASTG](https://mas.owasp.org/MASTG/iOS/0x06d-Testing-Data-Storage)
    221 - [2] [MASTG-TEST-0069: Testing App Permissions - OWASP MASTG](https://mas.owasp.org/MASTG/tests/ios/MASVS-PLATFORM/MASTG-TEST-0069/)
    222 - [3] [iOS Platform APIs - OWASP MASTG](https://mas.owasp.org/MASTG/0x06h-Testing-Platform-Interaction/)
    223 - [4] [Keychain data protection - Apple Support](https://support.apple.com/guide/security/keychain-data-protection-secb0694df1a/web)
    224 - [5] [Rootless ( -l ) - palera1n docs](https://docs.palera.in/docs/reference/environment-types/)
    225 - [6] [iOS Platform APIs - OWASP owasp-mastg (0x06h-Testing-Platform-Interaction.md)](https://github.com/OWASP/owasp-mastg/blob/master/Document/0x06h-Testing-Platform-Interaction.md)