169 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# macOS 启动/环境约束与信任缓存
{{#include ../../../banners/hacktricks-training.md}}
## 基本信息
macOS 中的启动约束旨在通过**规范进程的启动方式、启动者和启动来源**来增强安全性。自 macOS Ventura 开始引入,它们提供了一个框架,将**每个系统二进制文件分类为不同的约束类别**,这些类别在**信任缓存**中定义,该列表包含系统二进制文件及其各自的哈希值。这些约束扩展到系统中的每个可执行二进制文件,涉及一组**规则**,规定了**启动特定二进制文件的要求**。规则包括二进制文件必须满足的自我约束、其父进程必须满足的父约束,以及其他相关实体必须遵守的责任约束​。
该机制通过**环境约束**扩展到第三方应用程序,自 macOS Sonoma 开始,允许开发者通过指定**一组环境约束的键和值**来保护他们的应用程序。
您可以在约束字典中定义**启动环境和库约束**,这些字典可以保存在**`launchd` 属性列表文件**中,或在代码签名中使用的**单独属性列表**文件中。
约束有 4 种类型:
- **自我约束**:应用于**运行中的**二进制文件的约束。
- **父进程**:应用于**进程的父进程**的约束(例如 **`launchd`** 运行 XP 服务)
- **责任约束**:应用于**在 XPC 通信中调用服务的进程**的约束
- **库加载约束**:使用库加载约束选择性地描述可以加载的代码
因此,当一个进程尝试通过调用 `execve(_:_:_:)``posix_spawn(_:_:_:_:_:_:)` 启动另一个进程时,操作系统会检查**可执行**文件是否**满足**其**自身的自我约束**。它还会检查**父进程**的可执行文件是否**满足**可执行文件的**父约束**,以及**责任进程**的可执行文件是否**满足**可执行文件的责任进程约束。如果这些启动约束中的任何一个不满足,操作系统将不会运行该程序。
如果在加载库时,**库约束**的任何部分不成立,您的进程**将不会加载**该库。
## LC 类别
LC 由**事实**和**逻辑操作**(与,或..)组成,结合事实。
[**LC 可以使用的事实已记录**](https://developer.apple.com/documentation/security/defining_launch_environment_and_library_constraints)。例如:
- is-init-proc一个布尔值指示可执行文件是否必须是操作系统的初始化进程`launchd`)。
- is-sip-protected一个布尔值指示可执行文件是否必须是受系统完整性保护SIP保护的文件。
- `on-authorized-authapfs-volume:` 一个布尔值,指示操作系统是否从授权的、经过身份验证的 APFS 卷加载了可执行文件。
- `on-authorized-authapfs-volume`:一个布尔值,指示操作系统是否从授权的、经过身份验证的 APFS 卷加载了可执行文件。
- Cryptexes 卷
- `on-system-volume:` 一个布尔值,指示操作系统是否从当前启动的系统卷加载了可执行文件。
- 在 /System 内...
- ...
当 Apple 二进制文件被签名时,它会**将其分配到信任缓存**中的 LC 类别。
- **iOS 16 LC 类别**已在此处[**反向工程并记录**](https://gist.github.com/LinusHenze/4cd5d7ef057a144cda7234e2c247c056)。
- 当前的 **LC 类别macOS 14 - Sonoma**已被反向工程,其[**描述可以在这里找到**](https://gist.github.com/theevilbit/a6fef1e0397425a334d064f7b6e1be53)。
例如,类别 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 类别
您可以在这里找到更多信息 [**关于它**](https://theevilbit.github.io/posts/launch_constraints_deep_dive/#reversing-constraints),但基本上,它们在 **AMFI (AppleMobileFileIntegrity)** 中定义,因此您需要下载内核开发工具包以获取 **KEXT**。以 **`kConstraintCategory`** 开头的符号是 **有趣** 的。提取它们后,您将获得一个 DER (ASN.1) 编码流,您需要使用 [ASN.1 解码器](https://holtstrom.com/michael/tools/asn1decoder.php) 或 python-asn1 库及其 `dump.py` 脚本 [andrivet/python-asn1](https://github.com/andrivet/python-asn1/tree/master) 进行解码,这将为您提供一个更易理解的字符串。
## 环境约束
这些是配置在 **第三方应用程序** 中的启动约束。开发人员可以选择在其应用程序中使用的 **事实****逻辑运算符** 来限制对自身的访问。
可以使用以下方法枚举应用程序的环境约束:
```bash
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`**。
> [!WARNING]
> 在运行在 Apple Silicon 设备上的 macOS 上,如果 Apple 签名的二进制文件不在信任缓存中AMFI 将拒绝加载它。
### 枚举信任缓存
之前的信任缓存文件格式为 **IMG4****IM4P**IM4P 是 IMG4 格式的有效载荷部分。
您可以使用 [**pyimg4**](https://github.com/m1stadev/PyIMG4) 来提取数据库的有效载荷:
```bash
# 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
```
(另一个选项是使用工具 [**img4tool**](https://github.com/tihmstar/img4tool),即使发布版本较旧,它也可以在 M1 上运行,并且如果您将其安装在正确的位置,它也可以在 x86_64 上运行)。
现在您可以使用工具 [**trustcache**](https://github.com/CRKatri/trustcache) 以可读格式获取信息:
```bash
# 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 列**
```c
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__));
```
然后,您可以使用像[**这个**](https://gist.github.com/xpn/66dc3597acd48a4c31f5f77c3cc62f30)这样的脚本来提取数据。
从这些数据中,您可以检查具有**启动约束值为`0`**的应用程序,这些应用程序没有受到约束([**在这里检查**](https://gist.github.com/LinusHenze/4cd5d7ef057a144cda7234e2c247c056)每个值的含义)。
## 攻击缓解
启动约束将通过**确保进程不会在意外条件下执行**来缓解几种旧攻击例如从意外位置启动或被意外的父进程调用如果只有launchd应该启动它
此外,启动约束还**缓解降级攻击**。
然而,它们**并不缓解常见的XPC**滥用、**Electron**代码注入或**dylib注入**而不进行库验证除非可以加载库的团队ID是已知的
### XPC守护进程保护
在Sonoma版本中一个显著的点是守护进程XPC服务的**责任配置**。XPC服务对自己负责而不是连接的客户端负责。这在反馈报告FB13206884中有记录。这个设置可能看起来有缺陷因为它允许与XPC服务进行某些交互
- **启动XPC服务**如果被认为是一个bug这个设置不允许通过攻击者代码启动XPC服务。
- **连接到活动服务**如果XPC服务已经在运行可能由其原始应用程序激活则没有连接到它的障碍。
虽然对XPC服务实施约束可能通过**缩小潜在攻击的窗口**而有益但它并没有解决主要问题。确保XPC服务的安全性根本上需要**有效验证连接的客户端**。这仍然是加强服务安全性的唯一方法。此外,值得注意的是,提到的责任配置目前是有效的,这可能与预期设计不符。
### Electron保护
即使要求应用程序必须**通过LaunchService打开**(在父约束中)。这可以通过使用**`open`**(可以设置环境变量)或使用**Launch Services API**(可以指示环境变量)来实现。
## 参考文献
- [https://youtu.be/f1HA5QhLQ7Y?t=24146](https://youtu.be/f1HA5QhLQ7Y?t=24146)
- [https://theevilbit.github.io/posts/launch_constraints_deep_dive/](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://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/](https://developer.apple.com/videos/play/wwdc2023/10266/)
{{#include ../../../banners/hacktricks-training.md}}