18 KiB
☁️ HackTricks云 ☁️ -🐦 推特 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
-
你在一个网络安全公司工作吗?你想在HackTricks中看到你的公司广告吗?或者你想获得PEASS的最新版本或下载PDF格式的HackTricks吗?请查看订阅计划!
-
发现我们的独家NFTs收藏品- The PEASS Family
-
加入 💬 Discord群组 或 电报群组 或 关注我在Twitter上的 🐦@carlospolopm.
-
通过向hacktricks repo和hacktricks-cloud repo提交PR来分享你的黑客技巧。
特权分离和沙盒
用户可以访问的应用程序以mobile用户身份运行,而关键的系统进程以root身份运行。
然而,沙盒允许更好地控制进程和应用程序可以执行的操作。
例如,即使两个进程以相同的用户(mobile)身份运行,它们也不被允许访问或修改彼此的数据。
每个应用程序都安装在**private/var/mobile/Applications/{random ID}
下
一旦安装,应用程序对一些系统区域和功能(短信、电话等)具有有限的读取访问权限。如果应用程序想要访问受保护的区域**,会出现一个请求权限的弹窗。
数据保护
应用程序开发人员可以利用iOS的数据保护API来实现对存储在闪存中的用户数据的细粒度访问控制。这些API建立在安全区域处理器(SEP)之上。SEP是一个协处理器,提供用于数据保护和密钥管理的加密操作。一个设备特定的硬件密钥-设备UID(唯一标识符)-被嵌入在安全区域中,确保数据保护的完整性,即使操作系统内核被破坏。
当在磁盘上创建文件时,会使用安全区域的硬件随机数生成器生成一个新的256位AES密钥。然后,使用生成的密钥对文件的内容进行加密。然后,将此密钥与类密钥一起加密保存在文件的元数据中,同时两者的数据都由系统的密钥加密。
要解密文件,需要使用系统的密钥对元数据进行解密。然后,使用类ID检索类密钥,以解密每个文件的密钥并解密文件。
文件可以分配给四个不同的保护类,这些类在Apple平台安全指南中有更详细的解释:
- 完全保护(NSFileProtectionComplete):使用用户密码和设备UID派生的密钥来保护此类密钥。在设备锁定后不久,派生密钥将从内存中清除,使数据在用户解锁设备之前无法访问。
- 除非打开保护(NSFileProtectionCompleteUnlessOpen):此保护类与完全保护类类似,但如果在解锁时打开文件,则即使用户锁定设备,应用程序仍然可以继续访问文件。例如,当后台下载邮件附件时使用此保护类。
- 直到首次用户身份验证保护(NSFileProtectionCompleteUntilFirstUserAuthentication):在用户首次启动设备后,可以立即访问文件。即使用户随后锁定设备,类密钥也不会从内存中删除,仍然可以访问文件。
- 无保护(NSFileProtectionNone):此保护类的密钥仅由UID保护。类密钥存储在“可擦除存储”中,这是iOS设备上允许存储少量数据的闪存区域。此保护类用于快速远程擦除(立即删除类密钥,使数据无法访问)。
除了NSFileProtectionNone
之外的所有类密钥都使用从设备UID和用户的密码派生的密钥进行加密。因此,解密只能在设备本身上进行,并且需要正确的密码。
自iOS 7以来,默认的数据保护类是“Protected Until First User Authentication”。
FileDP是一个可以在iPhone内部上传和使用的程序,用于检查每个文件的数据保护类。
密钥链
密钥链是一个加密的容器,每个应用程序都可以在其中存储****敏感的信息,只有相同的应用程序(或经授权的应用程序)才能检索内容。
iOS会为密钥链生成自己的密码,并将此密码的加密版本存储在设备中。此密码使用AES加密,使用由用户的密码 + 盐(256位设备UID,仅安全区域芯片组可访问)的PBKDF2函数创建的AES密钥进行加密。由于使用设备UID作为盐,即使知道用户的密码,设备也无法解密不同设备的密钥链。
对密钥链的访问由**securityd
**守护程序管理,根据应用程序的Keychain-access-groups
、application-identifier
和application-group
授权来授予访问权限。
密钥链API包括以下主要操作:
SecItemAdd
SecItemUpdate
SecItemCopyMatching
SecItemDelete
尝试破解此密码的唯一方法是转储加密的密钥并尝试破解密码 + 盐(pbkdf2函数使用至少10000次迭代)。或者尝试在设备内部进行破解以避免破解盐,但是,安全区域确保在两次失败的密码尝试之间至少有5秒的延迟。
您可以通过在调用SecItemAdd
或SecItemUpdate
时设置kSecAttrAccessible
键来配置密钥链项的数据保护。以下可配置的kSecAttrAccessible的可访问性值是密钥链数据保护类:
kSecAttrAccessibleAlways
: Keychain项中的数据始终可以访问,无论设备是否被锁定。kSecAttrAccessibleAlwaysThisDeviceOnly
: Keychain项中的数据始终可以访问,无论设备是否被锁定。数据不会包含在iCloud或本地备份中。kSecAttrAccessibleAfterFirstUnlock
: 在设备被用户解锁一次之前,无法访问Keychain项中的数据。kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly
: 在设备被用户解锁一次之前,无法访问Keychain项中的数据。具有此属性的项不会迁移到新设备。因此,在从不同设备的备份恢复后,这些项将不会存在。kSecAttrAccessibleWhenUnlocked
: 只有在设备被用户解锁时才能访问Keychain项中的数据。kSecAttrAccessibleWhenUnlockedThisDeviceOnly
: 只有在设备被用户解锁时才能访问Keychain项中的数据。数据不会包含在iCloud或本地备份中。kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly
: 只有在设备被解锁时才能访问Keychain中的数据。此保护级别仅在设备上设置了密码时可用。数据不会包含在iCloud或本地备份中。
**AccessControlFlags
**定义了用户可以通过哪些机制进行密钥认证(SecAccessControlCreateFlags
):
kSecAccessControlDevicePasscode
: 通过密码访问项。kSecAccessControlBiometryAny
: 通过已注册到Touch ID的指纹之一访问项。添加或删除指纹不会使项无效。kSecAccessControlBiometryCurrentSet
: 通过已注册到Touch ID的指纹之一访问项。添加或删除指纹将使项无效。kSecAccessControlUserPresence
: 通过已注册的指纹(使用Touch ID)之一访问项,否则使用密码。
请注意,通过Touch ID(通过kSecAccessControlBiometryAny
或kSecAccessControlBiometryCurrentSet
)保护的密钥受到安全区的保护:Keychain仅保存令牌,而不是实际密钥。密钥驻留在安全区中。
iPhone使用用户解锁设备时输入的密码来解密Keychain中的密钥。
iOS使用_AppIdentifierPrefix_(团队ID)和_BundleIdentifier_(由开发者提供)来强制执行对Keychain项的访问控制。然后,同一团队可以配置2个应用程序共享Keychain项。
在备份过程启动时,Keychain中的数据保持加密,Keychain密码不包含在备份中。
{% hint style="warning" %} 越狱设备中的Keychain没有受到保护。 {% endhint %}
Keychain数据持久性
在iOS上,当应用程序被卸载时,应用程序使用的Keychain数据会被设备保留,而应用程序沙盒中存储的数据会被清除。如果用户在不进行恢复出厂设置的情况下出售设备,购买者可以通过重新安装之前用户使用的相同应用程序来访问先前用户的应用程序帐户和数据。这不需要进行技术操作。
开发人员无法使用iOS API在应用程序被卸载时强制清除数据。相反,开发人员应采取以下步骤防止Keychain数据在应用程序安装之间持久存在:
- 在应用程序安装后首次启动时,清除与应用程序相关的所有Keychain数据。这将防止设备的第二个用户意外访问先前用户的帐户。以下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
}
- 在开发iOS应用程序的注销功能时,确保在账户注销时清除Keychain数据。这将允许用户在卸载应用程序之前清除他们的账户。
应用程序功能
每个应用程序都有一个唯一的主目录,并且被沙箱化,因此它们无法访问受保护的系统资源或系统或其他应用程序存储的文件。这些限制是通过沙箱策略(也称为_配置文件_)实施的,由可信BSD(MAC)强制访问控制框架通过内核扩展来执行。
一些功能/权限可以由应用程序的开发人员配置(例如数据保护或钥匙串共享),并且在安装后将直接生效。然而,对于其他一些功能,用户将在应用程序首次尝试访问受保护资源时被明确询问。
目的字符串或_用途描述字符串_是在系统的权限请求警报中向用户提供的自定义文本,用于请求访问受保护数据或资源的权限。
如果有原始源代码,您可以验证Info.plist
文件中包含的权限:
- 使用Xcode打开项目。
- 在默认编辑器中找到并打开
Info.plist
文件,并搜索以"Privacy -"
开头的键。
您可以通过右键单击并选择“显示原始键/值”来切换视图以显示原始值(例如,"Privacy - Location When In Use Usage Description"
将变为NSLocationWhenInUseUsageDescription
)。
如果只有IPA文件:
- 解压IPA文件。
Info.plist
位于Payload/<appname>.app/Info.plist
。- 根据需要进行转换(例如,
plutil -convert xml1 Info.plist
),如“iOS基本安全测试”章节中的“Info.plist文件”中所述。 - 检查所有以_用途描述Info.plist键_结尾的键,通常以
UsageDescription
结尾:
<plist version="1.0">
<dict>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Your location is used to provide turn-by-turn directions to your destination.</string>
设备功能
设备功能用于App Store确保仅列出兼容的设备,并因此允许下载该应用程序。它们在应用程序的Info.plist
文件中的UIRequiredDeviceCapabilities
键下指定。
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
通常你会发现
armv7
能力,这意味着应用程序仅针对armv7指令集进行编译,或者如果它是一个32/64位通用应用程序。
例如,一个应用可能完全依赖于NFC来工作(例如一个"NFC标签阅读器"应用)。根据存档的iOS设备兼容性参考,NFC仅在iPhone 7(和iOS 11)之后可用。开发人员可能希望通过设置nfc
设备能力来排除所有不兼容的设备。
权限
权限是一对键值对,被签入应用程序并允许身份验证超出运行时因素,如UNIX用户ID。由于权限是数字签名的,它们无法更改。系统应用程序和守护程序广泛使用权限来执行特定的特权操作,否则需要以root身份运行的进程。这极大地减少了被损坏的系统应用程序或守护程序提升特权的可能性。
例如,如果您想设置"默认数据保护"能力,您需要进入Xcode的Capabilities选项卡,并启用数据保护。这将由Xcode直接写入到<appname>.entitlements
文件中,作为com.apple.developer.default-data-protection
权限,其默认值为NSFileProtectionComplete
。在IPA中,我们可能会在embedded.mobileprovision
中找到这个:
<key>Entitlements</key>
<dict>
...
<key>com.apple.developer.default-data-protection</key>
<string>NSFileProtectionComplete</string>
</dict>
对于其他功能,如HealthKit,用户必须被要求授权,因此仅添加权限是不够的,还必须在应用的Info.plist
文件中添加特殊的键和字符串。
Objective-C和Swift基础知识
Objective-C具有动态运行时,因此当在iOS中执行Objective-C程序时,它通过将消息中发送的函数名称与所有可用函数名称的列表进行比较,来调用在运行时解析地址的库。
起初,只有由Apple创建的应用程序在iPhone上运行,因此它们可以访问一切,因为它们是受信任的。然而,当Apple允许第三方应用程序时,Apple只是删除了强大功能的头文件,以将它们对开发人员进行“隐藏”。然而,开发人员发现“安全”功能需要一些这些未记录的功能,只需创建一个具有未记录功能名称的自定义头文件,就可以调用这些强大的隐藏功能。实际上,在允许应用程序发布之前,Apple会检查应用程序是否调用了任何这些被禁止的功能。
然后,出现了Swift。由于Swift是静态绑定的(它不像Objective-C那样在运行时解析函数的地址),可以通过静态代码分析更容易地检查Swift程序即将进行的调用。
设备管理
从iOS 6版本开始,内置了对设备管理功能的支持,具有细粒度的控制,允许组织控制企业苹果设备。
注册可以由用户通过安装代理来启动,以便访问企业应用程序。在这种情况下,设备通常属于用户。
或者,公司可以指定购买设备的序列号或采购订单ID,并指定要在这些设备上安装的MDM配置文件。请注意,Apple不允许以这种方式注册特定设备两次。一旦删除了第一个配置文件,用户需要同意安装另一个配置文件。
用户可以在_设置_ --> 通用 --> _描述文件与设备管理_中查看已安装的策略。
由于这些MDM策略正在检查和限制其他应用程序,因此它们以更高的权限运行。
MDM策略可以强制用户设置具有最小密码复杂性的密码。
配置文件与设备ID绑定,由MDM服务器进行签名和加密,并且防篡改。它们不能被删除,否则将丢失所有企业数据。
如果有X次密码尝试失败,MDM配置文件可以擦除所有数据。此外,管理员可以通过MDM界面随时远程擦除iPhone。
MDM代理还将检查设备是否可能被越狱,因为这对于iPhone来说是非常危险的状态。
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
-
你在一家网络安全公司工作吗?想要在HackTricks中宣传你的公司吗?或者想要获取PEASS的最新版本或下载PDF格式的HackTricks吗?请查看订阅计划!
-
发现我们的独家NFT收藏品——The PEASS Family
-
加入💬 Discord群组或电报群组,或在Twitter上关注我🐦@carlospolopm。
-
通过向hacktricks repo和hacktricks-cloud repo提交PR来分享你的黑客技巧。