13 KiB
macOS启动/环境约束
☁️ HackTricks云 ☁️ -🐦 推特 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
- 你在一家网络安全公司工作吗?想要在HackTricks中看到你的公司广告吗?或者你想要获得PEASS的最新版本或下载PDF格式的HackTricks吗?请查看订阅计划!
- 发现我们的独家NFT收藏品The PEASS Family
- 获得官方PEASS和HackTricks周边产品
- 加入💬 Discord群组 或 Telegram群组 或 关注我在Twitter上的🐦@carlospolopm。
- 通过向hacktricks repo 和hacktricks-cloud repo 提交PR来分享你的黑客技巧
- .
基本信息
macOS中的启动约束旨在通过规定进程的启动方式、启动者和启动位置来增强安全性。从macOS Ventura开始引入,它们提供了一个框架,将每个系统二进制文件分类为不同的约束类别,并在信任缓存中定义这些约束类别,信任缓存是一个包含系统二进制文件及其哈希值的列表。这些约束适用于系统中的每个可执行二进制文件,包括一组规则,用于描述启动特定二进制文件的要求。这些规则包括二进制文件必须满足的自身约束、其父进程必须满足的父级约束,以及其他相关实体必须遵守的责任约束。
该机制通过环境约束扩展到第三方应用程序,从macOS Sonoma开始,允许开发人员通过指定一组键和值来保护其应用程序的环境约束。
您可以在**launchd
属性列表文件中保存约束字典,也可以在代码签名中使用单独的属性列表文件来定义启动环境和库约束**。
约束分为4种类型:
- 自身约束:应用于正在运行的二进制文件。
- 父进程约束:应用于进程的父进程(例如**
launchd
**运行的XP服务)。 - 责任约束:应用于通过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是:
Category 1:
Self Constraint: (on-authorized-authapfs-volume || on-system-volume) && launch-type == 1 && validation-category == 1
Parent Constraint: is-init-proc
(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,它将给你一个更易理解的字符串。
环境约束
这些是在第三方应用程序中配置的启动约束。开发者可以选择在应用程序中使用的事实和逻辑操作数来限制对其自身的访问。
可以使用以下命令枚举应用程序的环境约束:
codesign -d -vvvv app.app
信任缓存
在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
**。
枚举信任缓存
之前的信任缓存文件采用IMG4和IM4P格式,其中IM4P是IMG4格式的有效负载部分。
您可以使用pyimg4来提取数据库的有效负载:
{% code overflow="wrap" %}
# Installation
python3 -m pip install pyimg4
# Extract payloads data
cp /System/Volumes/Preboot/*/boot/*/usr/standalone/firmware/FUD/BaseSystemTrustCache.img4 /tmp
pyimg4 img4 extract -i /tmp/BaseSystemTrustCache.img4 -p /tmp/BaseSystemTrustCache.im4p
pyimg4 im4p extract -i /tmp/BaseSystemTrustCache.im4p -o /tmp/BaseSystemTrustCache.data
cp /System/Volumes/Preboot/*/boot/*/usr/standalone/firmware/FUD/StaticTrustCache.img4 /tmp
pyimg4 img4 extract -i /tmp/StaticTrustCache.img4 -p /tmp/StaticTrustCache.im4p
pyimg4 im4p extract -i /tmp/StaticTrustCache.im4p -o /tmp/StaticTrustCache.data
pyimg4 im4p extract -i /System/Library/Security/OSLaunchPolicyData -o /tmp/OSLaunchPolicyData.data
{% endcode %}
(另一个选择是使用工具img4tool,即使是旧版本也可以在M1上运行,如果您将其安装在正确的位置,也可以在x86_64上运行)。
现在,您可以使用工具trustcache以可读格式获取信息:
# Install
wget https://github.com/CRKatri/trustcache/releases/download/v2.0/trustcache_macos_arm64
sudo mv ./trustcache_macos_arm64 /usr/local/bin/trustcache
xattr -rc /usr/local/bin/trustcache
chmod +x /usr/local/bin/trustcache
# Run
trustcache info /tmp/OSLaunchPolicyData.data | head
trustcache info /tmp/StaticTrustCache.data | head
trustcache info /tmp/BaseSystemTrustCache.data | head
version = 2
uuid = 35EB5284-FD1E-4A5A-9EFB-4F79402BA6C0
entry count = 969
0065fc3204c9f0765049b82022e4aa5b44f3a9c8 [none] [2] [1]
00aab02b28f99a5da9b267910177c09a9bf488a2 [none] [2] [1]
0186a480beeee93050c6c4699520706729b63eff [none] [2] [2]
0191be4c08426793ff3658ee59138e70441fc98a [none] [2] [3]
01b57a71112235fc6241194058cea5c2c7be3eb1 [none] [2] [2]
01e6934cb8833314ea29640c3f633d740fc187f2 [none] [2] [2]
020bf8c388deaef2740d98223f3d2238b08bab56 [none] [2] [3]
信任缓存遵循以下结构,因此LC类别是第4列。
struct trust_cache_entry2 {
uint8_t cdhash[CS_CDHASH_LEN];
uint8_t hash_type;
uint8_t flags;
uint8_t constraintCategory;
uint8_t reserved0;
} __attribute__((__packed__));
然后,您可以使用此脚本之类的脚本来提取数据。
从这些数据中,您可以检查具有**启动约束值为0
**的应用程序,这些应用程序没有受到约束(在此处检查每个值的含义)。
攻击缓解
启动约束可以通过确保进程不会在意外条件下执行来缓解多个旧攻击:例如,来自意外位置的执行或由意外父进程调用(如果只有launchd应该启动它)。
此外,启动约束还可以缓解降级攻击。
然而,它们无法缓解常见的XPC滥用、Electron代码注入或没有库验证的dylib注入(除非已知可以加载库的团队ID)。
XPC守护进程保护
在撰写本文时(Sonoma版本),守护进程XPC服务的负责进程是XPC服务本身,而不是连接的客户端(提交FB:FB13206884)。假设有一秒钟的时间,我们仍然无法在攻击者代码中启动XPC服务,但如果它已经处于活动状态(可能是因为原始应用程序调用了它),那么没有任何阻止我们连接到它的措施。因此,尽管设置约束可能是个好主意,并且会限制攻击时间范围,但它并不能解决主要问题,我们的XPC服务仍然应该正确验证连接的客户端。这仍然是保护它的唯一方法。而且正如一开始提到的,现在它甚至不起作用。
Electron保护
即使要求应用程序必须通过LaunchService打开(在父进程的约束中)。这可以通过使用**open
(可以设置环境变量)或使用Launch Services API**(可以指示环境变量)来实现。
参考资料
- https://youtu.be/f1HA5QhLQ7Y?t=24146
- https://theevilbit.github.io/posts/launch_constraints_deep_dive/
- https://eclecticlight.co/2023/06/13/why-wont-a-system-app-or-command-tool-run-launch-constraints-and-trust-caches/
- https://developer.apple.com/videos/play/wwdc2023/10266/
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
- 您在网络安全公司工作吗?您想在HackTricks中为您的公司做广告吗?或者您想获得PEASS的最新版本或下载PDF格式的HackTricks吗?请查看订阅计划!
- 发现我们的独家NFT收藏品The PEASS Family
- 获得官方PEASS和HackTricks周边产品
- 加入💬 Discord群组或电报群组,或在Twitter上关注我🐦@carlospolopm。
- 通过向hacktricks repo 和hacktricks-cloud repo 提交PR来分享您的黑客技巧
- .