macOS Launch/Environment Constraints & Trust Cache
基本信息
macOS中的启动约束旨在通过规范进程的启动方式、启动者和启动位置来增强安全性。在macOS Ventura中引入,它们提供了一个框架,将每个系统二进制文件分类为不同的约束类别,这些类别在信任缓存中定义,其中包含系统二进制文件及其相应哈希值的列表。这些约束扩展到系统中的每个可执行二进制文件,包括一组规则,详细说明启动特定二进制文件的要求。这些规则包括二进制文件必须满足的自身约束、其父进程必须满足的父约束,以及其他相关实体必须遵守的责任约束。
这种机制通过环境约束扩展到第三方应用程序,从macOS Sonoma开始,允许开发人员通过指定一组键和值的环境约束来保护其应用程序。
您可以在**launchd
属性列表文件中保存的约束字典中定义启动环境和库约束**,或者在用于代码签名的单独属性列表文件中定义。
有4种类型的约束:
自身约束:应用于运行中的二进制文件。
父进程约束:应用于进程的父进程(例如运行XP服务的**
launchd
**)。责任约束:应用于通过XPC通信调用服务的进程。
库加载约束:使用库加载约束有选择地描述可加载的代码。
因此,当一个进程尝试启动另一个进程时 — 通过调用execve(_:_:_:)
或posix_spawn(_:_:_:_:_:_:)
— 操作系统会检查可执行文件是否满足其自身约束。它还会检查父进程的可执行文件是否满足可执行文件的父约束,以及负责进程的可执行文件是否满足可执行文件的责任约束。如果这些启动约束中的任何一个不满足,操作系统将不运行该程序。
如果在加载库时库约束的任何部分不成立,您的进程不会加载该库。
LC类别
LC由事实和逻辑操作(与、或等)组成,结合事实。
LC可以使用的事实已记录。例如:
is-init-proc:一个布尔值,指示可执行文件是否必须是操作系统的初始化进程(
launchd
)。is-sip-protected:一个布尔值,指示可执行文件是否必须是受系统完整性保护(SIP)保护的文件。
on-authorized-authapfs-volume:
一个布尔值,指示操作系统是否从经授权的、经认证的APFS卷加载了可执行文件。on-authorized-authapfs-volume
:一个布尔值,指示操作系统是否从经授权的、经认证的APFS卷加载了可执行文件。Cryptexes卷
on-system-volume:
一个布尔值,指示操作系统是否从当前引导的系统卷加载了可执行文件。在/System...
...
当苹果二进制文件签名时,它会将其分配到信任缓存中的LC类别中。
例如,类别1是:
(on-authorized-authapfs-volume || on-system-volume)
: 必须位于系统或Cryptexes卷中。launch-type == 1
: 必须是系统服务(在LaunchDaemons中的plist)。validation-category == 1
: 操作系统可执行文件。is-init-proc
: Launchd
反向 LC 类别
您可以在这里了解更多信息,但基本上,它们在AMFI(AppleMobileFileIntegrity)中定义,因此您需要下载内核开发工具包以获取KEXT。以**kConstraintCategory
开头的符号是有趣的**。提取它们,您将获得一个DER(ASN.1)编码流,您需要使用ASN.1解码器或python-asn1库及其dump.py
脚本进行解码,andrivet/python-asn1,这将为您提供更易理解的字符串。
环境约束
这些是配置在第三方应用程序中的Launch Constraints。开发人员可以选择在其应用程序中使用的事实和逻辑操作数来限制对其自身的访问。
可以使用以下方法枚举应用程序的环境约束:
信任缓存
在macOS中有几个信任缓存:
/System/Volumes/Preboot/*/boot/*/usr/standalone/firmware/FUD/BaseSystemTrustCache.img4
/System/Volumes/Preboot/*/boot/*/usr/standalone/firmware/FUD/StaticTrustCache.img4
/System/Library/Security/OSLaunchPolicyData
而在iOS中,看起来是在**/usr/standalone/firmware/FUD/StaticTrustCache.img4
**中。
在运行在苹果硅设备上的macOS中,如果苹果签名的二进制文件不在信任缓存中,AMFI将拒绝加载它。
枚举信任缓存
之前的信任缓存文件是以IMG4和IM4P格式,其中IM4P是IMG4格式的有效负载部分。
您可以使用pyimg4来提取数据库的有效负载:
(另一个选择是使用工具img4tool,即使发布版本较旧且适用于x86_64,如果您将其安装在正确的位置,它也可以在M1上运行)。
现在,您可以使用工具trustcache以可读格式获取信息:
信任缓存遵循以下结构,因此LC类别是第4列
然后,您可以使用此脚本来提取数据。
从这些数据中,您可以检查具有0
启动约束值的应用程序,这些应用程序是没有受到约束的(在此处检查每个值代表什么)。
攻击缓解
启动约束将通过确保进程不会在意外条件下执行来缓解几种旧攻击:例如来自意外位置的执行或被意外父进程调用(如果只有launchd应该启动它)。
此外,启动约束还缓解了降级攻击。
然而,它们无法缓解常见的XPC滥用、Electron代码注入或没有库验证的dylib注入(除非已知可以加载库的团队ID)。
XPC守护程序保护
在Sonoma版本中,一个值得注意的点是守护程序XPC服务的责任配置。XPC服务对自身负责,而不是连接的客户端负责。这在反馈报告FB13206884中有记录。这种设置可能看起来有缺陷,因为它允许与XPC服务进行某些交互:
启动XPC服务:如果被认为是一个错误,这种设置不允许通过攻击者代码启动XPC服务。
连接到活动服务:如果XPC服务已经运行(可能由其原始应用程序激活),则连接到它没有障碍。
尽管对XPC服务实施约束可能有助于缩小潜在攻击的窗口,但它并未解决主要问题。确保XPC服务的安全性基本上需要有效验证连接的客户端。这仍然是加固服务安全性的唯一方法。另外值得注意的是,所述的责任配置目前正在运行,这可能与预期的设计不符。
Electron保护
即使要求应用程序必须在由LaunchService打开(在父级约束中)。这可以通过**open
(可以设置环境变量)或使用Launch Services API**(可以指定环境变量)来实现。
参考资料
最后更新于