mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-15 09:27:32 +00:00
Translated ['macos-hardening/macos-security-and-privilege-escalation/mac
This commit is contained in:
parent
b73102126b
commit
820d37d8bd
5 changed files with 601 additions and 254 deletions
|
@ -175,6 +175,7 @@
|
|||
* [macOS Java Applications Injection](macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-java-apps-injection.md)
|
||||
* [macOS Library Injection](macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-library-injection/README.md)
|
||||
* [macOS Dyld Hijacking & DYLD\_INSERT\_LIBRARIES](macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-library-injection/macos-dyld-hijacking-and-dyld\_insert\_libraries.md)
|
||||
* [macOS Dyld Process](macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-library-injection/macos-dyld-process.md)
|
||||
* [macOS Perl Applications Injection](macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-perl-applications-injection.md)
|
||||
* [macOS Python Applications Injection](macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-python-applications-injection.md)
|
||||
* [macOS Ruby Applications Injection](macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-ruby-applications-injection.md)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# macOS文件夹、文件和二进制文件与内存
|
||||
# macOS文件夹、文件和二进制文件 & 内存
|
||||
|
||||
<details>
|
||||
|
||||
|
@ -6,46 +6,46 @@
|
|||
|
||||
支持HackTricks的其他方式:
|
||||
|
||||
- 如果您想看到您的**公司在HackTricks中做广告**或**下载PDF格式的HackTricks**,请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
|
||||
- 获取[**官方PEASS和HackTricks周边产品**](https://peass.creator-spring.com)
|
||||
- 发现[**PEASS家族**](https://opensea.io/collection/the-peass-family),我们的独家[NFT](https://opensea.io/collection/the-peass-family)收藏品
|
||||
- **加入** 💬 [**Discord群**](https://discord.gg/hRep4RUj7f) 或 [**电报群**](https://t.me/peass) 或 **关注**我们的**Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**。**
|
||||
- 通过向[**HackTricks**](https://github.com/carlospolop/hacktricks)和[**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github仓库提交PR来分享您的黑客技巧。
|
||||
* 如果您想看到您的**公司在HackTricks中做广告**或**下载PDF格式的HackTricks**,请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
|
||||
* 获取[**官方PEASS & HackTricks周边产品**](https://peass.creator-spring.com)
|
||||
* 探索[**PEASS家族**](https://opensea.io/collection/the-peass-family),我们的独家[NFTs](https://opensea.io/collection/the-peass-family)收藏品
|
||||
* **加入** 💬 [**Discord群**](https://discord.gg/hRep4RUj7f) 或 [**电报群**](https://t.me/peass) 或 **关注**我们的**Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**。**
|
||||
* 通过向[**HackTricks**](https://github.com/carlospolop/hacktricks)和[**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github仓库提交PR来分享您的黑客技巧。
|
||||
|
||||
</details>
|
||||
|
||||
## 文件层次结构
|
||||
|
||||
- **/Applications**:已安装的应用程序应位于此处。所有用户都可以访问它们。
|
||||
- **/bin**:命令行二进制文件
|
||||
- **/cores**:如果存在,用于存储核心转储
|
||||
- **/dev**:一切都被视为文件,因此您可能会在此处看到存储的硬件设备。
|
||||
- **/etc**:配置文件
|
||||
- **/Library**:可以在此处找到许多与首选项、缓存和日志相关的子目录和文件。根目录和每个用户目录中都存在一个Library文件夹。
|
||||
- **/private**:未记录,但许多提到的文件夹是符号链接到私有目录的。
|
||||
- **/sbin**:基本系统二进制文件(与管理相关)
|
||||
- **/System**:使OS X运行的文件。您应该在这里主要只找到Apple特定的文件(而不是第三方文件)。
|
||||
- **/tmp**:文件将在3天后被删除(这是指向/private/tmp的软链接)
|
||||
- **/Users**:用户的主目录。
|
||||
- **/usr**:配置和系统二进制文件
|
||||
- **/var**:日志文件
|
||||
- **/Volumes**:挂载的驱动器将出现在这里。
|
||||
- **/.vol**:运行`stat a.txt`,您将获得类似`16777223 7545753 -rw-r--r-- 1 username wheel ...`的内容,其中第一个数字是文件所在卷的ID号,第二个数字是索引节点号。您可以通过/.vol/访问具有该信息的文件的内容,运行`cat /.vol/16777223/7545753`
|
||||
* **/Applications**:已安装的应用程序应位于此处。所有用户都可以访问它们。
|
||||
* **/bin**:命令行二进制文件
|
||||
* **/cores**:如果存在,用于存储核心转储
|
||||
* **/dev**:一切都被视为文件,因此您可能会在此处看到存储的硬件设备。
|
||||
* **/etc**:配置文件
|
||||
* **/Library**:可以在此处找到许多与首选项、缓存和日志相关的子目录和文件。根目录和每个用户目录中都存在一个Library文件夹。
|
||||
* **/private**:未记录,但许多提到的文件夹是符号链接到私有目录。
|
||||
* **/sbin**:基本系统二进制文件(与管理相关)
|
||||
* **/System**:使OS X运行的文件。您应该在这里主要找到Apple特定的文件(而不是第三方文件)。
|
||||
* **/tmp**:文件将在3天后被删除(这是指向/private/tmp的软链接)
|
||||
* **/Users**:用户的主目录。
|
||||
* **/usr**:配置和系统二进制文件
|
||||
* **/var**:日志文件
|
||||
* **/Volumes**:挂载的驱动器将出现在这里。
|
||||
* **/.vol**:运行`stat a.txt`,您将获得类似`16777223 7545753 -rw-r--r-- 1 username wheel ...`的内容,其中第一个数字是文件所在卷的ID号,第二个数字是索引节点号。您可以通过/.vol/访问该文件的内容,使用该信息运行`cat /.vol/16777223/7545753`
|
||||
|
||||
### 应用程序文件夹
|
||||
|
||||
- **系统应用程序**位于`/System/Applications`
|
||||
- **已安装的**应用程序通常安装在`/Applications`或`~/Applications`
|
||||
- **应用程序数据**可以在`/Library/Application Support`中找到,用于以root身份运行的应用程序,以及在`~/Library/Application Support`中找到,用于以用户身份运行的应用程序。
|
||||
- **需要以root身份运行**的第三方应用程序**守护程序**通常位于`/Library/PrivilegedHelperTools/`
|
||||
- **沙箱**应用程序映射到`~/Library/Containers`文件夹。每个应用程序都有一个根据应用程序的捆绑ID(`com.apple.Safari`)命名的文件夹。
|
||||
- **内核**位于`/System/Library/Kernels/kernel`
|
||||
- **Apple的内核扩展**位于`/System/Library/Extensions`
|
||||
- **第三方内核扩展**存储在`/Library/Extensions`
|
||||
* **系统应用程序**位于`/System/Applications`
|
||||
* **已安装的**应用程序通常安装在`/Applications`或`~/Applications`
|
||||
* **应用程序数据**可以在`/Library/Application Support`中找到,用于以root身份运行的应用程序,以及在`~/Library/Application Support`中找到,用于以用户身份运行的应用程序。
|
||||
* **需要以root身份运行**的第三方应用程序**守护程序**通常位于`/Library/PrivilegedHelperTools/`
|
||||
* **沙箱**应用程序映射到`~/Library/Containers`文件夹。每个应用程序都有一个根据应用程序的捆绑ID(`com.apple.Safari`)命名的文件夹。
|
||||
* **内核**位于`/System/Library/Kernels/kernel`
|
||||
* **Apple的内核扩展**位于`/System/Library/Extensions`
|
||||
* **第三方内核扩展**存储在`/Library/Extensions`
|
||||
|
||||
### 包含敏感信息的文件
|
||||
|
||||
macOS在几个位置存储诸如密码之类的信息:
|
||||
MacOS在几个位置存储诸如密码之类的信息:
|
||||
|
||||
{% content-ref url="macos-sensitive-locations.md" %}
|
||||
[macos-sensitive-locations.md](macos-sensitive-locations.md)
|
||||
|
@ -59,23 +59,23 @@ macOS在几个位置存储诸如密码之类的信息:
|
|||
|
||||
## OS X特定扩展
|
||||
|
||||
- **`.dmg`**:苹果磁盘映像文件在安装程序中非常常见。
|
||||
- **`.kext`**:它必须遵循特定结构,是驱动程序的OS X版本(它是一个捆绑包)。
|
||||
- **`.plist`**:也称为属性列表,以XML或二进制格式存储信息。
|
||||
- 可以是XML或二进制。可以使用以下命令读取二进制文件:
|
||||
- `defaults read config.plist`
|
||||
- `/usr/libexec/PlistBuddy -c print config.plsit`
|
||||
- `plutil -p ~/Library/Preferences/com.apple.screensaver.plist`
|
||||
- `plutil -convert xml1 ~/Library/Preferences/com.apple.screensaver.plist -o -`
|
||||
- `plutil -convert json ~/Library/Preferences/com.apple.screensaver.plist -o -`
|
||||
- **`.app`**:遵循目录结构的苹果应用程序(它是一个捆绑包)。
|
||||
- **`.dylib`**:动态库(类似于Windows的DLL文件)
|
||||
- **`.pkg`**:与xar(可扩展存档格式)相同。可以使用installer命令安装这些文件的内容。
|
||||
- **`.DS_Store`**:每个目录中都有此文件,它保存目录的属性和自定义。
|
||||
- **`.Spotlight-V100`**:此文件夹出现在系统上每个卷的根目录上。
|
||||
- **`.metadata_never_index`**:如果此文件位于卷的根目录中,Spotlight将不会索引该卷。
|
||||
- **`.noindex`**:具有此扩展名的文件和文件夹不会被Spotlight索引。
|
||||
- **`.sdef`**:捆绑包中的文件指定如何从AppleScript与应用程序进行交互。
|
||||
* **`.dmg`**:苹果磁盘映像文件在安装程序中非常常见。
|
||||
* **`.kext`**:它必须遵循特定结构,是驱动程序的OS X版本(它是一个捆绑包)。
|
||||
* **`.plist`**:也称为属性列表,以XML或二进制格式存储信息。
|
||||
* 可以是XML或二进制。可以使用以下命令读取二进制文件:
|
||||
* `defaults read config.plist`
|
||||
* `/usr/libexec/PlistBuddy -c print config.plsit`
|
||||
* `plutil -p ~/Library/Preferences/com.apple.screensaver.plist`
|
||||
* `plutil -convert xml1 ~/Library/Preferences/com.apple.screensaver.plist -o -`
|
||||
* `plutil -convert json ~/Library/Preferences/com.apple.screensaver.plist -o -`
|
||||
* **`.app`**:遵循目录结构的苹果应用程序(它是一个捆绑包)。
|
||||
* **`.dylib`**:动态库(类似于Windows的DLL文件)
|
||||
* **`.pkg`**:与xar(可扩展存档格式)相同。可以使用安装程序命令安装这些文件的内容。
|
||||
* **`.DS_Store`**:每个目录中都有此文件,它保存目录的属性和自定义。
|
||||
* **`.Spotlight-V100`**:此文件夹出现在系统上每个卷的根目录中。
|
||||
* **`.metadata_never_index`**:如果此文件位于卷的根目录中,Spotlight将不会索引该卷。
|
||||
* **`.noindex`**:具有此扩展名的文件和文件夹不会被Spotlight索引。
|
||||
* **`.sdef`**:捆绑包中的文件指定如何从AppleScript与应用程序进行交互。
|
||||
|
||||
### macOS捆绑包
|
||||
|
||||
|
@ -85,11 +85,14 @@ macOS在几个位置存储诸如密码之类的信息:
|
|||
[macos-bundles.md](macos-bundles.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
## Dyld共享缓存
|
||||
## Dyld共享库缓存(SLC)
|
||||
|
||||
在macOS(和iOS)中,所有系统共享库,如框架和dylibs,都**合并到一个单个文件**中,称为**dyld共享缓存**。这提高了性能,因为代码可以更快地加载。
|
||||
在macOS(和iOS)中,所有系统共享库,如框架和dylibs,都**合并到一个文件**中,称为**dyld共享缓存**。这提高了性能,因为代码可以更快地加载。
|
||||
|
||||
与dyld共享缓存类似,内核和内核扩展也编译到内核缓存中,在引导时加载。
|
||||
在macOS中,它位于`/System/Volumes/Preboot/Cryptexes/OS/System/Library/dyld/`,在旧版本中,您可能会在**`/System/Library/dyld/`**中找到**共享缓存**。\
|
||||
在iOS中,您可以在**`/System/Library/Caches/com.apple.dyld/`**中找到它们。
|
||||
|
||||
与dyld共享缓存类似,内核和内核扩展也编译到内核缓存中,在启动时加载。
|
||||
|
||||
为了从单个文件dylib共享缓存中提取库,可以使用二进制文件[dyld\_shared\_cache\_util](https://www.mbsplugins.de/files/dyld\_shared\_cache\_util-dyld-733.8.zip),这可能在现在无法工作,但您也可以使用[**dyldextractor**](https://github.com/arandomdev/dyldextractor):
|
||||
```bash
|
||||
|
@ -103,36 +106,53 @@ dyldex_all [dyld_shared_cache_path] # Extract all
|
|||
```
|
||||
{% endcode %}
|
||||
|
||||
在旧版本中,您可能会在 **`/System/Library/dyld/`** 中找到 **共享缓存**。
|
||||
|
||||
在 iOS 中,您可以在 **`/System/Library/Caches/com.apple.dyld/`** 中找到它们。
|
||||
|
||||
{% hint style="success" %}
|
||||
请注意,即使 `dyld_shared_cache_util` 工具无法工作,您也可以将 **共享 dyld 二进制文件传递给 Hopper**,Hopper 将能够识别所有库并让您 **选择要调查的库**:
|
||||
请注意,即使 `dyld_shared_cache_util` 工具无法工作,您也可以将**共享的 dyld 二进制文件传递给 Hopper**,Hopper 将能够识别所有库并让您**选择要调查的库**:
|
||||
{% endhint %}
|
||||
|
||||
<figure><img src="../../../.gitbook/assets/image (1149).png" alt="" width="563"><figcaption></figcaption></figure>
|
||||
|
||||
一些提取器可能无法工作,因为 dylibs 预链接到硬编码地址,因此它们可能会跳转到未知地址
|
||||
|
||||
{% hint style="success" %}
|
||||
还可以通过在 Xcode 中使用模拟器来下载 macOS 中其他 \*OS 设备的共享库缓存。它们将被下载到:ls `$HOME/Library/Developer/Xcode/<*>OS\ DeviceSupport/<version>/Symbols/System/Library/Caches/com.apple.dyld/`,例如:`$HOME/Library/Developer/Xcode/iOS\ DeviceSupport/14.1\ (18A8395)/Symbols/System/Library/Caches/com.apple.dyld/dyld_shared_cache_arm64`
|
||||
{% endhint %}
|
||||
|
||||
### 映射 SLC
|
||||
|
||||
**`dyld`** 使用系统调用 **`shared_region_check_np`** 来检查 SLC 是否已映射(返回地址),并使用 **`shared_region_map_and_slide_np`** 来映射 SLC。
|
||||
|
||||
请注意,即使 SLC 在第一次使用时被滑动,所有**进程**都使用**相同的副本**,如果攻击者能够在系统中运行进程,则**消除了 ASLR** 保护。 这实际上在过去被利用过,并通过共享区域分页器进行了修复。
|
||||
|
||||
分支池是创建图像映射之间的小空间的小 Mach-O dylibs,使得不可能插入函数。
|
||||
|
||||
### 覆盖 SLCs
|
||||
|
||||
使用环境变量:
|
||||
|
||||
* **`DYLD_DHARED_REGION=private DYLD_SHARED_CACHE_DIR=</path/dir> DYLD_SHARED_CACHE_DONT_VALIDATE=1`** -> 这将允许加载新的共享库缓存
|
||||
* **`DYLD_SHARED_CACHE_DIR=avoid`** 并手动用符号链接替换共享缓存中的库与真实库(您需要提取它们)
|
||||
|
||||
## 特殊文件权限
|
||||
|
||||
### 文件夹权限
|
||||
|
||||
在一个 **文件夹** 中,**读取** 允许 **列出它**,**写入** 允许 **删除** 和 **写入** 文件,**执行** 允许 **遍历** 目录。因此,例如,一个用户对目录中的 **文件具有读取权限**,但他 **没有执行权限**,则 **无法读取** 该文件。
|
||||
在**文件夹**中,**读取**允许**列出**它,**写入**允许**删除**和**写入**文件,**执行**允许**遍历**目录。因此,例如,用户对**没有执行权限**的目录中的文件具有**读取权限**,则**无法读取**该文件。
|
||||
|
||||
### 标志修饰符
|
||||
|
||||
有一些标志可以设置在文件中,使文件的行为不同。您可以使用 `ls -lO /path/directory` 命令 **检查目录中文件的标志**
|
||||
有一些标志可以设置在文件中,使文件的行为不同。您可以使用 `ls -lO /path/directory` 检查目录中文件的标志
|
||||
|
||||
* **`uchg`**:被称为 **uchange** 标志,将 **阻止任何更改或删除** **文件** 的操作。要设置它,请执行:`chflags uchg file.txt`
|
||||
* root 用户可以 **移除该标志** 并修改文件
|
||||
* **`uchg`**:称为**uchange**标志,将**阻止任何更改或删除**文件的操作。要设置它,请执行:`chflags uchg file.txt`
|
||||
* root 用户可以**移除该标志**并修改文件
|
||||
* **`restricted`**:此标志使文件受到 SIP 的保护(无法将此标志添加到文件)。
|
||||
* **`Sticky bit`**:如果一个目录具有粘性位,**只有** 目录的 **所有者或 root 可以重命名或删除** 文件。通常在 /tmp 目录上设置此标志,以防止普通用户删除或移动其他用户的文件。
|
||||
* **`粘性位`**:如果一个目录具有粘性位,**只有**目录的**所有者或 root 可以重命名或删除**文件。通常在 /tmp 目录上设置此标志,以防止普通用户删除或移动其他用户的文件。
|
||||
|
||||
所有标志都可以在文件 `sys/stat.h` 中找到(使用 `mdfind stat.h | grep stat.h` 查找),包括:
|
||||
所有标志都可以在文件 `sys/stat.h` 中找到(使用 `mdfind stat.h | grep stat.h` 查找),它们是:
|
||||
|
||||
* `UF_SETTABLE` 0x0000ffff:可更改所有者标志的掩码。
|
||||
* `UF_NODUMP` 0x00000001:不要转储文件。
|
||||
* `UF_IMMUTABLE` 0x00000002:文件不得更改。
|
||||
* `UF_SETTABLE` 0x0000ffff:所有者可更改标志的掩码。
|
||||
* `UF_NODUMP` 0x00000001:不转储文件。
|
||||
* `UF_IMMUTABLE` 0x00000002:文件不可更改。
|
||||
* `UF_APPEND` 0x00000004:只能追加写入文件。
|
||||
* `UF_OPAQUE` 0x00000008:目录对于联合是不透明的。
|
||||
* `UF_COMPRESSED` 0x00000020:文件已压缩(某些文件系统)。
|
||||
|
@ -143,21 +163,21 @@ dyldex_all [dyld_shared_cache_path] # Extract all
|
|||
* `SF_SETTABLE` 0x3fff0000:超级用户可更改的标志掩码。
|
||||
* `SF_SYNTHETIC` 0xc0000000:系统只读合成标志的掩码。
|
||||
* `SF_ARCHIVED` 0x00010000:文件已存档。
|
||||
* `SF_IMMUTABLE` 0x00020000:文件不得更改。
|
||||
* `SF_IMMUTABLE` 0x00020000:文件不可更改。
|
||||
* `SF_APPEND` 0x00040000:只能追加写入文件。
|
||||
* `SF_RESTRICTED` 0x00080000:需要写入的授权。
|
||||
* `SF_NOUNLINK` 0x00100000:项目不得被移除、重命名或挂载。
|
||||
* `SF_NOUNLINK` 0x00100000:项目不可被移除、重命名或挂载。
|
||||
* `SF_FIRMLINK` 0x00800000:文件是一个 firmlink。
|
||||
* `SF_DATALESS` 0x40000000:文件是无数据对象。
|
||||
|
||||
### **文件 ACLs**
|
||||
|
||||
文件 **ACLs** 包含 **ACE**(访问控制条目),可以为不同用户分配更多 **细粒度权限**。
|
||||
文件**ACLs** 包含**ACE**(访问控制条目),可以为不同用户分配更**精细的权限**。
|
||||
|
||||
可以授予一个 **目录** 这些权限:`list`、`search`、`add_file`、`add_subdirectory`、`delete_child`、`delete_child`。\
|
||||
对于一个 **文件**:`read`、`write`、`append`、`execute`。
|
||||
可以授予**目录**这些权限:`list`、`search`、`add_file`、`add_subdirectory`、`delete_child`、`delete_child`。\
|
||||
对于**文件**:`read`、`write`、`append`、`execute`。
|
||||
|
||||
当文件包含 ACLs 时,您将在列出权限时 **找到一个 "+"**,就像在下面的示例中一样:
|
||||
当文件包含 ACLs 时,您将在列出权限时**找到一个 "+"**,如下所示:
|
||||
```bash
|
||||
ls -ld Movies
|
||||
drwx------+ 7 username staff 224 15 Apr 19:42 Movies
|
||||
|
@ -174,7 +194,7 @@ ls -RAle / 2>/dev/null | grep -E -B1 "\d: "
|
|||
```
|
||||
### 扩展属性
|
||||
|
||||
扩展属性具有名称和任何所需的值,可以使用 `ls -@` 查看,并使用 `xattr` 命令进行操作。一些常见的扩展属性包括:
|
||||
扩展属性具有名称和任何所需值,可以使用 `ls -@` 查看,并使用 `xattr` 命令进行操作。一些常见的扩展属性包括:
|
||||
|
||||
- `com.apple.resourceFork`: 资源叉兼容性。也可在 `filename/..namedfork/rsrc` 中看到
|
||||
- `com.apple.quarantine`: MacOS: Gatekeeper 隔离机制 (III/6)
|
||||
|
@ -182,9 +202,9 @@ ls -RAle / 2>/dev/null | grep -E -B1 "\d: "
|
|||
- `com.apple.lastuseddate` (#PS): 最后使用日期
|
||||
- `com.apple.FinderInfo`: MacOS: Finder 信息(例如,颜色标签)
|
||||
- `com.apple.TextEncoding`: 指定 ASCII 文本文件的文本编码
|
||||
- `com.apple.logd.metadata`: 由 `/var/db/diagnostics` 中的 logd 在文件上使用
|
||||
- `com.apple.logd.metadata`: 由位于 `/var/db/diagnostics` 中的 logd 使用的文件
|
||||
- `com.apple.genstore.*`: 生成存储 (`/.DocumentRevisions-V100` 在文件系统根目录中)
|
||||
- `com.apple.rootless`: MacOS: 由系统完整性保护使用以标记文件 (III/10)
|
||||
- `com.apple.rootless`: MacOS: 由系统完整性保护用于标记文件 (III/10)
|
||||
- `com.apple.uuidb.boot-uuid`: 具有唯一 UUID 的引导时期的 logd 标记
|
||||
- `com.apple.decmpfs`: MacOS: 透明文件压缩 (II/7)
|
||||
- `com.apple.cprotect`: \*OS: 每个文件的加密数据 (III/11)
|
||||
|
@ -192,7 +212,7 @@ ls -RAle / 2>/dev/null | grep -E -B1 "\d: "
|
|||
|
||||
### 资源叉 | macOS ADS
|
||||
|
||||
这是在 MacOS 机器中获取**备用数据流**的一种方法。您可以通过将内容保存在名为 **com.apple.ResourceFork** 的扩展属性中的文件中来保存在 **file/..namedfork/rsrc** 中。
|
||||
这是在 MacOS 机器中获取**备用数据流**的一种方法。您可以通过将内容保存在名为 **com.apple.ResourceFork** 的扩展属性中的文件中,将其保存在 **file/..namedfork/rsrc** 中。
|
||||
```bash
|
||||
echo "Hello" > a.txt
|
||||
echo "Hello Mac ADS" > a.txt/..namedfork/rsrc
|
||||
|
@ -209,19 +229,17 @@ ls -l a.txt #The file length is still q
|
|||
```bash
|
||||
find / -type f -exec ls -ld {} \; 2>/dev/null | grep -E "[x\-]@ " | awk '{printf $9; printf "\n"}' | xargs -I {} xattr -lv {} | grep "com.apple.ResourceFork"
|
||||
```
|
||||
{% endcode %}
|
||||
## decmpfs
|
||||
|
||||
### decmpfs
|
||||
扩展属性`com.apple.decmpfs`表示文件已加密存储,`ls -l`将报告**大小为0**,压缩数据位于此属性内。每当访问文件时,它将在内存中解密。
|
||||
|
||||
扩展属性 `com.apple.decmpfs` 表示文件已加密,`ls -l` 将报告**大小为 0**,压缩数据位于此属性中。每当访问文件时,它将在内存中解密。
|
||||
可以使用`ls -lO`查看此属性,因为压缩文件也会标记为标志`UF_COMPRESSED`。如果删除压缩文件,则使用`chflags nocompressed </path/to/file>`清除此标志,系统将不知道文件已压缩,因此无法解压缩和访问数据(系统会认为文件实际上是空的)。
|
||||
|
||||
可以使用 `ls -lO` 查看此属性,因为压缩文件还会标记为标志 `UF_COMPRESSED`。如果删除压缩文件,则使用 `chflags nocompressed </path/to/file>` 删除此标志,系统将不知道文件已被压缩,因此无法解压缩和访问数据(系统会认为文件实际上是空的)。
|
||||
工具afscexpand可用于强制解压缩文件。
|
||||
|
||||
工具 afscexpand 可用于强制解压缩文件。
|
||||
## **通用二进制文件和** Mach-o 格式
|
||||
|
||||
## **通用二进制文件 &** Mach-o 格式
|
||||
|
||||
Mac OS 二进制文件通常编译为**通用二进制文件**。**通用二进制文件** 可以**在同一文件中支持多个架构**。
|
||||
Mac OS 二进制文件通常编译为**通用二进制文件**。**通用二进制文件**可以在同一文件中**支持多个架构**。
|
||||
|
||||
{% content-ref url="universal-binaries-and-mach-o-format.md" %}
|
||||
[universal-binaries-and-mach-o-format.md](universal-binaries-and-mach-o-format.md)
|
||||
|
@ -235,20 +253,20 @@ Mac OS 二进制文件通常编译为**通用二进制文件**。**通用二进
|
|||
|
||||
## Mac OS 风险类别文件
|
||||
|
||||
目录 `/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/System` 存储有关不同文件扩展名的**风险级别信息**。该目录将文件分类为不同的风险级别,影响 Safari 在下载后如何处理这些文件。分类如下:
|
||||
目录`/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/System`存储有关不同文件扩展名的**风险级别信息**。此目录将文件分类为不同的风险级别,影响 Safari 在下载后如何处理这些文件。各类别如下:
|
||||
|
||||
* **LSRiskCategorySafe**:此类文件被认为**完全安全**。Safari 将在下载后自动打开这些文件。
|
||||
* **LSRiskCategoryNeutral**:这些文件没有警告,Safari **不会自动打开**它们。
|
||||
* **LSRiskCategoryUnsafeExecutable**:此类文件会**触发警告**,指示文件是一个应用程序。这是一项安全措施,用于提醒用户。
|
||||
* **LSRiskCategoryMayContainUnsafeExecutable**:此类文件,如存档文件,可能包含可执行文件。除非 Safari 可以验证所有内容是安全或中立,否则 Safari 将**触发警告**。
|
||||
- **LSRiskCategorySafe**:此类别中的文件被认为是**完全安全**的。Safari 将在下载后自动打开这些文件。
|
||||
- **LSRiskCategoryNeutral**:这些文件没有警告,并且**Safari 不会自动打开**它们。
|
||||
- **LSRiskCategoryUnsafeExecutable**:此类别下的文件会**触发警告**,指示该文件是一个应用程序。这是一项安全措施,用于提醒用户。
|
||||
- **LSRiskCategoryMayContainUnsafeExecutable**:此类别适用于可能包含可执行文件的文件,例如存档文件。除非 Safari 可以验证所有内容是安全或中立的,否则将**触发警告**。
|
||||
|
||||
## 日志文件
|
||||
|
||||
* **`$HOME/Library/Preferences/com.apple.LaunchServices.QuarantineEventsV2`**:包含有关下载文件的信息,如下载文件的 URL。
|
||||
* **`/var/log/system.log`**:OSX 系统的主要日志。com.apple.syslogd.plist 负责执行系统日志记录(您可以通过在 `launchctl list` 中查找 "com.apple.syslogd" 来检查是否已禁用)。
|
||||
* **`/private/var/log/asl/*.asl`**:这些是可能包含有趣信息的 Apple 系统日志。
|
||||
* **`$HOME/Library/Preferences/com.apple.recentitems.plist`**:存储通过“Finder”最近访问的文件和应用程序。
|
||||
* **`$HOME/Library/Preferences/com.apple.loginitems.plsit`**:存储系统启动时要启动的项目。
|
||||
* **`$HOME/Library/Logs/DiskUtility.log`**:DiskUtility 应用程序的日志文件(包含有关驱动器的信息,包括 USB 设备)。
|
||||
* **`/Library/Preferences/SystemConfiguration/com.apple.airport.preferences.plist`**:关于无线访问点的数据。
|
||||
* **`/private/var/db/launchd.db/com.apple.launchd/overrides.plist`**:已停用的守护进程列表。
|
||||
- **`$HOME/Library/Preferences/com.apple.LaunchServices.QuarantineEventsV2`**:包含有关下载文件的信息,如下载文件的 URL。
|
||||
- **`/var/log/system.log`**:OSX 系统的主要日志。com.apple.syslogd.plist 负责执行系统日志记录(您可以通过在`launchctl list`中查找"com.apple.syslogd"来检查是否已禁用)。
|
||||
- **`/private/var/log/asl/*.asl`**:这些是可能包含有趣信息的 Apple 系统日志。
|
||||
- **`$HOME/Library/Preferences/com.apple.recentitems.plist`**:存储通过“Finder”最近访问的文件和应用程序。
|
||||
- **`$HOME/Library/Preferences/com.apple.loginitems.plsit`**:存储系统启动时要启动的项目。
|
||||
- **`$HOME/Library/Logs/DiskUtility.log`**:DiskUtility 应用程序的日志文件(包含有关驱动器的信息,包括 USB 设备)。
|
||||
- **`/Library/Preferences/SystemConfiguration/com.apple.airport.preferences.plist`**:关于无线访问点的数据。
|
||||
- **`/private/var/db/launchd.db/com.apple.launchd/overrides.plist`**:已停用的守护进程列表。
|
||||
|
|
|
@ -1,28 +1,30 @@
|
|||
# macOS Function Hooking
|
||||
# macOS函数挂钩
|
||||
|
||||
<details>
|
||||
|
||||
<summary><strong>从零开始学习AWS黑客技术,成为专家</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE(HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
||||
<summary><strong>从零开始学习AWS黑客技术,成为专家</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE(HackTricks AWS红队专家)</strong></a><strong>!</strong></summary>
|
||||
|
||||
支持HackTricks的其他方式:
|
||||
|
||||
* 如果您想看到您的**公司在HackTricks中做广告**或**下载PDF格式的HackTricks**,请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
|
||||
* 获取[**官方PEASS & HackTricks周边产品**](https://peass.creator-spring.com)
|
||||
* 探索[**PEASS家族**](https://opensea.io/collection/the-peass-family),我们的独家[**NFTs**](https://opensea.io/collection/the-peass-family)
|
||||
* **加入** 💬 [**Discord群组**](https://discord.gg/hRep4RUj7f) 或 [**电报群组**](https://t.me/peass) 或 **关注**我们的**Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**。**
|
||||
* 通过向[**HackTricks**](https://github.com/carlospolop/hacktricks)和[**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github仓库提交PR来分享您的黑客技巧。
|
||||
- 如果您想看到您的**公司在HackTricks中做广告**或**下载PDF格式的HackTricks**,请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
|
||||
- 获取[**官方PEASS & HackTricks周边产品**](https://peass.creator-spring.com)
|
||||
- 发现[**PEASS家族**](https://opensea.io/collection/the-peass-family),我们的独家[**NFTs**](https://opensea.io/collection/the-peass-family)
|
||||
- **加入** 💬 [**Discord群**](https://discord.gg/hRep4RUj7f) 或 [**电报群**](https://t.me/peass) 或 **关注**我们的**Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**。**
|
||||
- 通过向[**HackTricks**](https://github.com/carlospolop/hacktricks)和[**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github仓库提交PR来分享您的黑客技巧。
|
||||
|
||||
</details>
|
||||
|
||||
## 函数插入
|
||||
|
||||
创建一个包含指向**原始**和**替换**函数的**函数指针**元组的**dylib**,其中包含一个\*\*`__interpose`**部分(或标记为**`S_INTERPOSING`\*\*的部分)。
|
||||
创建一个包含指向**原始**和**替换**函数的**函数指针**元组的**dylib**,其中包含一个**`__interpose` (`__DATA___interpose`)**部分(或一个标记为**`S_INTERPOSING`**的部分)。
|
||||
|
||||
然后,使用\*\*`DYLD_INSERT_LIBRARIES`**注入dylib(插入操作需要在主应用程序加载之前发生)。显然,这里也适用于对**`DYLD_INSERT_LIBRARIES`\*\*的[**限制**](macos-library-injection/#check-restrictions)。
|
||||
然后,使用**`DYLD_INSERT_LIBRARIES`**注入dylib(插入操作需要在主应用程序加载之前发生)。显然,这里也适用于对**`DYLD_INSERT_LIBRARIES`**的[**限制**](macos-library-injection/#check-restrictions)。
|
||||
|
||||
### 插入printf
|
||||
|
||||
{% code title="interpose.c" %}
|
||||
{% tabs %}
|
||||
{% tab title="interpose.c" %}
|
||||
{% code title="interpose.c" overflow="wrap" %}
|
||||
```c
|
||||
// gcc -dynamiclib interpose.c -o interpose.dylib
|
||||
#include <stdio.h>
|
||||
|
@ -42,7 +44,9 @@ __attribute__((used)) static struct { const void *replacement; const void *repla
|
|||
__attribute__ ((section ("__DATA,__interpose"))) = { (const void *)(unsigned long)&my_printf, (const void *)(unsigned long)&printf };
|
||||
```
|
||||
{% endcode %}
|
||||
{% endtab %}
|
||||
|
||||
{% tab title="hello.c" %}
|
||||
```c
|
||||
//gcc hello.c -o hello
|
||||
#include <stdio.h>
|
||||
|
@ -52,33 +56,10 @@ printf("Hello World!\n");
|
|||
return 0;
|
||||
}
|
||||
```
|
||||
{% endtab %}
|
||||
|
||||
#### macOS功能挂钩
|
||||
|
||||
macOS提供了一种称为`DYLD_INSERT_LIBRARIES`的环境变量,允许我们在程序加载时注入动态链接库。这为我们提供了一种功能挂钩的方法,可以用来劫持程序的函数调用。
|
||||
|
||||
我们可以创建一个动态链接库,重写目标函数的实现,然后将其注入到目标程序中。这样,当目标程序调用该函数时,实际上会执行我们注入的代码。
|
||||
|
||||
以下是一个示例,展示了如何使用`DYLD_INSERT_LIBRARIES`环境变量来劫持`open`函数的调用:
|
||||
|
||||
```c
|
||||
#include <stdio.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
int open(const char *path, int oflag, ...) {
|
||||
int (*original_open)(const char *, int, ...);
|
||||
original_open = dlsym(RTLD_NEXT, "open");
|
||||
|
||||
printf("Intercepted open call: %s\n", path);
|
||||
|
||||
return original_open(path, oflag);
|
||||
}
|
||||
```
|
||||
|
||||
在这个示例中,我们重写了`open`函数,添加了一行打印语句,然后调用原始的`open`函数。
|
||||
|
||||
通过这种方式,我们可以在不修改目标程序源代码的情况下,劫持其函数调用,实现各种有趣的功能。
|
||||
|
||||
{% tab title="interpose2.c" %}
|
||||
{% code overflow="wrap" %}
|
||||
```c
|
||||
// Just another way to define an interpose
|
||||
// gcc -dynamiclib interpose2.c -o interpose2.dylib
|
||||
|
@ -102,7 +83,9 @@ return ret;
|
|||
|
||||
DYLD_INTERPOSE(my_printf,printf);
|
||||
```
|
||||
|
||||
{% endcode %}
|
||||
{% endtab %}
|
||||
{% endtabs %}
|
||||
```bash
|
||||
DYLD_INSERT_LIBRARIES=./interpose.dylib ./hello
|
||||
Hello from interpose
|
||||
|
@ -110,25 +93,44 @@ Hello from interpose
|
|||
DYLD_INSERT_LIBRARIES=./interpose2.dylib ./hello
|
||||
Hello from interpose
|
||||
```
|
||||
{% hint style="warning" %}
|
||||
**`DYLD_PRINT_INTERPOSTING`** 环境变量可用于调试 interposing,并将打印 interpose 过程。
|
||||
{% endhint %}
|
||||
|
||||
还要注意,**interposing 发生在进程和加载的库之间**,它不适用于共享库缓存。
|
||||
|
||||
### 动态 Interposing
|
||||
|
||||
现在也可以使用函数 **`dyld_dynamic_interpose`** 动态地 interpose 一个函数。这允许在运行时以编程方式 interpose 一个函数,而不仅仅是从一开始就这样做。
|
||||
|
||||
只需要指示**要替换的函数和替换函数的元组**。
|
||||
```c
|
||||
struct dyld_interpose_tuple {
|
||||
const void* replacement;
|
||||
const void* replacee;
|
||||
};
|
||||
extern void dyld_dynamic_interpose(const struct mach_header* mh,
|
||||
const struct dyld_interpose_tuple array[], size_t count);
|
||||
```
|
||||
## 方法交换
|
||||
|
||||
在 ObjectiveC 中,方法的调用方式如下:**`[myClassInstance nameOfTheMethodFirstParam:param1 secondParam:param2]`**
|
||||
|
||||
需要**对象**、**方法**和**参数**。当调用方法时,会使用函数\*\*`objc_msgSend`**发送**消息\*\*:`int i = ((int (*)(id, SEL, NSString *, NSString *))objc_msgSend)(someObject, @selector(method1p1:p2:), value1, value2);`
|
||||
需要**对象**、**方法**和**参数**。当调用方法时,会使用函数**`objc_msgSend`**发送**消息**:`int i = ((int (*)(id, SEL, NSString *, NSString *))objc_msgSend)(someObject, @selector(method1p1:p2:), value1, value2);`
|
||||
|
||||
对象是\*\*`someObject`**,方法是**`@selector(method1p1:p2:)`**,参数是**value1\*\*、**value2**。
|
||||
对象是**`someObject`**,方法是**`@selector(method1p1:p2:)`**,参数是**value1**、**value2**。
|
||||
|
||||
根据对象结构,可以访问一个包含方法**名称**和**指向方法代码的指针**的**方法数组**。
|
||||
|
||||
{% hint style="danger" %}
|
||||
请注意,由于方法和类是根据它们的名称访问的,这些信息存储在二进制文件中,因此可以使用 `otool -ov </path/bin>` 或 [`class-dump </path/bin>`](https://github.com/nygard/class-dump) 检索它。
|
||||
请注意,由于方法和类是根据它们的名称访问的,这些信息存储在二进制文件中,因此可以使用 `otool -ov </path/bin>` 或 [`class-dump </path/bin>`](https://github.com/nygard/class-dump) 检索它们。
|
||||
{% endhint %}
|
||||
|
||||
### 访问原始方法
|
||||
|
||||
可以访问方法的信息,如名称、参数数量或地址,如下例所示:
|
||||
|
||||
{% code overflow="wrap" %}
|
||||
```objectivec
|
||||
// gcc -framework Foundation test.m -o test
|
||||
|
||||
|
@ -194,15 +196,15 @@ NSLog(@"Uppercase string: %@", uppercaseString3);
|
|||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
### 使用`method_exchangeImplementations`进行方法交换
|
||||
|
||||
函数\*\*`method_exchangeImplementations`**允许**更改**一个函数的**实现地址为另一个函数\*\*。
|
||||
函数**`method_exchangeImplementations`**允许**更改**一个函数的**实现地址为另一个函数**的地址。
|
||||
|
||||
{% hint style="danger" %}
|
||||
因此,当调用一个函数时,**执行的是另一个函数**。
|
||||
{% endhint %}
|
||||
|
||||
{% code overflow="wrap" %}
|
||||
```objectivec
|
||||
//gcc -framework Foundation swizzle_str.m -o swizzle_str
|
||||
|
||||
|
@ -246,6 +248,7 @@ NSLog(@"Substring: %@", subString);
|
|||
return 0;
|
||||
}
|
||||
```
|
||||
{% endcode %}
|
||||
|
||||
{% hint style="warning" %}
|
||||
在这种情况下,如果**合法方法的实现代码**验证**方法名称**,它可以**检测**到这种方法交换并阻止其运行。
|
||||
|
@ -255,10 +258,11 @@ return 0;
|
|||
|
||||
### 使用method\_setImplementation进行方法交换
|
||||
|
||||
之前的格式很奇怪,因为你正在改变其中一个方法的实现。使用函数\*\*`method_setImplementation`**,您可以将一个方法的**实现更改为另一个方法\*\*。
|
||||
之前的格式很奇怪,因为你正在改变其中一个方法的实现。使用函数**`method_setImplementation`**,你可以将一个方法的实现**更改为另一个方法**。
|
||||
|
||||
只需记住,如果您打算从新实现中调用原始实现的地址,请**存储原始实现的地址**,因为稍后要定位该地址将变得更加复杂。
|
||||
只需记住,如果你打算从新实现中调用原始实现的地址,**请存储原始实现的地址**,因为稍后要定位该地址将变得更加复杂。
|
||||
|
||||
{% code overflow="wrap" %}
|
||||
```objectivec
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <objc/runtime.h>
|
||||
|
@ -310,19 +314,19 @@ return 0;
|
|||
}
|
||||
}
|
||||
```
|
||||
{% endcode %}
|
||||
|
||||
## Hooking Attack Methodology
|
||||
|
||||
在这一页中,讨论了不同的挂钩函数的方法。然而,它们涉及**在进程内运行代码进行攻击**。
|
||||
在这一页中,讨论了钩住函数的不同方法。然而,它们涉及**在进程内运行代码进行攻击**。
|
||||
|
||||
为了做到这一点,最简单的技术是通过环境变量或劫持注入[Dyld](macos-library-injection/macos-dyld-hijacking-and-dyld\_insert\_libraries.md)。然而,我认为这也可以通过[通过任务端口进行的Dylib进程注入](macos-ipc-inter-process-communication/#dylib-process-injection-via-task-port)来实现。
|
||||
为了做到这一点,最简单的技术是通过注入[Dyld通过环境变量或劫持](macos-library-injection/macos-dyld-hijacking-and-dyld\_insert\_libraries.md)。然而,我想这也可以通过[Dylib进程注入](macos-ipc-inter-process-communication/#dylib-process-injection-via-task-port)来实现。
|
||||
|
||||
然而,这两种选项都**限制**在**未受保护**的二进制文件/进程上。查看每种技术以了解更多限制。
|
||||
|
||||
然而,函数挂钩攻击非常具体,攻击者会这样做是为了**从进程内部窃取敏感信息**(如果不是的话,你只会进行进程注入攻击)。而这些敏感信息可能位于用户下载的应用程序中,比如MacPass。
|
||||
|
||||
因此,攻击者的向量将是要么找到漏洞,要么剥离应用程序的签名,通过应用程序的Info.plist注入\*\*`DYLD_INSERT_LIBRARIES`\*\*环境变量,添加类似以下内容:
|
||||
然而,函数钩取攻击非常具体,攻击者会这样做是为了**从进程内部窃取敏感信息**(如果不是的话,你只会进行进程注入攻击)。而这些敏感信息可能位于用户下载的应用程序中,比如MacPass。
|
||||
|
||||
因此,攻击者的向量将是要么找到一个漏洞,要么剥离应用程序的签名,通过应用程序的Info.plist注入**`DYLD_INSERT_LIBRARIES`**环境变量,添加类似以下内容:
|
||||
```xml
|
||||
<key>LSEnvironment</key>
|
||||
<dict>
|
||||
|
@ -330,7 +334,6 @@ return 0;
|
|||
<string>/Applications/Application.app/Contents/malicious.dylib</string>
|
||||
</dict>
|
||||
```
|
||||
|
||||
然后**重新注册**应用程序:
|
||||
|
||||
{% code overflow="wrap" %}
|
||||
|
@ -342,11 +345,12 @@ return 0;
|
|||
在该库中添加挂钩代码以外泄信息:密码,消息...
|
||||
|
||||
{% hint style="danger" %}
|
||||
请注意,在较新版本的 macOS 中,如果您**剥离应用程序二进制文件的签名**,并且该应用程序之前已被执行,macOS将**不再执行该应用程序**。
|
||||
请注意,在 macOS 的新版本中,如果您**剥离应用程序二进制文件的签名**,并且该应用程序之前已被执行过,macOS将**不再执行该应用程序**。
|
||||
{% endhint %}
|
||||
|
||||
#### 库示例
|
||||
|
||||
{% code overflow="wrap" %}
|
||||
```objectivec
|
||||
// gcc -dynamiclib -framework Foundation sniff.m -o sniff.dylib
|
||||
|
||||
|
@ -382,6 +386,7 @@ IMP fake_IMP = (IMP)custom_setPassword;
|
|||
real_setPassword = method_setImplementation(real_Method, fake_IMP);
|
||||
}
|
||||
```
|
||||
{% endcode %}
|
||||
|
||||
## 参考
|
||||
|
||||
|
@ -389,14 +394,14 @@ real_setPassword = method_setImplementation(real_Method, fake_IMP);
|
|||
|
||||
<details>
|
||||
|
||||
<summary><strong>从零开始学习AWS黑客技术,成为专家</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
||||
<summary><strong>从零开始学习 AWS 黑客技术,成为专家</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE(HackTricks AWS 红队专家)</strong></a><strong>!</strong></summary>
|
||||
|
||||
支持HackTricks的其他方式:
|
||||
支持 HackTricks 的其他方式:
|
||||
|
||||
* 如果您想看到您的**公司在HackTricks中做广告**或**下载PDF格式的HackTricks**,请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
|
||||
* 获取[**官方PEASS & HackTricks周边产品**](https://peass.creator-spring.com)
|
||||
* 发现[**PEASS家族**](https://opensea.io/collection/the-peass-family),我们的独家[**NFTs**](https://opensea.io/collection/the-peass-family)
|
||||
* **加入** 💬 [**Discord群组**](https://discord.gg/hRep4RUj7f) 或 [**电报群组**](https://t.me/peass) 或 **关注**我们的**Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
|
||||
* 通过向[**HackTricks**](https://github.com/carlospolop/hacktricks)和[**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github仓库提交PR来分享您的黑客技巧。
|
||||
* 如果您想看到您的**公司在 HackTricks 中做广告**或**下载 PDF 版本的 HackTricks**,请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
|
||||
* 获取[**官方 PEASS & HackTricks 商品**](https://peass.creator-spring.com)
|
||||
* 发现[**PEASS 家族**](https://opensea.io/collection/the-peass-family),我们的独家[**NFTs**](https://opensea.io/collection/the-peass-family)
|
||||
* **加入** 💬 [**Discord 群组**](https://discord.gg/hRep4RUj7f) 或 [**电报群组**](https://t.me/peass) 或**关注**我们的**Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**。**
|
||||
* 通过向 [**HackTricks**](https://github.com/carlospolop/hacktricks) 和 [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github 仓库提交 PR 来分享您的黑客技巧。
|
||||
|
||||
</details>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# macOS Library Injection
|
||||
# macOS库注入
|
||||
|
||||
<details>
|
||||
|
||||
|
@ -6,55 +6,63 @@
|
|||
|
||||
支持HackTricks的其他方式:
|
||||
|
||||
* 如果您想看到您的**公司在HackTricks中做广告**或**下载PDF格式的HackTricks**,请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
|
||||
* 获取[**官方PEASS & HackTricks周边产品**](https://peass.creator-spring.com)
|
||||
* 探索[**PEASS家族**](https://opensea.io/collection/the-peass-family),我们的独家[NFT](https://opensea.io/collection/the-peass-family)收藏品
|
||||
* **加入** 💬 [**Discord群**](https://discord.gg/hRep4RUj7f) 或 [**电报群**](https://t.me/peass) 或 **关注**我的**Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**。**
|
||||
* 通过向[**HackTricks**](https://github.com/carlospolop/hacktricks)和[**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github仓库提交PR来分享您的黑客技巧。
|
||||
- 如果您想看到您的**公司在HackTricks中做广告**或**下载PDF格式的HackTricks**,请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
|
||||
- 获取[**官方PEASS & HackTricks周边产品**](https://peass.creator-spring.com)
|
||||
- 探索[**PEASS家族**](https://opensea.io/collection/the-peass-family),我们的独家[NFTs](https://opensea.io/collection/the-peass-family)收藏品
|
||||
- **加入** 💬 [**Discord群**](https://discord.gg/hRep4RUj7f) 或 [**电报群**](https://t.me/peass) 或 **关注**我们的**Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**。**
|
||||
- 通过向[**HackTricks**](https://github.com/carlospolop/hacktricks)和[**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github仓库提交PR来分享您的黑客技巧。
|
||||
|
||||
</details>
|
||||
|
||||
{% hint style="danger" %}
|
||||
**dyld的代码是开源的**,可以在[https://opensource.apple.com/source/dyld/](https://opensource.apple.com/source/dyld/)找到,并且可以使用类似[https://opensource.apple.com/tarballs/dyld/dyld-852.2.tar.gz](https://opensource.apple.com/tarballs/dyld/dyld-852.2.tar.gz)的URL下载tar文件。
|
||||
**dyld的代码是开源的**,可以在[https://opensource.apple.com/source/dyld/](https://opensource.apple.com/source/dyld/)找到,也可以使用类似[https://opensource.apple.com/tarballs/dyld/dyld-852.2.tar.gz](https://opensource.apple.com/tarballs/dyld/dyld-852.2.tar.gz)的URL下载tar文件。
|
||||
{% endhint %}
|
||||
|
||||
## **Dyld进程**
|
||||
|
||||
查看Dyld如何在二进制文件中加载库:
|
||||
|
||||
{% content-ref url="macos-dyld-process.md" %}
|
||||
[macos-dyld-process.md](macos-dyld-process.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
## **DYLD\_INSERT\_LIBRARIES**
|
||||
|
||||
这类似于[**Linux上的LD\_PRELOAD**](../../../../linux-hardening/privilege-escalation/#ld\_preload)。它允许指示一个进程将要运行以从路径加载特定库的库(如果启用了环境变量)
|
||||
这类似于[**Linux上的LD\_PRELOAD**](../../../../linux-hardening/privilege-escalation/#ld\_preload)。它允许指示一个进程将从路径加载特定库(如果启用了环境变量)。
|
||||
|
||||
这种技术也可以**用作ASEP技术**,因为每个安装的应用程序都有一个名为"Info.plist"的plist,允许使用名为`LSEnvironmental`的键**分配环境变量**。
|
||||
这种技术也可以**用作ASEP技术**,因为每个安装的应用程序都有一个名为"Info.plist"的属性列表,允许使用名为`LSEnvironmental`的键**分配环境变量**。
|
||||
|
||||
{% hint style="info" %}
|
||||
自2012年以来,**苹果大大降低了** **`DYLD_INSERT_LIBRARIES`** 的权限。
|
||||
自2012年以来,**苹果大大减少了** **`DYLD_INSERT_LIBRARIES`** 的权限。
|
||||
|
||||
转到代码并**检查`src/dyld.cpp`**。在函数\*\*`pruneEnvironmentVariables`**中,您可以看到**`DYLD_*`\*\*变量被移除。
|
||||
转到代码并**检查`src/dyld.cpp`**。在函数**`pruneEnvironmentVariables`**中,您可以看到**删除了`DYLD_*`**变量。
|
||||
|
||||
在函数\*\*`processRestricted`\*\*中设置了限制的原因。检查该代码,您会看到限制的原因是:
|
||||
在函数**`processRestricted`**中设置了限制的原因。检查该代码,您会看到限制的原因是:
|
||||
|
||||
* 二进制文件是`setuid/setgid`
|
||||
* 在macho二进制文件中存在`__RESTRICT/__restrict`部分。
|
||||
* 软件具有没有[`com.apple.security.cs.allow-dyld-environment-variables`](https://developer.apple.com/documentation/bundleresources/entitlements/com\_apple\_security\_cs\_allow-dyld-environment-variables)授权的强化运行时
|
||||
* 使用以下命令检查二进制文件的**授权**:`codesign -dv --entitlements :- </path/to/bin>`
|
||||
- 二进制文件是`setuid/setgid`
|
||||
- 在macho二进制文件中存在`__RESTRICT/__restrict`部分。
|
||||
- 软件具有没有[`com.apple.security.cs.allow-dyld-environment-variables`](https://developer.apple.com/documentation/bundleresources/entitlements/com\_apple\_security\_cs\_allow-dyld-environment-variables)授权的强化运行时
|
||||
- 使用以下命令检查二进制文件的**授权**:`codesign -dv --entitlements :- </path/to/bin>`
|
||||
|
||||
在更新的版本中,您可以在函数\*\*`configureProcessRestrictions`**的第二部分找到这种逻辑。然而,在较新版本中执行的是函数的**开始检查\*\*(您可以删除与iOS或模拟相关的if,因为这些在macOS中不会使用)。
|
||||
在更新的版本中,您可以在函数**`configureProcessRestrictions`**的第二部分找到此逻辑。但是,在较新版本中执行的是函数的**开始检查**(您可以删除与iOS或模拟相关的if,因为这些在macOS中不会使用)。
|
||||
{% endhint %}
|
||||
|
||||
### 库验证
|
||||
|
||||
即使二进制文件允许使用\*\*`DYLD_INSERT_LIBRARIES`\*\*环境变量,如果二进制文件检查要加载的库的签名,则不会加载自定义内容。
|
||||
即使二进制文件允许使用**`DYLD_INSERT_LIBRARIES`**环境变量,如果二进制文件检查要加载的库的签名,它将不会加载自定义内容。
|
||||
|
||||
为了加载自定义库,二进制文件需要具有以下授权之一:
|
||||
|
||||
* [`com.apple.security.cs.disable-library-validation`](../../macos-security-protections/macos-dangerous-entitlements.md#com.apple.security.cs.disable-library-validation)
|
||||
* [`com.apple.private.security.clear-library-validation`](../../macos-security-protections/macos-dangerous-entitlements.md#com.apple.private.security.clear-library-validation)
|
||||
- [`com.apple.security.cs.disable-library-validation`](../../macos-security-protections/macos-dangerous-entitlements.md#com.apple.security.cs.disable-library-validation)
|
||||
- [`com.apple.private.security.clear-library-validation`](../../macos-security-protections/macos-dangerous-entitlements.md#com.apple.private.security.clear-library-validation)
|
||||
|
||||
或者二进制文件**不应该**具有**强化运行时标志**或**库验证标志**。
|
||||
|
||||
您可以使用`codesign --display --verbose <bin>`检查二进制文件是否具有**强化运行时**,检查\*\*`CodeDirectory`**中的标志运行时,例如:**`CodeDirectory v=20500 size=767 flags=0x10000(runtime) hashes=13+7 location=embedded`\*\*
|
||||
您可以使用`codesign --display --verbose <bin>`检查二进制文件是否具有**强化运行时**,检查**`CodeDirectory`**中的标志运行时,例如:**`CodeDirectory v=20500 size=767 flags=0x10000(runtime) hashes=13+7 location=embedded`**
|
||||
|
||||
如果库**与二进制文件相同证书签名**,也可以加载库。
|
||||
如果**使用与二进制文件相同的证书签名**,也可以加载库。
|
||||
|
||||
找到一个关于如何(滥用)使用此功能并检查限制的示例:
|
||||
找到一个关于如何(滥用)利用此功能并检查限制的示例:
|
||||
|
||||
{% content-ref url="macos-dyld-hijacking-and-dyld_insert_libraries.md" %}
|
||||
[macos-dyld-hijacking-and-dyld\_insert\_libraries.md](macos-dyld-hijacking-and-dyld\_insert\_libraries.md)
|
||||
|
@ -63,28 +71,29 @@
|
|||
## Dylib劫持
|
||||
|
||||
{% hint style="danger" %}
|
||||
请记住,**以前的库验证限制也适用于**执行Dylib劫持攻击。
|
||||
请记住**以前的库验证限制也适用**于执行Dylib劫持攻击。
|
||||
{% endhint %}
|
||||
|
||||
与Windows一样,在MacOS中,您也可以**劫持dylibs**以使**应用程序**执行**任意**代码(实际上,从普通用户这样做可能不可能,因为您可能需要TCC权限才能写入`.app`包并劫持库)。 然而,**MacOS**应用程序**加载**库的方式**比Windows更受限制**。这意味着**恶意软件**开发人员仍然可以使用此技术进行**隐蔽**,但是**滥用此技术以提升权限的可能性要低得多**。
|
||||
与Windows一样,在MacOS中,您也可以**劫持dylibs**以使**应用程序**执行**任意** **代码**(实际上,从普通用户这样做可能不可能,因为您可能需要TCC权限才能写入`.app`包并劫持库)。\
|
||||
然而,**MacOS**应用程序**加载**库的方式**比Windows更受限制**。这意味着**恶意软件**开发人员仍然可以使用此技术进行**隐蔽**,但是**滥用此技术以提升权限的可能性要低得多**。
|
||||
|
||||
首先,**更常见**的是发现**MacOS二进制文件指示要加载的库的完整路径**。其次,**MacOS从不在** **$PATH** **文件夹中搜索**库。
|
||||
首先,**更常见**的是发现**MacOS二进制文件指示库的完整路径**。其次,**MacOS从不在** **$PATH** **文件夹中搜索**库。
|
||||
|
||||
与此功能相关的**主要**代码部分位于`ImageLoader.cpp`中的\*\*`ImageLoader::recursiveLoadLibraries`\*\*中。
|
||||
与此功能相关的**主要**代码部分位于`ImageLoader.cpp`中的**`ImageLoader::recursiveLoadLibraries`**中。
|
||||
|
||||
Macho二进制文件可以使用**4个不同的头部命令**来加载库:
|
||||
|
||||
* \*\*`LC_LOAD_DYLIB`\*\*命令是加载dylib的常见命令。
|
||||
* \*\*`LC_LOAD_WEAK_DYLIB`\*\*命令与前一个命令类似,但如果未找到dylib,则继续执行而不会出现任何错误。
|
||||
* \*\*`LC_REEXPORT_DYLIB`\*\*命令代理(或重新导出)来自不同库的符号。
|
||||
* \*\*`LC_LOAD_UPWARD_DYLIB`\*\*命令在两个库彼此依赖时使用(这称为\_向上依赖\_)。
|
||||
- **`LC_LOAD_DYLIB`**命令是加载dylib的常见命令。
|
||||
- **`LC_LOAD_WEAK_DYLIB`**命令与前一个命令类似,但如果未找到dylib,则继续执行而不会出现任何错误。
|
||||
- **`LC_REEXPORT_DYLIB`**命令代理(或重新导出)来自不同库的符号。
|
||||
- **`LC_LOAD_UPWARD_DYLIB`**命令在两个库彼此依赖时使用(这称为_向上依赖_)。
|
||||
|
||||
然而,有**2种dylib劫持**:
|
||||
|
||||
* **缺失的弱链接库**:这意味着应用程序将尝试加载一个使用**LC\_LOAD\_WEAK\_DYLIB**配置的不存在的库。然后,**如果攻击者将dylib放在预期的位置,它将被加载**。
|
||||
* 与此相关的**代码**在`ImageLoaderMachO.cpp`的`ImageLoaderMachO::doGetDependentLibraries`函数中,其中`lib->required`仅在`LC_LOAD_WEAK_DYLIB`为true时为`false`。
|
||||
* 在二进制文件中查找**弱链接库**(稍后您将看到如何创建劫持库的示例):
|
||||
|
||||
- **缺失的弱链接库**:这意味着应用程序将尝试加载一个使用**LC\_LOAD\_WEAK\_DYLIB**配置的不存在的库。然后,**如果攻击者将dylib放在预期的位置,它将被加载**。
|
||||
- 链接是“弱”的意思是即使未找到库,应用程序也将继续运行。
|
||||
- 与此相关的**代码**位于`ImageLoaderMachO.cpp`的`ImageLoaderMachO::doGetDependentLibraries`函数中,其中`lib->required`仅在`LC_LOAD_WEAK_DYLIB`为true时为`false`。
|
||||
- 在二进制文件中查找**弱链接库**(稍后您将看到如何创建劫持库的示例):
|
||||
```bash
|
||||
otool -l </path/to/bin> | grep LC_LOAD_WEAK_DYLIB -A 5 cmd LC_LOAD_WEAK_DYLIB
|
||||
cmdsize 56
|
||||
|
@ -93,24 +102,25 @@ Macho二进制文件可以使用**4个不同的头部命令**来加载库:
|
|||
current version 1.0.0
|
||||
compatibility version 1.0.0
|
||||
```
|
||||
* **配置为@rpath**:Mach-O二进制文件可以具有\*\*`LC_RPATH`**和**`LC_LOAD_DYLIB`**命令。根据这些命令的**值\*\*,库将从**不同目录**加载。
|
||||
* \*\*`LC_RPATH`\*\*包含用于由二进制文件加载库的某些文件夹的路径。
|
||||
* **`LC_LOAD_DYLIB`包含要加载的特定库的路径。这些路径可以包含`@rpath`**,它将被\*\*`LC_RPATH`**中的值**替换\*\*。如果\*\*`LC_RPATH`**中有几个路径,每个路径都将用于搜索要加载的库。例如: 如果**`LC_LOAD_DYLIB`**包含`@rpath/library.dylib`,而**`LC_RPATH`**包含`/application/app.app/Contents/Framework/v1/`和`/application/app.app/Contents/Framework/v2/`。将使用两个文件夹来加载`library.dylib`。如果库不存在于`[...]/v1/`中,攻击者可以将其放在那里以劫持`[...]/v2/`中库的加载,因为将遵循**`LC_LOAD_DYLIB`\*\*中路径的顺序。
|
||||
* 使用以下命令在二进制文件中查找rpath路径和库:`otool -l </path/to/binary> | grep -E "LC_RPATH|LC_LOAD_DYLIB" -A 5`
|
||||
- **配置为@rpath**:Mach-O二进制文件可以具有**`LC_RPATH`**和**`LC_LOAD_DYLIB`**命令。根据这些命令的**值**,库将从**不同目录**加载。
|
||||
* **`LC_LOAD_DYLIB`** 包含要加载的特定库的路径。这些路径可以包含 **`@rpath`**,它将被 **`LC_RPATH`** 中的值 **替换**。如果 **`LC_RPATH`** 中有多个路径,则每个路径都将用于搜索要加载的库。例如:
|
||||
* 如果 **`LC_LOAD_DYLIB`** 包含 `@rpath/library.dylib`,而 **`LC_RPATH`** 包含 `/application/app.app/Contents/Framework/v1/` 和 `/application/app.app/Contents/Framework/v2/`。那么这两个文件夹都将用于加载 `library.dylib`。如果库在 `[...]/v1/` 中不存在,攻击者可以将其放在那里以劫持在 `[...]/v2/` 中的库加载,因为会按照 **`LC_LOAD_DYLIB`** 中路径的顺序进行加载。
|
||||
* 使用以下命令在二进制文件中 **查找 rpath 路径和库**:`otool -l </path/to/binary> | grep -E "LC_RPATH|LC_LOAD_DYLIB" -A 5`
|
||||
|
||||
{% hint style="info" %}
|
||||
**`@executable_path`**:是包含**主可执行文件**的目录的**路径**。
|
||||
**`@executable_path`**:是包含 **主可执行文件** 的 **目录路径**。
|
||||
|
||||
**`@loader_path`**:是包含**包含加载命令的Mach-O二进制文件**的**目录**的**路径**。
|
||||
**`@loader_path`**:是包含包含加载命令的 **Mach-O 二进制文件** 的 **目录路径**。
|
||||
|
||||
* 在可执行文件中使用时,\*\*`@loader_path`**实际上与**`@executable_path`\*\*相同。
|
||||
* 在**dylib**中使用时,**`@loader_path`给出dylib**的**路径**。
|
||||
* 当在可执行文件中使用时,**`@loader_path`** 实际上与 **`@executable_path`** **相同**。
|
||||
* 当在 **dylib** 中使用时,**`@loader_path`** 给出了 **dylib** 的 **路径**。
|
||||
{% endhint %}
|
||||
|
||||
滥用此功能升级权限的方式是在**以root身份执行的应用程序**中查找**攻击者具有写权限的某个文件夹**中的某个库的情况下。
|
||||
利用这种功能进行 **权限提升** 的方式是在罕见情况下,由 **root** 执行的 **应用程序** 正在 **查找** 一些 **库**,而攻击者具有写权限的某个文件夹中存在该库。
|
||||
|
||||
{% hint style="success" %}
|
||||
一个很好的**扫描工具**,用于查找应用程序中的**缺失库**是[**Dylib Hijack Scanner**](https://objective-see.com/products/dhs.html)或[**CLI版本**](https://github.com/pandazheng/DylibHijack)。 关于此技术的技术细节的**报告**可以在[**这里**](https://www.virusbulletin.com/virusbulletin/2015/03/dylib-hijacking-os-x)找到。
|
||||
一个很好的 **扫描工具**,用于查找应用程序中的 **缺失库** 是 [**Dylib Hijack Scanner**](https://objective-see.com/products/dhs.html) 或 [**CLI 版本**](https://github.com/pandazheng/DylibHijack)。
|
||||
关于这种技术的一个带有技术细节的不错的 **报告** 可以在 [**这里**](https://www.virusbulletin.com/virusbulletin/2015/03/dylib-hijacking-os-x) 找到。
|
||||
{% endhint %}
|
||||
|
||||
**示例**
|
||||
|
@ -119,16 +129,15 @@ Macho二进制文件可以使用**4个不同的头部命令**来加载库:
|
|||
[macos-dyld-hijacking-and-dyld\_insert\_libraries.md](macos-dyld-hijacking-and-dyld\_insert\_libraries.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
## Dlopen劫持
|
||||
## Dlopen 劫持
|
||||
|
||||
{% hint style="danger" %}
|
||||
请记住,**以前的库验证限制也适用于**执行Dlopen劫持攻击。
|
||||
请记住,执行 Dlopen 劫持攻击时也适用 **先前的库验证限制**。
|
||||
{% endhint %}
|
||||
|
||||
从\*\*`man dlopen`\*\*:
|
||||
|
||||
* 当路径**不包含斜杠字符**(即仅为叶名称),**dlopen()将进行搜索**。如果在启动时设置了\*\*`$DYLD_LIBRARY_PATH`**,dyld将首先在该目录中查找。接下来,如果调用的mach-o文件或主可执行文件指定了**`LC_RPATH`**,那么dyld将在这些目录中查找。接下来,如果进程是**不受限制的\*\*,dyld将在**当前工作目录**中搜索。最后,对于旧二进制文件,dyld将尝试一些回退。如果在启动时设置了\*\*`$DYLD_FALLBACK_LIBRARY_PATH`**,dyld将在**这些目录中搜索\*\*,否则,dyld将在\*\*`/usr/local/lib/`**中查找(如果进程不受限制),然后在**`/usr/lib/`**中查找(此信息来自**`man dlopen`\*\*)。
|
||||
来自 **`man dlopen`**:
|
||||
|
||||
* 当路径 **不包含斜杠字符**(即只是一个叶子名称)时,**dlopen() 将进行搜索**。如果在启动时设置了 **`$DYLD_LIBRARY_PATH`**,dyld 将首先在该目录中查找。接下来,如果调用的 mach-o 文件或主可执行文件指定了 **`LC_RPATH`**,那么 dyld 将在这些目录中查找。接下来,如果进程是 **不受限制的**,dyld 将在 **当前工作目录** 中搜索。最后,对于旧的二进制文件,dyld 将尝试一些回退。如果在启动时设置了 **`$DYLD_FALLBACK_LIBRARY_PATH`**,dyld 将在 **这些目录中搜索**,否则,dyld 将在 **`/usr/local/lib/`** 中查找(如果进程是不受限制的),然后在 **`/usr/lib/`** 中查找(此信息取自 **`man dlopen`**)。
|
||||
1. `$DYLD_LIBRARY_PATH`
|
||||
2. `LC_RPATH`
|
||||
3. `CWD`(如果不受限制)
|
||||
|
@ -137,44 +146,51 @@ Macho二进制文件可以使用**4个不同的头部命令**来加载库:
|
|||
6. `/usr/lib/`
|
||||
|
||||
{% hint style="danger" %}
|
||||
如果名称中没有斜杠,则有两种方法可以进行劫持:
|
||||
如果名称中没有斜杠,有两种方法可以进行劫持:
|
||||
|
||||
* 如果任何\*\*`LC_RPATH`**是**可写的\*\*(但会检查签名,因此对于此,您还需要二进制文件是不受限制的)
|
||||
* 如果二进制文件是**不受限制的**,那么可以从CWD加载内容(或滥用其中提到的环境变量之一)
|
||||
* 如果任何 **`LC_RPATH`** 是 **可写的**(但会检查签名,因此您还需要二进制文件是不受限制的)
|
||||
* 如果二进制文件是 **不受限制的**,那么可以从 CWD 中加载内容(或滥用其中提到的环境变量之一)
|
||||
{% endhint %}
|
||||
|
||||
* 当路径**看起来像一个框架路径**(例如`/stuff/foo.framework/foo`)时,如果在启动时设置了\*\*`$DYLD_FRAMEWORK_PATH`**,dyld将首先在该目录中查找**框架部分路径\*\*(例如`foo.framework/foo`)。接下来,dyld将尝试**使用提供的路径**(对于相对路径,使用当前工作目录)。最后,对于旧二进制文件,dyld将尝试一些回退。如果在启动时设置了\*\*`$DYLD_FALLBACK_FRAMEWORK_PATH`**,dyld将搜索这些目录。否则,它将搜索**`/Library/Frameworks`**(在macOS上,如果进程不受限制),然后在**`/System/Library/Frameworks`\*\*中搜索。
|
||||
|
||||
* 当路径 **看起来像一个框架** 路径(例如 `/stuff/foo.framework/foo`),如果在启动时设置了 **`$DYLD_FRAMEWORK_PATH`**,dyld 将首先在该目录中查找 **框架部分路径**(例如 `foo.framework/foo`)。接下来,dyld 将尝试使用 **提供的路径**(对于相对路径,使用当前工作目录)。最后,对于旧的二进制文件,dyld 将尝试一些回退。如果在启动时设置了 **`$DYLD_FALLBACK_FRAMEWORK_PATH`**,dyld 将搜索这些目录。否则,它将搜索 **`/Library/Frameworks`**(在 macOS 上,如果进程是不受限制的),然后在 **`/System/Library/Frameworks`** 中搜索。
|
||||
1. `$DYLD_FRAMEWORK_PATH`
|
||||
2. 提供的路径(对于相对路径,如果不受限制,则使用当前工作目录)
|
||||
2. 提供的路径(对于相对路径,如果不受限制,使用当前工作目录)
|
||||
3. `$DYLD_FALLBACK_FRAMEWORK_PATH`
|
||||
4. `/Library/Frameworks`(如果不受限制)
|
||||
5. `/System/Library/Frameworks`
|
||||
|
||||
{% hint style="danger" %}
|
||||
如果是框架路径,则劫持它的方式是:
|
||||
如果是框架路径,劫持的方式是:
|
||||
|
||||
* 如果进程是**不受限制的**,滥用**相对路径从CWD**和提到的环境变量(即使在文档中没有说过如果进程受限制,DYLD\_\*环境变量将被移除)
|
||||
* 如果进程是 **不受限制的**,可以滥用从 CWD 开始的 **相对路径** 和提到的环境变量(即使在文档中没有提到进程是否受限制,DYLD\_\* 环境变量会被移除)
|
||||
{% endhint %}
|
||||
|
||||
* 当路径**包含斜杠但不是框架路径**(即完整路径或指向dylib的部分路径)时,dlopen()首先在(如果设置了)**`$DYLD_LIBRARY_PATH`中查找(使用路径的叶部分)。接下来,dyld尝试提供的路径**(对于相对路径,仅对于不受限制的进程使用当前工作目录)。最后,对于旧二进制文件,dyld将尝试回退。如果在启动时设置了\*\*`$DYLD_FALLBACK_LIBRARY_PATH`**,dyld将在这些目录中搜索,否则,dyld将在**`/usr/local/lib/`**中查找(如果进程不受限制),然后在**`/usr/lib/`\*\*中查找。
|
||||
|
||||
* 当路径 **包含斜杠但不是框架路径**(即完整路径或指向 dylib 的部分路径),dlopen() 首先在(如果设置了) **`$DYLD_LIBRARY_PATH`** 中查找(使用路径的叶子部分)。接下来,dyld 将尝试使用 **提供的路径**(对于相对路径,仅对于不受限制的进程使用当前工作目录)。最后,对于旧的二进制文件,dyld 将尝试一些回退。如果在启动时设置了 **`$DYLD_FALLBACK_LIBRARY_PATH`**,dyld 将在这些目录中搜索,否则,dyld 将在 **`/usr/local/lib/`** 中查找(如果进程是不受限制的),然后在 **`/usr/lib/`** 中查找。
|
||||
1. `$DYLD_LIBRARY_PATH`
|
||||
2. 提供的路径(对于相对路径,如果不受限制,则使用当前工作目录)
|
||||
2. 提供的路径(对于相对路径,如果不受限制,使用当前工作目录)
|
||||
3. `$DYLD_FALLBACK_LIBRARY_PATH`
|
||||
4. `/usr/local/lib/`(如果不受限制)
|
||||
5. `/usr/lib/`
|
||||
|
||||
{% hint style="danger" %}
|
||||
如果名称中有斜杠而不是框架,则劫持它的方式是:
|
||||
如果名称中有斜杠而不是框架,劫持的方式是:
|
||||
|
||||
* 如果二进制文件是**不受限制的**,那么可以从CWD或`/usr/local/lib`加载内容(或滥用其中提到的环境变量)
|
||||
* 如果二进制文件是 **不受限制的**,那么可以从 CWD 或 `/usr/local/lib` 中加载内容(或滥用其中提到的环境变量之一)
|
||||
{% endhint %}
|
||||
|
||||
注意:没有**控制dlopen搜索**的配置文件。
|
||||
{% hint style="info" %}
|
||||
注意:没有配置文件来 **控制 dlopen 搜索**。
|
||||
|
||||
注意:如果主可执行文件是\*\*set\[ug]id二进制文件或具有授权的
|
||||
注意:如果主可执行文件是 **set\[ug]id 二进制文件或使用授权签名**,则会 **忽略所有环境变量**,只能使用完整路径([查看 DYLD\_INSERT\_LIBRARIES 限制](macos-dyld-hijacking-and-dyld\_insert\_libraries.md#check-dyld\_insert\_librery-restrictions) 获取更详细信息)
|
||||
|
||||
注意:Apple 平台使用 "universal" 文件来组合 32 位和 64 位库。这意味着没有 **单独的 32 位和 64 位搜索路径**。
|
||||
|
||||
注意:在 Apple 平台上,大多数 OS dylibs 都 **合并到 dyld 缓存** 中,不存在于磁盘上。因此,调用 **`stat()`** 来预先检查 OS dylib 是否存在 **不起作用**。但是,**`dlopen_preflight()`** 使用与 **`dlopen()`** 相同的步骤来查找兼容的 mach-o 文件。
|
||||
{% endhint %}
|
||||
|
||||
**检查路径**
|
||||
|
||||
让我们使用以下代码检查所有选项:
|
||||
```c
|
||||
// gcc dlopentest.c -o dlopentest -Wl,-rpath,/tmp/test
|
||||
#include <dlfcn.h>
|
||||
|
@ -217,33 +233,27 @@ fprintf(stderr, "Error loading: %s\n\n\n", dlerror());
|
|||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
如果您编译并执行它,您可以看到**每个库未成功搜索到的位置**。此外,您可以**过滤FS日志**:
|
||||
|
||||
如果您编译并执行它,您可以看到**每个库未成功搜索的位置**。此外,您可以**过滤FS日志**:
|
||||
```bash
|
||||
sudo fs_usage | grep "dlopentest"
|
||||
```
|
||||
|
||||
## 相对路径劫持
|
||||
|
||||
如果一个**特权二进制应用**(比如一个SUID或一些拥有强大权限的二进制应用)正在**加载一个相对路径**库(例如使用`@executable_path`或`@loader_path`),并且**禁用了库验证**,那么可能会将二进制应用移动到攻击者可以**修改相对路径加载的库**的位置,并利用它来在进程中注入代码。
|
||||
如果一个**特权二进制应用程序**(比如一个SUID或一些拥有强大权限的二进制文件)正在**加载一个相对路径**库(例如使用`@executable_path`或`@loader_path`),并且**禁用了库验证**,那么可能会将二进制文件移动到攻击者可以**修改相对路径加载的库**的位置,并滥用它来向进程注入代码。
|
||||
|
||||
## 清理 `DYLD_*` 和 `LD_LIBRARY_PATH` 环境变量
|
||||
## 修剪 `DYLD_*` 和 `LD_LIBRARY_PATH` 环境变量
|
||||
|
||||
在文件 `dyld-dyld-832.7.1/src/dyld2.cpp` 中,可以找到函数\*\*`pruneEnvironmentVariables`\*\*,它将删除任何以`DYLD_`开头和`LD_LIBRARY_PATH=`的环境变量。
|
||||
在文件 `dyld-dyld-832.7.1/src/dyld2.cpp` 中,可以找到函数**`pruneEnvironmentVariables`**,它将删除任何以`DYLD_`开头和`LD_LIBRARY_PATH=`的环境变量。
|
||||
|
||||
它还会将\*\*`DYLD_FALLBACK_FRAMEWORK_PATH`**和**`DYLD_FALLBACK_LIBRARY_PATH`**这两个环境变量特别设置为**null\*\*,用于**suid**和**sgid**二进制应用。
|
||||
|
||||
如果针对类似OSX的目标,该函数将从同一文件的\*\*`_main`\*\*函数中调用:
|
||||
它还会将**`DYLD_FALLBACK_FRAMEWORK_PATH`**和**`DYLD_FALLBACK_LIBRARY_PATH`**这两个环境变量对于**suid**和**sgid**二进制文件设置为**null**。
|
||||
|
||||
如果针对OSX,可以从同一文件的**`_main`**函数中调用此函数:
|
||||
```cpp
|
||||
#if TARGET_OS_OSX
|
||||
if ( !gLinkContext.allowEnvVarsPrint && !gLinkContext.allowEnvVarsPath && !gLinkContext.allowEnvVarsSharedCache ) {
|
||||
pruneEnvironmentVariables(envp, &apple);
|
||||
```
|
||||
|
||||
并且这些布尔标志在代码中的同一文件中设置:
|
||||
|
||||
```cpp
|
||||
#if TARGET_OS_OSX
|
||||
// support chrooting from old kernel
|
||||
|
@ -274,15 +284,13 @@ gLinkContext.allowClassicFallbackPaths = !isRestricted;
|
|||
gLinkContext.allowInsertFailures = false;
|
||||
gLinkContext.allowInterposing = true;
|
||||
```
|
||||
|
||||
这基本上意味着,如果二进制文件是**suid**或**sgid**,或者在标头中有一个**RESTRICT**段,或者使用**CS\_RESTRICT**标志签名,那么\*\*`!gLinkContext.allowEnvVarsPrint && !gLinkContext.allowEnvVarsPath && !gLinkContext.allowEnvVarsSharedCache`\*\*为真,环境变量将被修剪。
|
||||
这基本上意味着,如果二进制文件是**suid**或**sgid**,或者在标头中有一个**RESTRICT**段,或者使用**CS\_RESTRICT**标志进行签名,那么**`!gLinkContext.allowEnvVarsPrint && !gLinkContext.allowEnvVarsPath && !gLinkContext.allowEnvVarsSharedCache`**为真,环境变量将被修剪。
|
||||
|
||||
请注意,如果CS\_REQUIRE\_LV为真,则变量不会被修剪,但库验证将检查它们是否使用与原始二进制文件相同的证书。
|
||||
|
||||
## 检查限制
|
||||
|
||||
### SUID & SGID
|
||||
|
||||
```bash
|
||||
# Make it owned by root and suid
|
||||
sudo chown root hello
|
||||
|
@ -293,14 +301,11 @@ DYLD_INSERT_LIBRARIES=inject.dylib ./hello
|
|||
# Remove suid
|
||||
sudo chmod -s hello
|
||||
```
|
||||
|
||||
### 区块 `__RESTRICT` 与段 `__restrict`
|
||||
|
||||
```bash
|
||||
gcc -sectcreate __RESTRICT __restrict /dev/null hello.c -o hello-restrict
|
||||
DYLD_INSERT_LIBRARIES=inject.dylib ./hello-restrict
|
||||
```
|
||||
|
||||
### 强化运行时
|
||||
|
||||
在钥匙串中创建一个新证书,并使用它来签署二进制文件:
|
||||
|
@ -328,31 +333,27 @@ DYLD_INSERT_LIBRARIES=inject.dylib ./hello-signed # Won't work
|
|||
{% endcode %}
|
||||
|
||||
{% hint style="danger" %}
|
||||
请注意,即使有用标志\*\*`0x0(none)`**签名的二进制文件,当执行时也可以动态地获得**`CS_RESTRICT`\*\*标志,因此这种技术在其中不起作用。
|
||||
|
||||
您可以使用以下命令检查进程是否具有此标志(获取[**csops here**](https://github.com/axelexic/CSOps)):
|
||||
请注意,即使有用标志**`0x0(none)`**签名的二进制文件,当执行时也可以动态地获得**`CS_RESTRICT`**标志,因此这种技术在其中不起作用。
|
||||
|
||||
您可以使用以下命令检查进程是否具有此标志(获取[**csops here**](https://github.com/axelexic/CSOps)):
|
||||
```bash
|
||||
csops -status <pid>
|
||||
```
|
||||
|
||||
然后检查标志0x800是否已启用。
|
||||
{% endhint %}
|
||||
|
||||
## 参考资料
|
||||
|
||||
* [https://theevilbit.github.io/posts/dyld\_insert\_libraries\_dylib\_injection\_in\_macos\_osx\_deep\_dive/](https://theevilbit.github.io/posts/dyld\_insert\_libraries\_dylib\_injection\_in\_macos\_osx\_deep\_dive/)
|
||||
* [**\*OS Internals, Volume I: User Mode. By Jonathan Levin**](https://www.amazon.com/MacOS-iOS-Internals-User-Mode/dp/099105556X)
|
||||
|
||||
<details>
|
||||
|
||||
<summary><strong>从零开始学习AWS黑客技术,成为专家</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE(HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
||||
<summary><strong>从零开始学习AWS黑客技术,成为专家</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
||||
|
||||
支持HackTricks的其他方式:
|
||||
|
||||
* 如果您想看到您的**公司在HackTricks中做广告**或**下载PDF格式的HackTricks**,请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
|
||||
* 获取[**官方PEASS&HackTricks周边产品**](https://peass.creator-spring.com)
|
||||
* 获取[**官方PEASS & HackTricks周边产品**](https://peass.creator-spring.com)
|
||||
* 发现[**PEASS家族**](https://opensea.io/collection/the-peass-family),我们的独家[**NFTs**](https://opensea.io/collection/the-peass-family)收藏品
|
||||
* **加入** 💬 [**Discord群**](https://discord.gg/hRep4RUj7f) 或 [**电报群**](https://t.me/peass) 或 **关注**我的**Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**。**
|
||||
* **加入** 💬 [**Discord群组**](https://discord.gg/hRep4RUj7f) 或 [**电报群组**](https://t.me/peass) 或 **关注**我们的**Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
|
||||
* 通过向[**HackTricks**](https://github.com/carlospolop/hacktricks)和[**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github仓库提交PR来分享您的黑客技巧。
|
||||
|
||||
</details>
|
||||
|
|
|
@ -0,0 +1,322 @@
|
|||
# macOS Dyld 进程
|
||||
|
||||
<details>
|
||||
|
||||
<summary><strong>从零开始学习 AWS 黑客技术,成为专家</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE(HackTricks AWS 红队专家)</strong></a><strong>!</strong></summary>
|
||||
|
||||
支持 HackTricks 的其他方式:
|
||||
|
||||
- 如果您想看到您的**公司在 HackTricks 中做广告**或**下载 PDF 版的 HackTricks**,请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
|
||||
- 获取[**官方 PEASS & HackTricks 商品**](https://peass.creator-spring.com)
|
||||
- 探索[**PEASS 家族**](https://opensea.io/collection/the-peass-family),我们的独家[**NFTs**](https://opensea.io/collection/the-peass-family)
|
||||
- **加入** 💬 [**Discord 群组**](https://discord.gg/hRep4RUj7f) 或 [**电报群组**](https://t.me/peass) 或在 **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)** 上关注我们**。
|
||||
- 通过向 [**HackTricks**](https://github.com/carlospolop/hacktricks) 和 [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github 仓库提交 PR 来分享您的黑客技巧。
|
||||
|
||||
</details>
|
||||
|
||||
## 基本信息
|
||||
|
||||
Mach-o 二进制文件的真正**入口点**是动态链接器,在 `LC_LOAD_DYLINKER` 中定义,通常为 `/usr/lib/dyld`。
|
||||
|
||||
这个链接器需要定位所有可执行库,在内存中映射它们,并链接所有非懒加载库。只有在此过程完成后,二进制文件的入口点才会被执行。
|
||||
|
||||
当然,**`dyld`** 没有任何依赖(它使用系统调用和 libSystem 片段)。
|
||||
|
||||
{% hint style="danger" %}
|
||||
如果此链接器包含任何漏洞,因为它在执行任何二进制文件(甚至是高度特权的二进制文件)之前被执行,将有可能**提升权限**。
|
||||
{% endhint %}
|
||||
|
||||
### 流程
|
||||
|
||||
Dyld 将由 **`dyldboostrap::start`** 加载,它还会加载诸如**栈保护**之类的东西。这是因为此函数将在其**`apple`**参数向量中接收此类**敏感**的**值**。
|
||||
|
||||
**`dyls::_main()`** 是 dyld 的入口点,它的第一个任务是运行 `configureProcessRestrictions()`,通常会限制**`DYLD_*`**环境变量,详细说明在:
|
||||
|
||||
{% content-ref url="./" %}
|
||||
[.](./)
|
||||
{% endcontent-ref %}
|
||||
|
||||
然后,它映射 dyld 共享缓存,其中预链接了所有重要的系统库,然后映射二进制文件依赖的库,并递归继续,直到加载所有需要的库。因此:
|
||||
|
||||
1. 它开始加载插入的库,使用 `DYLD_INSERT_LIBRARIES`(如果允许)
|
||||
2. 然后是共享缓存中的库
|
||||
3. 然后是导入的库
|
||||
4. 然后继续递归导入库
|
||||
|
||||
一旦所有库都加载完毕,这些库的**初始化程序**将被运行。这些程序使用**`__attribute__((constructor))`**编写,在 `LC_ROUTINES[_64]` 中定义(现在已弃用),或者通过指针在一个带有 `S_MOD_INIT_FUNC_POINTERS` 标志的部分中(通常为:**`__DATA.__MOD_INIT_FUNC`**)。
|
||||
|
||||
终结器使用**`__attribute__((destructor))`**编写,并位于一个带有 `S_MOD_TERM_FUNC_POINTERS` 标志的部分中(**`__DATA.__mod_term_func`**)。
|
||||
|
||||
### 存根
|
||||
|
||||
macOS 中的所有二进制文件都是动态链接的。因此,它们包含一些存根部分,帮助二进制文件在不同的机器和上下文中跳转到正确的代码。在执行二进制文件时,需要 dyld 来解析这些地址(至少是非懒加载的地址)。
|
||||
|
||||
二进制文件中的一些存根部分:
|
||||
|
||||
- **`__TEXT.__[auth_]stubs`**:来自 `__DATA` 部分的指针
|
||||
- **`__TEXT.__stub_helper`**:调用带有要调用函数信息的动态链接的小代码
|
||||
- **`__DATA.__[auth_]got`**:全局偏移表(指向导入函数的地址,在解析后绑定(在加载时绑定,因为它标记为 `S_NON_LAZY_SYMBOL_POINTERS`))
|
||||
- **`__DATA.__nl_symbol_ptr`**:非懒加载符号指针(在加载时绑定,因为它标记为 `S_NON_LAZY_SYMBOL_POINTERS`)
|
||||
- **`__DATA.__la_symbol_ptr`**:惰性符号指针(首次访问时绑定)
|
||||
|
||||
{% hint style="warning" %}
|
||||
请注意,带有前缀 "auth\_" 的指针使用一个进程内加密密钥进行保护(PAC)。此外,可以使用 arm64 指令 `BLRA[A/B]` 在跟随指针之前验证指针。而 RETA\[A/B\] 可以用于替代 RET 地址。\
|
||||
实际上,**`__TEXT.__auth_stubs`** 中的代码将使用 **`braa`** 而不是 **`bl`** 来调用请求的函数以验证指针。
|
||||
|
||||
还要注意,当前的 dyld 版本将**所有内容加载为非懒加载**。
|
||||
{% endhint %}
|
||||
|
||||
### 查找惰性符号
|
||||
```c
|
||||
//gcc load.c -o load
|
||||
#include <stdio.h>
|
||||
int main (int argc, char **argv, char **envp, char **apple)
|
||||
{
|
||||
printf("Hi\n");
|
||||
}
|
||||
```
|
||||
有趣的反汇编部分:
|
||||
```armasm
|
||||
; objdump -d ./load
|
||||
100003f7c: 90000000 adrp x0, 0x100003000 <_main+0x1c>
|
||||
100003f80: 913e9000 add x0, x0, #4004
|
||||
100003f84: 94000005 bl 0x100003f98 <_printf+0x100003f98>
|
||||
```
|
||||
可以看到跳转到调用 printf 的位置是在 **`__TEXT.__stubs`**:
|
||||
```bash
|
||||
objdump --section-headers ./load
|
||||
|
||||
./load: file format mach-o arm64
|
||||
|
||||
Sections:
|
||||
Idx Name Size VMA Type
|
||||
0 __text 00000038 0000000100003f60 TEXT
|
||||
1 __stubs 0000000c 0000000100003f98 TEXT
|
||||
2 __cstring 00000004 0000000100003fa4 DATA
|
||||
3 __unwind_info 00000058 0000000100003fa8 DATA
|
||||
4 __got 00000008 0000000100004000 DATA
|
||||
```
|
||||
在**`__stubs`**部分的反汇编中:
|
||||
```bash
|
||||
objdump -d --section=__stubs ./load
|
||||
|
||||
./load: file format mach-o arm64
|
||||
|
||||
Disassembly of section __TEXT,__stubs:
|
||||
|
||||
0000000100003f98 <__stubs>:
|
||||
100003f98: b0000010 adrp x16, 0x100004000 <__stubs+0x4>
|
||||
100003f9c: f9400210 ldr x16, [x16]
|
||||
100003fa0: d61f0200 br x16
|
||||
```
|
||||
你可以看到我们正在**跳转到GOT的地址**,在这种情况下,它是通过非延迟解析的,将包含printf函数的地址。
|
||||
|
||||
在其他情况下,而不是直接跳转到GOT,它可以跳转到**`__DATA.__la_symbol_ptr`**,它将加载一个代表它正在尝试加载的函数的值,然后跳转到**`__TEXT.__stub_helper`**,它跳转到包含**`dyld_stub_binder`**地址的**`__DATA.__nl_symbol_ptr`**,该函数接受函数编号和地址作为参数。\
|
||||
在找到搜索的函数地址后,该最后一个函数将其写入**`__TEXT.__stub_helper`**中的相应位置,以避免将来进行查找。
|
||||
|
||||
{% hint style="success" %}
|
||||
但请注意,当前dyld版本将所有内容都作为非延迟加载。
|
||||
{% endhint %}
|
||||
|
||||
#### Dyld操作码
|
||||
|
||||
最后,**`dyld_stub_binder`**需要找到指定的函数并将其写入正确的地址,以免再次搜索。为此,它在dyld内部使用操作码(有限状态机)。
|
||||
|
||||
## apple\[]参数向量
|
||||
|
||||
在macOS中,主函数实际上接收4个参数而不是3个。第四个称为apple,每个条目的形式为`key=value`。例如:
|
||||
```c
|
||||
// gcc apple.c -o apple
|
||||
#include <stdio.h>
|
||||
int main (int argc, char **argv, char **envp, char **apple)
|
||||
{
|
||||
for (int i=0; apple[i]; i++)
|
||||
printf("%d: %s\n", i, apple[i])
|
||||
}
|
||||
```
|
||||
结果:
|
||||
```
|
||||
0: executable_path=./a
|
||||
1:
|
||||
2:
|
||||
3:
|
||||
4: ptr_munge=
|
||||
5: main_stack=
|
||||
6: executable_file=0x1a01000012,0x5105b6a
|
||||
7: dyld_file=0x1a01000012,0xfffffff0009834a
|
||||
8: executable_cdhash=757a1b08ab1a79c50a66610f3adbca86dfd3199b
|
||||
9: executable_boothash=f32448504e788a2c5935e372d22b7b18372aa5aa
|
||||
10: arm64e_abi=os
|
||||
11: th_port=
|
||||
```
|
||||
{% hint style="success" %}
|
||||
当这些值到达主函数时,敏感信息已经被删除,否则可能会导致数据泄漏。
|
||||
{% endhint %}
|
||||
|
||||
在进入主函数之前,可以通过调试查看所有这些有趣的值:
|
||||
|
||||
<pre><code>lldb ./apple
|
||||
|
||||
<strong>(lldb) target create "./a"
|
||||
</strong>当前可执行文件设置为'/tmp/a' (arm64)。
|
||||
(lldb) process launch -s
|
||||
[..]
|
||||
|
||||
<strong>(lldb) mem read $sp
|
||||
</strong>0x16fdff510: 00 00 00 00 01 00 00 00 01 00 00 00 00 00 00 00 ................
|
||||
0x16fdff520: d8 f6 df 6f 01 00 00 00 00 00 00 00 00 00 00 00 ...o............
|
||||
|
||||
<strong>(lldb) x/55s 0x016fdff6d8
|
||||
</strong>[...]
|
||||
0x16fdffd6a: "TERM_PROGRAM=WarpTerminal"
|
||||
0x16fdffd84: "WARP_USE_SSH_WRAPPER=1"
|
||||
0x16fdffd9b: "WARP_IS_LOCAL_SHELL_SESSION=1"
|
||||
0x16fdffdb9: "SDKROOT=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.4.sdk"
|
||||
0x16fdffe24: "NVM_DIR=/Users/carlospolop/.nvm"
|
||||
0x16fdffe44: "CONDA_CHANGEPS1=false"
|
||||
0x16fdffe5a: ""
|
||||
0x16fdffe5b: ""
|
||||
0x16fdffe5c: ""
|
||||
0x16fdffe5d: ""
|
||||
0x16fdffe5e: ""
|
||||
0x16fdffe5f: ""
|
||||
0x16fdffe60: "pfz=0xffeaf0000"
|
||||
0x16fdffe70: "stack_guard=0x8af2b510e6b800b5"
|
||||
0x16fdffe8f: "malloc_entropy=0xf2349fbdea53f1e4,0x3fd85d7dcf817101"
|
||||
0x16fdffec4: "ptr_munge=0x983e2eebd2f3e746"
|
||||
0x16fdffee1: "main_stack=0x16fe00000,0x7fc000,0x16be00000,0x4000000"
|
||||
0x16fdfff17: "executable_file=0x1a01000012,0x5105b6a"
|
||||
0x16fdfff3e: "dyld_file=0x1a01000012,0xfffffff0009834a"
|
||||
0x16fdfff67: "executable_cdhash=757a1b08ab1a79c50a66610f3adbca86dfd3199b"
|
||||
0x16fdfffa2: "executable_boothash=f32448504e788a2c5935e372d22b7b18372aa5aa"
|
||||
0x16fdfffdf: "arm64e_abi=os"
|
||||
0x16fdfffed: "th_port=0x103"
|
||||
0x16fdffffb: ""
|
||||
</code></pre>
|
||||
|
||||
## dyld\_all\_image\_infos
|
||||
|
||||
这是由dyld导出的一个结构,包含有关dyld状态的信息,可以在[**源代码**](https://opensource.apple.com/source/dyld/dyld-852.2/include/mach-o/dyld\_images.h.auto.html)中找到,包括版本、指向dyld\_image\_info数组的指针、指向dyld\_image\_notifier的指针、如果进程与共享缓存分离、是否调用了libSystem初始化程序、指向dyld自身Mach头文件的指针、指向dyld版本字符串的指针...
|
||||
|
||||
## dyld环境变量
|
||||
|
||||
### 调试dyld
|
||||
|
||||
有助于了解dyld操作的有趣环境变量:
|
||||
|
||||
* **DYLD\_PRINT\_LIBRARIES**
|
||||
|
||||
检查加载的每个库:
|
||||
```
|
||||
DYLD_PRINT_LIBRARIES=1 ./apple
|
||||
dyld[19948]: <9F848759-9AB8-3BD2-96A1-C069DC1FFD43> /private/tmp/a
|
||||
dyld[19948]: <F0A54B2D-8751-35F1-A3CF-F1A02F842211> /usr/lib/libSystem.B.dylib
|
||||
dyld[19948]: <C683623C-1FF6-3133-9E28-28672FDBA4D3> /usr/lib/system/libcache.dylib
|
||||
dyld[19948]: <BFDF8F55-D3DC-3A92-B8A1-8EF165A56F1B> /usr/lib/system/libcommonCrypto.dylib
|
||||
dyld[19948]: <B29A99B2-7ADE-3371-A774-B690BEC3C406> /usr/lib/system/libcompiler_rt.dylib
|
||||
dyld[19948]: <65612C42-C5E4-3821-B71D-DDE620FB014C> /usr/lib/system/libcopyfile.dylib
|
||||
dyld[19948]: <B3AC12C0-8ED6-35A2-86C6-0BFA55BFF333> /usr/lib/system/libcorecrypto.dylib
|
||||
dyld[19948]: <8790BA20-19EC-3A36-8975-E34382D9747C> /usr/lib/system/libdispatch.dylib
|
||||
dyld[19948]: <4BB77515-DBA8-3EDF-9AF7-3C9EAE959EA6> /usr/lib/system/libdyld.dylib
|
||||
dyld[19948]: <F7CE9486-FFF5-3CB8-B26F-75811EF4283A> /usr/lib/system/libkeymgr.dylib
|
||||
dyld[19948]: <1A7038EC-EE49-35AE-8A3C-C311083795FB> /usr/lib/system/libmacho.dylib
|
||||
[...]
|
||||
```
|
||||
* **DYLD\_PRINT\_SEGMENTS**
|
||||
|
||||
检查每个库是如何加载的:
|
||||
```
|
||||
DYLD_PRINT_SEGMENTS=1 ./apple
|
||||
dyld[21147]: re-using existing shared cache (/System/Volumes/Preboot/Cryptexes/OS/System/Library/dyld/dyld_shared_cache_arm64e):
|
||||
dyld[21147]: 0x181944000->0x1D5D4BFFF init=5, max=5 __TEXT
|
||||
dyld[21147]: 0x1D5D4C000->0x1D5EC3FFF init=1, max=3 __DATA_CONST
|
||||
dyld[21147]: 0x1D7EC4000->0x1D8E23FFF init=3, max=3 __DATA
|
||||
dyld[21147]: 0x1D8E24000->0x1DCEBFFFF init=3, max=3 __AUTH
|
||||
dyld[21147]: 0x1DCEC0000->0x1E22BFFFF init=1, max=3 __AUTH_CONST
|
||||
dyld[21147]: 0x1E42C0000->0x1E5457FFF init=1, max=1 __LINKEDIT
|
||||
dyld[21147]: 0x1E5458000->0x22D173FFF init=5, max=5 __TEXT
|
||||
dyld[21147]: 0x22D174000->0x22D9E3FFF init=1, max=3 __DATA_CONST
|
||||
dyld[21147]: 0x22F9E4000->0x230F87FFF init=3, max=3 __DATA
|
||||
dyld[21147]: 0x230F88000->0x234EC3FFF init=3, max=3 __AUTH
|
||||
dyld[21147]: 0x234EC4000->0x237573FFF init=1, max=3 __AUTH_CONST
|
||||
dyld[21147]: 0x239574000->0x270BE3FFF init=1, max=1 __LINKEDIT
|
||||
dyld[21147]: Kernel mapped /private/tmp/a
|
||||
dyld[21147]: __PAGEZERO (...) 0x000000904000->0x000101208000
|
||||
dyld[21147]: __TEXT (r.x) 0x000100904000->0x000100908000
|
||||
dyld[21147]: __DATA_CONST (rw.) 0x000100908000->0x00010090C000
|
||||
dyld[21147]: __LINKEDIT (r..) 0x00010090C000->0x000100910000
|
||||
dyld[21147]: Using mapping in dyld cache for /usr/lib/libSystem.B.dylib
|
||||
dyld[21147]: __TEXT (r.x) 0x00018E59D000->0x00018E59F000
|
||||
dyld[21147]: __DATA_CONST (rw.) 0x0001D5DFDB98->0x0001D5DFDBA8
|
||||
dyld[21147]: __AUTH_CONST (rw.) 0x0001DDE015A8->0x0001DDE01878
|
||||
dyld[21147]: __AUTH (rw.) 0x0001D9688650->0x0001D9688658
|
||||
dyld[21147]: __DATA (rw.) 0x0001D808AD60->0x0001D808AD68
|
||||
dyld[21147]: __LINKEDIT (r..) 0x000239574000->0x000270BE4000
|
||||
dyld[21147]: Using mapping in dyld cache for /usr/lib/system/libcache.dylib
|
||||
dyld[21147]: __TEXT (r.x) 0x00018E597000->0x00018E59D000
|
||||
dyld[21147]: __DATA_CONST (rw.) 0x0001D5DFDAF0->0x0001D5DFDB98
|
||||
dyld[21147]: __AUTH_CONST (rw.) 0x0001DDE014D0->0x0001DDE015A8
|
||||
dyld[21147]: __LINKEDIT (r..) 0x000239574000->0x000270BE4000
|
||||
[...]
|
||||
```
|
||||
* **DYLD\_PRINT\_INITIALIZERS**
|
||||
|
||||
打印每个库初始化程序运行时的信息:
|
||||
```
|
||||
DYLD_PRINT_INITIALIZERS=1 ./apple
|
||||
dyld[21623]: running initializer 0x18e59e5c0 in /usr/lib/libSystem.B.dylib
|
||||
[...]
|
||||
```
|
||||
### 其他
|
||||
|
||||
* `DYLD_BIND_AT_LAUNCH`: 惰性绑定将使用非惰性绑定解析
|
||||
* `DYLD_DISABLE_PREFETCH`: 禁用对 \_\_DATA 和 \_\_LINKEDIT 内容的预取
|
||||
* `DYLD_FORCE_FLAT_NAMESPACE`: 单级绑定
|
||||
* `DYLD_[FRAMEWORK/LIBRARY]_PATH | DYLD_FALLBACK_[FRAMEWORK/LIBRARY]_PATH | DYLD_VERSIONED_[FRAMEWORK/LIBRARY]_PATH`: 解析路径
|
||||
* `DYLD_INSERT_LIBRARIES`: 加载特定库
|
||||
* `DYLD_PRINT_TO_FILE`: 将 dyld 调试信息写入文件
|
||||
* `DYLD_PRINT_APIS`: 打印 libdyld API 调用
|
||||
* `DYLD_PRINT_APIS_APP`: 打印主程序调用的 libdyld API
|
||||
* `DYLD_PRINT_BINDINGS`: 绑定时打印符号
|
||||
* `DYLD_WEAK_BINDINGS`: 仅在绑定时打印弱符号
|
||||
* `DYLD_PRINT_CODE_SIGNATURES`: 打印代码签名注册操作
|
||||
* `DYLD_PRINT_DOFS`: 打印加载的 D-Trace 对象格式部分
|
||||
* `DYLD_PRINT_ENV`: 打印 dyld 可见的环境变量
|
||||
* `DYLD_PRINT_INTERPOSTING`: 打印 interposing 操作
|
||||
* `DYLD_PRINT_LIBRARIES`: 打印加载的库
|
||||
* `DYLD_PRINT_OPTS`: 打印加载选项
|
||||
* `DYLD_REBASING`: 打印符号重新定位操作
|
||||
* `DYLD_RPATHS`: 打印 @rpath 的扩展
|
||||
* `DYLD_PRINT_SEGMENTS`: 打印 Mach-O 段的映射
|
||||
* `DYLD_PRINT_STATISTICS`: 打印时间统计信息
|
||||
* `DYLD_PRINT_STATISTICS_DETAILS`: 打印详细的时间统计信息
|
||||
* `DYLD_PRINT_WARNINGS`: 打印警告消息
|
||||
* `DYLD_SHARED_CACHE_DIR`: 用于共享库缓存的路径
|
||||
* `DYLD_SHARED_REGION`: "use", "private", "avoid"
|
||||
* `DYLD_USE_CLOSURES`: 启用闭包
|
||||
|
||||
可以通过类似以下方式找到更多内容:
|
||||
```bash
|
||||
strings /usr/lib/dyld | grep "^DYLD_" | sort -u
|
||||
```
|
||||
或者从[https://opensource.apple.com/tarballs/dyld/dyld-852.2.tar.gz](https://opensource.apple.com/tarballs/dyld/dyld-852.2.tar.gz)下载dyld项目,并在文件夹内运行:
|
||||
```bash
|
||||
find . -type f | xargs grep strcmp| grep key,\ \" | cut -d'"' -f2 | sort -u
|
||||
```
|
||||
## 参考资料
|
||||
|
||||
* [**\*OS Internals, Volume I: User Mode. By Jonathan Levin**](https://www.amazon.com/MacOS-iOS-Internals-User-Mode/dp/099105556X)
|
||||
|
||||
<details>
|
||||
|
||||
<summary><strong>从零开始学习AWS黑客技术,成为专家</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
||||
|
||||
支持HackTricks的其他方式:
|
||||
|
||||
* 如果您想看到您的**公司在HackTricks中做广告**或**下载PDF格式的HackTricks**,请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
|
||||
* 获取[**官方PEASS & HackTricks周边产品**](https://peass.creator-spring.com)
|
||||
* 探索[**PEASS家族**](https://opensea.io/collection/the-peass-family),我们的独家[**NFTs**](https://opensea.io/collection/the-peass-family)
|
||||
* **加入** 💬 [**Discord群组**](https://discord.gg/hRep4RUj7f) 或 [**电报群组**](https://t.me/peass) 或 **关注**我们的**Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**。**
|
||||
* 通过向[**HackTricks**](https://github.com/carlospolop/hacktricks)和[**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github仓库提交PR来分享您的黑客技巧。
|
||||
|
||||
</details>
|
Loading…
Reference in a new issue