diff --git a/SUMMARY.md b/SUMMARY.md index 5d2fc846d..6feb25b60 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -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) diff --git a/macos-hardening/macos-security-and-privilege-escalation/macos-files-folders-and-binaries/README.md b/macos-hardening/macos-security-and-privilege-escalation/macos-files-folders-and-binaries/README.md index bb14e9046..91785f85c 100644 --- a/macos-hardening/macos-security-and-privilege-escalation/macos-files-folders-and-binaries/README.md +++ b/macos-hardening/macos-security-and-privilege-escalation/macos-files-folders-and-binaries/README.md @@ -1,4 +1,4 @@ -# macOS文件夹、文件和二进制文件与内存 +# macOS文件夹、文件和二进制文件 & 内存
@@ -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来分享您的黑客技巧。
## 文件层次结构 -- **/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 %}
+一些提取器可能无法工作,因为 dylibs 预链接到硬编码地址,因此它们可能会跳转到未知地址 + +{% hint style="success" %} +还可以通过在 Xcode 中使用模拟器来下载 macOS 中其他 \*OS 设备的共享库缓存。它们将被下载到:ls `$HOME/Library/Developer/Xcode/<*>OS\ DeviceSupport//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= 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 `清除此标志,系统将不知道文件已压缩,因此无法解压缩和访问数据(系统会认为文件实际上是空的)。 -可以使用 `ls -lO` 查看此属性,因为压缩文件还会标记为标志 `UF_COMPRESSED`。如果删除压缩文件,则使用 `chflags nocompressed ` 删除此标志,系统将不知道文件已被压缩,因此无法解压缩和访问数据(系统会认为文件实际上是空的)。 +工具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`**:已停用的守护进程列表。 diff --git a/macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-function-hooking.md b/macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-function-hooking.md index 480c04354..b58079eee 100644 --- a/macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-function-hooking.md +++ b/macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-function-hooking.md @@ -1,28 +1,30 @@ -# macOS Function Hooking +# macOS函数挂钩
-从零开始学习AWS黑客技术,成为专家 htARTE(HackTricks AWS Red Team Expert) +从零开始学习AWS黑客技术,成为专家 htARTE(HackTricks AWS红队专家) 支持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来分享您的黑客技巧。
## 函数插入 -创建一个包含指向**原始**和**替换**函数的**函数指针**元组的**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 @@ -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 @@ -52,33 +56,10 @@ printf("Hello World!\n"); return 0; } ``` +{% endtab %} -#### macOS功能挂钩 - -macOS提供了一种称为`DYLD_INSERT_LIBRARIES`的环境变量,允许我们在程序加载时注入动态链接库。这为我们提供了一种功能挂钩的方法,可以用来劫持程序的函数调用。 - -我们可以创建一个动态链接库,重写目标函数的实现,然后将其注入到目标程序中。这样,当目标程序调用该函数时,实际上会执行我们注入的代码。 - -以下是一个示例,展示了如何使用`DYLD_INSERT_LIBRARIES`环境变量来劫持`open`函数的调用: - -```c -#include -#include - -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 ` 或 [`class-dump `](https://github.com/nygard/class-dump) 检索它。 +请注意,由于方法和类是根据它们的名称访问的,这些信息存储在二进制文件中,因此可以使用 `otool -ov ` 或 [`class-dump `](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 #import @@ -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 LSEnvironment @@ -330,7 +334,6 @@ return 0; /Applications/Application.app/Contents/malicious.dylib ``` - 然后**重新注册**应用程序: {% 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);
-从零开始学习AWS黑客技术,成为专家 htARTE (HackTricks AWS Red Team Expert)! +从零开始学习 AWS 黑客技术,成为专家 htARTE(HackTricks AWS 红队专家) -支持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 来分享您的黑客技巧。
diff --git a/macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-library-injection/README.md b/macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-library-injection/README.md index f139fdf14..a01b232b1 100644 --- a/macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-library-injection/README.md +++ b/macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-library-injection/README.md @@ -1,4 +1,4 @@ -# macOS Library Injection +# macOS库注入
@@ -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来分享您的黑客技巧。
{% 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 :- ` +- 二进制文件是`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 :- ` -在更新的版本中,您可以在函数\*\*`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 `检查二进制文件是否具有**强化运行时**,检查\*\*`CodeDirectory`**中的标志运行时,例如:**`CodeDirectory v=20500 size=767 flags=0x10000(runtime) hashes=13+7 location=embedded`\*\* +您可以使用`codesign --display --verbose `检查二进制文件是否具有**强化运行时**,检查**`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,54 +71,56 @@ ## 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`。 -* 在二进制文件中查找**弱链接库**(稍后您将看到如何创建劫持库的示例): - - ```bash - otool -l | grep LC_LOAD_WEAK_DYLIB -A 5 cmd LC_LOAD_WEAK_DYLIB - cmdsize 56 - name /var/tmp/lib/libUtl.1.dylib (offset 24) - time stamp 2 Wed Jun 21 12:23:31 1969 - 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 | grep -E "LC_RPATH|LC_LOAD_DYLIB" -A 5` +- **缺失的弱链接库**:这意味着应用程序将尝试加载一个使用**LC\_LOAD\_WEAK\_DYLIB**配置的不存在的库。然后,**如果攻击者将dylib放在预期的位置,它将被加载**。 +- 链接是“弱”的意思是即使未找到库,应用程序也将继续运行。 +- 与此相关的**代码**位于`ImageLoaderMachO.cpp`的`ImageLoaderMachO::doGetDependentLibraries`函数中,其中`lib->required`仅在`LC_LOAD_WEAK_DYLIB`为true时为`false`。 +- 在二进制文件中查找**弱链接库**(稍后您将看到如何创建劫持库的示例): + ```bash + otool -l | grep LC_LOAD_WEAK_DYLIB -A 5 cmd LC_LOAD_WEAK_DYLIB + cmdsize 56 + name /var/tmp/lib/libUtl.1.dylib (offset 24) + time stamp 2 Wed Jun 21 12:23:31 1969 + current version 1.0.0 + compatibility version 1.0.0 + ``` +- **配置为@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 | 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 @@ -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 ``` - -然后检查标志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)
-从零开始学习AWS黑客技术,成为专家 htARTE(HackTricks AWS Red Team Expert) +从零开始学习AWS黑客技术,成为专家 htARTE (HackTricks AWS Red Team Expert)! 支持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来分享您的黑客技巧。
diff --git a/macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-library-injection/macos-dyld-process.md b/macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-library-injection/macos-dyld-process.md new file mode 100644 index 000000000..0eda41910 --- /dev/null +++ b/macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-library-injection/macos-dyld-process.md @@ -0,0 +1,322 @@ +# macOS Dyld 进程 + +
+ +从零开始学习 AWS 黑客技术,成为专家 htARTE(HackTricks AWS 红队专家) + +支持 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 来分享您的黑客技巧。 + +
+ +## 基本信息 + +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 +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 +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 %} + +在进入主函数之前,可以通过调试查看所有这些有趣的值: + +
lldb ./apple
+
+(lldb) target create "./a"
+当前可执行文件设置为'/tmp/a' (arm64)。
+(lldb) process launch -s
+[..]
+
+(lldb) mem read $sp
+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............
+
+(lldb) x/55s 0x016fdff6d8
+[...]
+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: ""
+
+ +## 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]: /usr/lib/libSystem.B.dylib +dyld[19948]: /usr/lib/system/libcache.dylib +dyld[19948]: /usr/lib/system/libcommonCrypto.dylib +dyld[19948]: /usr/lib/system/libcompiler_rt.dylib +dyld[19948]: <65612C42-C5E4-3821-B71D-DDE620FB014C> /usr/lib/system/libcopyfile.dylib +dyld[19948]: /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]: /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) + +
+ +从零开始学习AWS黑客技术,成为专家 htARTE (HackTricks AWS Red Team Expert) + +支持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来分享您的黑客技巧。 + +