hacktricks/mobile-pentesting/ios-pentesting/ios-basics.md
2023-08-03 19:12:22 +00:00

18 KiB
Raw Blame History

☁️ HackTricks云 ☁️ -🐦 推特 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥

特权分离和沙盒

用户可以访问的应用程序以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-groupsapplication-identifierapplication-group授权来授予访问权限。

密钥链API包括以下主要操作:

  • SecItemAdd
  • SecItemUpdate
  • SecItemCopyMatching
  • SecItemDelete

尝试破解此密码的唯一方法是转储加密的密钥并尝试破解密码 + 盐(pbkdf2函数使用至少10000次迭代)。或者尝试在设备内部进行破解以避免破解盐,但是,安全区域确保在两次失败的密码尝试之间至少有5秒的延迟

您可以通过在调用SecItemAddSecItemUpdate时设置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通过kSecAccessControlBiometryAnykSecAccessControlBiometryCurrentSet保护的密钥受到安全区的保护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数据。这将允许用户在卸载应用程序之前清除他们的账户。

应用程序功能

每个应用程序都有一个唯一的主目录,并且被沙箱化因此它们无法访问受保护的系统资源或系统或其他应用程序存储的文件。这些限制是通过沙箱策略也称为_配置文件_实施的可信BSDMAC强制访问控制框架通过内核扩展来执行。

一些功能/权限可以由应用程序的开发人员配置(例如数据保护或钥匙串共享),并且在安装后将直接生效。然而,对于其他一些功能,用户将在应用程序首次尝试访问受保护资源时被明确询问

目的字符串或_用途描述字符串_是在系统的权限请求警报中向用户提供的自定义文本用于请求访问受保护数据或资源的权限。

如果有原始源代码,您可以验证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 🎥