{{#include ../../banners/hacktricks-training.md}} # 权限分离和沙箱 在 iOS 中,用户可访问的应用程序与系统核心进程之间存在权限区分。应用程序在 **`mobile`** 用户身份下运行,而关键的系统进程则以 **`root`** 身份运行。这种分离通过沙箱机制得到了增强,该机制对应用程序可以执行的操作施加了严格的限制。例如,即使应用程序共享相同的用户身份,它们也被禁止访问或修改彼此的数据。 应用程序安装在特定目录(`private/var/mobile/Applications/{random ID}`)中,并对某些系统区域和功能(如短信和电话)具有有限的读取访问权限。访问受保护区域会触发用户权限请求的弹出窗口。 # 数据保护 iOS 为开发者提供了 **数据保护 API**,该 API 建立在安全隔离处理器(SEP)之上——一个专门用于加密操作和密钥管理的协处理器。SEP 通过嵌入其中的唯一设备特定密钥(设备 UID)确保数据保护的完整性。 在文件创建时,会生成一个唯一的 256 位 AES 加密密钥,用于加密文件内容。该加密密钥与类 ID 一起,使用类密钥进行加密并存储在文件的元数据中。解密文件涉及使用系统密钥访问元数据,使用类 ID 检索类密钥,然后解密文件的唯一加密密钥。 iOS 定义了 **四个保护类** 用于数据安全,这些保护类决定了何时以及如何访问数据: - **完全保护 (NSFileProtectionComplete)**:在设备使用用户密码解锁之前,数据不可访问。 - **除非打开受保护 (NSFileProtectionCompleteUnlessOpen)**:即使设备被锁定,只要在设备解锁时打开了文件,仍然允许访问文件。 - **直到首次用户身份验证受保护 (NSFileProtectionCompleteUntilFirstUserAuthentication)**:在首次用户解锁后,数据可访问,即使设备再次被锁定也保持可访问。 - **无保护 (NSFileProtectionNone)**:数据仅由设备 UID 保护,便于快速远程数据清除。 所有类的加密,除了 `NSFileProtectionNone`,都涉及一个由设备 UID 和用户密码派生的密钥,确保只有在具有正确密码的设备上才能解密。从 iOS 7 开始,默认保护类为“直到首次用户身份验证受保护”。 开发者可以使用 [**FileDP**](https://github.com/abjurato/FileDp-Source) 工具检查 iPhone 上文件的数据保护类。 ```python # Example code to use FileDP for checking file protection class # Note: Ensure your device is jailbroken and has Python installed to use FileDP. # Installation and usage of FileDP: git clone https://github.com/abjurato/FileDp-Source cd FileDp-Source python filedp.py /path/to/check ``` ## **钥匙串** 在 iOS 中,**钥匙串**作为一个安全的**加密容器**,用于存储**敏感信息**,仅可由存储它的应用程序或那些明确授权的应用程序访问。这种加密由 iOS 生成的唯一**密码**增强,该密码本身使用**AES**加密。此加密过程利用了**PBKDF2 函数**,将用户的密码与来自设备的**UID**的盐结合,只有**安全隔离芯片**可以访问该组件。因此,即使用户的密码已知,钥匙串的内容在任何其他设备上仍然无法访问,只有在最初加密的设备上才能访问。 **钥匙串数据的管理和访问**由**`securityd` 守护进程**处理,基于特定的应用程序权限,如 `Keychain-access-groups` 和 `application-identifier`。 ### **钥匙串 API 操作** 钥匙串 API 的详细信息见 [Apple's Keychain Services documentation](https://developer.apple.com/library/content/documentation/Security/Conceptual/keychainServConcepts/02concepts/concepts.html),提供了安全存储管理的基本功能: - **`SecItemAdd`**: 向钥匙串添加新项目。 - **`SecItemUpdate`**: 更新钥匙串中的现有项目。 - **`SecItemCopyMatching`**: 从钥匙串检索项目。 - **`SecItemDelete`**: 从钥匙串删除项目。 暴力破解钥匙串密码涉及直接攻击加密密钥或尝试在设备上猜测密码,这在很大程度上受到安全隔离的强制延迟的阻碍。 ### **配置钥匙串项目数据保护** 钥匙串项目的数据保护级别在项目创建或更新时使用 `kSecAttrAccessible` 属性设置。这些级别,[如 Apple 所指定](https://developer.apple.com/documentation/security/keychain_services/keychain_items/item_attribute_keys_and_values#1679100),决定了钥匙串项目何时以及如何可访问: - **`kSecAttrAccessibleAlways`**: 随时可访问,无论设备锁定状态如何。 - **`kSecAttrAccessibleAlwaysThisDeviceOnly`**: 始终可访问,但不包括在备份中。 - **`kSecAttrAccessibleAfterFirstUnlock`**: 在重启后第一次解锁后可访问。 - **`kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly`**: 与上述相同,但不可转移到新设备。 - **`kSecAttrAccessibleWhenUnlocked`**: 仅在设备解锁时可访问。 - **`kSecAttrAccessibleWhenUnlockedThisDeviceOnly`**: 解锁时可访问,不包括在备份中。 - **`kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly`**: 需要设备密码,不包括在备份中。 **`AccessControlFlags`** 进一步细化访问方法,允许使用生物识别认证或密码。 ### **越狱设备警告** > [!WARNING] > 在 **越狱设备**上,钥匙串的保护被破坏,构成重大安全风险。 ### **钥匙串数据的持久性** 与在应用程序卸载时删除的应用程序特定数据不同,**钥匙串数据在设备上持久存在**。这一特性可能使二手设备的新拥有者通过重新安装应用程序访问前一个拥有者的应用程序数据。建议开发者在应用程序安装或注销时主动清除钥匙串数据,以降低此风险。以下是一个 Swift 代码示例,演示如何在第一次应用程序启动时清除钥匙串数据: ```swift let userDefaults = UserDefaults.standard if userDefaults.bool(forKey: "hasRunBefore") == false { // Remove Keychain items here // Update the flag indicator userDefaults.set(true, forKey: "hasRunBefore") userDefaults.synchronize() // Forces the app to update UserDefaults } ``` # **应用程序能力** 在应用程序开发领域,**沙盒**在增强安全性方面发挥着至关重要的作用。此过程确保每个应用程序在其独特的主目录中运行,从而防止其访问系统文件或其他应用程序的数据。这些限制的执行是通过沙盒策略进行的,这些策略是**受信任的 BSD (MAC) 强制访问控制框架**的一部分。 开发人员可以为他们的应用程序配置某些**能力或权限**,例如**数据保护**或**钥匙串共享**。这些权限在应用程序安装后立即生效。然而,要访问某些受保护的资源,应用程序必须在第一次尝试时获得用户的明确同意。这是通过使用_目的字符串_或_使用描述字符串_来实现的,这些字符串在权限请求警报中呈现给用户。 对于有源代码访问权限的人,可以通过以下方式验证`Info.plist`文件中包含的权限: 1. 在 Xcode 中打开项目。 2. 找到并打开`Info.plist`文件。 3. 搜索以`"Privacy -"`为前缀的键,并可以查看原始键/值以便于理解。 处理 IPA 文件时,可以按照以下步骤进行: 1. 解压 IPA。 2. 在`Payload/.app/`中找到`Info.plist`文件。 3. 如有必要,将文件转换为 XML 格式,以便于检查。 例如,`Info.plist`文件中的目的字符串可能如下所示: ```xml NSLocationWhenInUseUsageDescription Your location is used to provide turn-by-turn directions to your destination. ``` ## 设备能力 应用的 `Info.plist` 文件指定了 **设备能力**,帮助 App Store 过滤与设备兼容的应用。这些在 **`UIRequiredDeviceCapabilities`** 键下定义。例如: ```xml UIRequiredDeviceCapabilities armv7 ``` 这个例子表明该应用程序与 armv7 指令集兼容。开发人员还可以指定能力,如 nfc,以确保他们的应用程序仅在支持 NFC 的设备上可用。 ## 权限 **权限** 是 iOS 应用开发的另一个关键方面,作为键值对,授予应用程序执行某些操作的权限,超出运行时检查。例如,在应用程序中启用 **数据保护** 涉及在 Xcode 项目中添加特定权限,这随后反映在应用程序的权限文件或 IPA 的嵌入式移动配置文件中。 # 参考文献 - [https://mas.owasp.org/MASTG/iOS/0x06d-Testing-Data-Storage](https://mas.owasp.org/MASTG/iOS/0x06d-Testing-Data-Storage) - [https://github.com/OWASP/owasp-mastg/blob/master/Document/0x06h-Testing-Platform-Interaction.md](https://github.com/OWASP/owasp-mastg/blob/master/Document/0x06h-Testing-Platform-Interaction.md) - [https://mas.owasp.org/MASTG/tests/ios/MASVS-PLATFORM/MASTG-TEST-0069/](https://mas.owasp.org/MASTG/tests/ios/MASVS-PLATFORM/MASTG-TEST-0069/) - [https://mas.owasp.org/MASTG/iOS/0x06h-Testing-Platform-Interaction/](https://mas.owasp.org/MASTG/iOS/0x06h-Testing-Platform-Interaction/) {{#include ../../banners/hacktricks-training.md}}