macOS Apps - Ispezione, debug e Fuzzing
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.
Analisi Statica
otool & objdump & nm
otool -L /bin/ls #List dynamically linked libraries
otool -tv /bin/ps #Decompile application
objdump -m --dylibs-used /bin/ls #List dynamically linked libraries
objdump -m -h /bin/ls # Get headers information
objdump -m --syms /bin/ls # Check if the symbol table exists to get function names
objdump -m --full-contents /bin/ls # Dump every section
objdump -d /bin/ls # Dissasemble the binary
objdump --disassemble-symbols=_hello --x86-asm-syntax=intel toolsdemo #Disassemble a function using intel flavour
nm -m ./tccd # List of symbols
jtool2 & Disarm
Puoi scaricare disarm da qui.
ARCH=arm64e disarm -c -i -I --signature /path/bin # Get bin info and signature
ARCH=arm64e disarm -c -l /path/bin # Get binary sections
ARCH=arm64e disarm -c -L /path/bin # Get binary commands (dependencies included)
ARCH=arm64e disarm -c -S /path/bin # Get symbols (func names, strings...)
ARCH=arm64e disarm -c -d /path/bin # Get disasembled
jtool2 -d __DATA.__const myipc_server | grep MIG # Get MIG info
Puoi scaricare jtool2 qui o installarlo con brew.
# Install
brew install --cask jtool2
jtool2 -l /bin/ls # Get commands (headers)
jtool2 -L /bin/ls # Get libraries
jtool2 -S /bin/ls # Get symbol info
jtool2 -d /bin/ls # Dump binary
jtool2 -D /bin/ls # Decompile binary
# Get signature information
ARCH=x86_64 jtool2 --sig /System/Applications/Automator.app/Contents/MacOS/Automator
# Get MIG information
jtool2 -d __DATA.__const myipc_server | grep MIG
[!CAUTION] > jtool è deprecato a favore di disarm
Codesign / ldid
[!TIP] >
Codesignsi trova in macOS mentreldidsi trova in iOS
# Get signer
codesign -vv -d /bin/ls 2>&1 | grep -E "Authority|TeamIdentifier"
# Check if the appâs contents have been modified
codesign --verify --verbose /Applications/Safari.app
# Get entitlements from the binary
codesign -d --entitlements :- /System/Applications/Automator.app # Check the TCC perms
# Check if the signature is valid
spctl --assess --verbose /Applications/Safari.app
# Sign a binary
codesign -s <cert-name-keychain> toolsdemo
# Get signature info
ldid -h <binary>
# Get entitlements
ldid -e <binary>
# Change entilements
## /tmp/entl.xml is a XML file with the new entitlements to add
ldid -S/tmp/entl.xml <binary>
SuspiciousPackage
SuspiciousPackage è uno strumento utile per ispezionare i file .pkg (installer) e vedere cosa câè dentro prima di installarli.
Questi installer hanno script bash preinstall e postinstall che gli autori di malware di solito abusano per persist il malware.
hdiutil
Questo strumento consente di mount i file immagine disco Apple (.dmg) per ispezionarli prima di eseguire qualsiasi cosa:
hdiutil attach ~/Downloads/Firefox\ 58.0.2.dmg
SarĂ montato in /Volumes
Binarie impacchettate
- Controlla lâalta entropia
- Controlla le stringhe (se non ci sono stringhe comprensibili, è impacchettato)
- Il pacchetto UPX per MacOS genera una sezione chiamata â__XHDRâ
Analisi statica di Objective-C
Metadati
Caution
Nota che i programmi scritti in Objective-C mantengono le loro dichiarazioni di classe quando compilati in Mach-O binaries. Tali dichiarazioni di classe includono il nome e il tipo di:
- Le interfacce definite
- I metodi dellâinterfaccia
- Le variabili di istanza dellâinterfaccia
- I protocolli definiti
Nota che questi nomi potrebbero essere offuscati per rendere piĂš difficile il reverse engineering del binario.
Chiamata di funzione
Quando una funzione viene chiamata in un binario che utilizza Objective-C, il codice compilato invece di chiamare quella funzione, chiamerĂ objc_msgSend. Che chiamerĂ la funzione finale:
.png)
I parametri che questa funzione si aspetta sono:
- Il primo parametro (self) è âun puntatore che punta allâistanza della classe che deve ricevere il messaggioâ. In altre parole, è lâoggetto su cui viene invocato il metodo. Se il metodo è un metodo di classe, questo sarĂ unâistanza dellâoggetto classe (nel suo insieme), mentre per un metodo di istanza, self punterĂ a unâistanza instanziata della classe come oggetto.
- Il secondo parametro, (op), è âil selettore del metodo che gestisce il messaggioâ. In termini piĂš semplici, questo è solo il nome del metodo.
- I parametri rimanenti sono eventuali valori richiesti dal metodo (op).
Vedi come ottenere queste informazioni facilmente con lldb in ARM64 in questa pagina:
x64:
| Argomento | Registro | (per) objc_msgSend |
|---|---|---|
| 1° argomento | rdi | self: oggetto su cui viene invocato il metodo |
| 2° argomento | rsi | op: nome del metodo |
| 3° argomento | rdx | 1° argomento per il metodo |
| 4° argomento | rcx | 2° argomento per il metodo |
| 5° argomento | r8 | 3° argomento per il metodo |
| 6° argomento | r9 | 4° argomento per il metodo |
| 7°+ argomento |
rsp+ | 5°+ argomento per il metodo |
Dump dei metadati di ObjectiveC
Dynadump
Dynadump è uno strumento per il class-dump di binari Objective-C. Il github specifica dylibs ma funziona anche con eseguibili.
./dynadump dump /path/to/bin
Al momento della scrittura, questo è attualmente quello che funziona meglio.
Strumenti regolari
nm --dyldinfo-only /path/to/bin
otool -ov /path/to/bin
objdump --macho --objc-meta-data /path/to/bin
class-dump
class-dump è lo strumento originale per generare dichiarazioni per le classi, categorie e protocolli nel codice formattato in ObjectiveC.
Ă vecchio e non mantenuto, quindi probabilmente non funzionerĂ correttamente.
ICDump
iCDump è un dump di classi Objective-C moderno e multipiattaforma. Rispetto agli strumenti esistenti, iCDump può funzionare indipendentemente dallâecosistema Apple e espone binding Python.
import icdump
metadata = icdump.objc.parse("/path/to/bin")
print(metadata.to_decl())
Analisi statica di Swift
Con i binari Swift, poichĂŠ câè compatibilitĂ con Objective-C, a volte puoi estrarre dichiarazioni utilizzando class-dump ma non sempre.
Con i comandi jtool -l o otool -l è possibile trovare diverse sezioni che iniziano con il prefisso __swift5:
jtool2 -l /Applications/Stocks.app/Contents/MacOS/Stocks
LC 00: LC_SEGMENT_64 Mem: 0x000000000-0x100000000 __PAGEZERO
LC 01: LC_SEGMENT_64 Mem: 0x100000000-0x100028000 __TEXT
[...]
Mem: 0x100026630-0x100026d54 __TEXT.__swift5_typeref
Mem: 0x100026d60-0x100027061 __TEXT.__swift5_reflstr
Mem: 0x100027064-0x1000274cc __TEXT.__swift5_fieldmd
Mem: 0x1000274cc-0x100027608 __TEXT.__swift5_capture
[...]
Puoi trovare ulteriori informazioni su le informazioni memorizzate in questa sezione in questo post del blog.
Inoltre, i binari Swift potrebbero avere simboli (ad esempio, le librerie devono memorizzare simboli affinchĂŠ le loro funzioni possano essere chiamate). I simboli di solito contengono informazioni sul nome della funzione e sugli attributi in un modo poco chiaro, quindi sono molto utili e ci sono âdemanglersâ che possono ottenere il nome originale:
# Ghidra plugin
https://github.com/ghidraninja/ghidra_scripts/blob/master/swift_demangler.py
# Swift cli
swift demangle
Analisi Dinamica
Warning
Nota che per eseguire il debug dei binari, SIP deve essere disabilitato (
csrutil disableocsrutil enable --without debug) oppure copiare i binari in una cartella temporanea e rimuovere la firma concodesign --remove-signature <binary-path>o consentire il debug del binario (puoi usare questo script)
Warning
Nota che per strumentare i binari di sistema, (come
cloudconfigurationd) su macOS, SIP deve essere disabilitato (rimuovere solo la firma non funzionerĂ ).
API
macOS espone alcune API interessanti che forniscono informazioni sui processi:
proc_info: Questo è il principale che fornisce molte informazioni su ciascun processo. Devi essere root per ottenere informazioni su altri processi, ma non hai bisogno di diritti speciali o porte mach.libsysmon.dylib: Consente di ottenere informazioni sui processi tramite funzioni esposte da XPC, tuttavia, è necessario avere il dirittocom.apple.sysmond.client.
Stackshot e microstackshots
Stackshotting è una tecnica utilizzata per catturare lo stato dei processi, inclusi gli stack di chiamate di tutti i thread in esecuzione. Questo è particolarmente utile per il debug, lâanalisi delle prestazioni e la comprensione del comportamento del sistema in un momento specifico. Su iOS e macOS, lo stackshotting può essere eseguito utilizzando diversi strumenti e metodi come gli strumenti sample e spindump.
Sysdiagnose
Questo strumento (/usr/bini/ysdiagnose) raccoglie fondamentalmente molte informazioni dal tuo computer eseguendo decine di comandi diversi come ps, zprintâŚ
Deve essere eseguito come root e il demone /usr/libexec/sysdiagnosed ha diritti molto interessanti come com.apple.system-task-ports e get-task-allow.
Il suo plist si trova in /System/Library/LaunchDaemons/com.apple.sysdiagnose.plist che dichiara 3 MachServices:
com.apple.sysdiagnose.CacheDelete: Elimina archivi vecchi in /var/rmpcom.apple.sysdiagnose.kernel.ipc: Porta speciale 23 (kernel)com.apple.sysdiagnose.service.xpc: Interfaccia in modalitĂ utente tramite la classe Obj-CLibsysdiagnose. Tre argomenti in un dizionario possono essere passati (compress,display,run)
Log Unificati
MacOS genera molti log che possono essere molto utili quando si esegue unâapplicazione cercando di capire cosa sta facendo.
Inoltre, ci sono alcuni log che conterranno il tag <private> per nascondere alcune informazioni identificabili dellâutente o del computer. Tuttavia, è possibile installare un certificato per rivelare queste informazioni. Segui le spiegazioni da qui.
Hopper
Pannello sinistro
Nel pannello sinistro di hopper è possibile vedere i simboli (Labels) del binario, lâelenco delle procedure e delle funzioni (Proc) e le stringhe (Str). Queste non sono tutte le stringhe, ma quelle definite in diverse parti del file Mac-O (come cstring o objc_methname).
Pannello centrale
Nel pannello centrale puoi vedere il codice disassemblato. E puoi vederlo in un disassemblaggio grezzo, come grafico, come decompilato e come binario cliccando sullâicona rispettiva:
.png)
Facendo clic destro su un oggetto di codice puoi vedere riferimenti a/da quellâoggetto o persino cambiare il suo nome (questo non funziona nel pseudocodice decompilato):
.png)
Inoltre, nella parte centrale in basso puoi scrivere comandi python.
Pannello destro
Nel pannello destro puoi vedere informazioni interessanti come la cronologia di navigazione (cosĂŹ sai come sei arrivato alla situazione attuale), il grafo delle chiamate dove puoi vedere tutte le funzioni che chiamano questa funzione e tutte le funzioni che questa funzione chiama, e informazioni sulle variabili locali.
dtrace
Consente agli utenti di accedere alle applicazioni a un livello molto basso e fornisce un modo per gli utenti di tracciare programmi e persino cambiare il loro flusso di esecuzione. Dtrace utilizza probes che sono posizionati in tutto il kernel e si trovano in posizioni come lâinizio e la fine delle chiamate di sistema.
DTrace utilizza la funzione dtrace_probe_create per creare una sonda per ciascuna chiamata di sistema. Queste sonde possono essere attivate nel punto di ingresso e uscita di ciascuna chiamata di sistema. Lâinterazione con DTrace avviene tramite /dev/dtrace che è disponibile solo per lâutente root.
Tip
Per abilitare Dtrace senza disabilitare completamente la protezione SIP puoi eseguire in modalitĂ di recupero:
csrutil enable --without dtracePuoi anche
dtraceodtrussbinari che hai compilato.
Le sonde disponibili di dtrace possono essere ottenute con:
dtrace -l | head
ID PROVIDER MODULE FUNCTION NAME
1 dtrace BEGIN
2 dtrace END
3 dtrace ERROR
43 profile profile-97
44 profile profile-199
Il nome della sonda è composto da quattro parti: il fornitore, il modulo, la funzione e il nome (fbt:mach_kernel:ptrace:entry). Se non specifichi alcune parti del nome, Dtrace applicherà quella parte come un carattere jolly.
Per configurare DTrace per attivare le sonde e specificare quali azioni eseguire quando si attivano, dovremo utilizzare il linguaggio D.
Una spiegazione piĂš dettagliata e ulteriori esempi possono essere trovati in https://illumos.org/books/dtrace/chp-intro.html
Esempi
Esegui man -k dtrace per elencare gli script DTrace disponibili. Esempio: sudo dtruss -n binary
- In linea
#Count the number of syscalls of each running process
sudo dtrace -n 'syscall:::entry {@[execname] = count()}'
- script
syscall:::entry
/pid == $1/
{
}
#Log every syscall of a PID
sudo dtrace -s script.d 1234
syscall::open:entry
{
printf("%s(%s)", probefunc, copyinstr(arg0));
}
syscall::close:entry
{
printf("%s(%d)\n", probefunc, arg0);
}
#Log files opened and closed by a process
sudo dtrace -s b.d -c "cat /etc/hosts"
syscall:::entry
{
;
}
syscall:::return
{
printf("=%d\n", arg1);
}
#Log sys calls with values
sudo dtrace -s syscalls_info.d -c "cat /etc/hosts"
dtruss
dtruss -c ls #Get syscalls of ls
dtruss -c -p 1000 #get syscalls of PID 1000
kdebug
Ă una struttura di tracciamento del kernel. I codici documentati possono essere trovati in /usr/share/misc/trace.codes.
Strumenti come latency, sc_usage, fs_usage e trace lo utilizzano internamente.
Per interfacciarsi con kdebug, si utilizza sysctl sul namespace kern.kdebug e i MIB da utilizzare possono essere trovati in sys/sysctl.h, con le funzioni implementate in bsd/kern/kdebug.c.
Per interagire con kdebug con un client personalizzato, questi sono solitamente i passaggi:
- Rimuovere le impostazioni esistenti con KERN_KDSETREMOVE
- Impostare il tracciamento con KERN_KDSETBUF e KERN_KDSETUP
- Usare KERN_KDGETBUF per ottenere il numero di voci del buffer
- Ottenere il proprio client dal tracciamento con KERN_KDPINDEX
- Abilitare il tracciamento con KERN_KDENABLE
- Leggere il buffer chiamando KERN_KDREADTR
- Per abbinare ogni thread al suo processo, chiamare KERN_KDTHRMAP.
Per ottenere queste informazioni è possibile utilizzare lo strumento Apple trace o lo strumento personalizzato kDebugView (kdv).
Nota che Kdebug è disponibile solo per 1 cliente alla volta. Quindi solo uno strumento alimentato da k-debug può essere eseguito alla stessa volta.
ktrace
Le API ktrace_* provengono da libktrace.dylib, che avvolgono quelle di Kdebug. Quindi, un client può semplicemente chiamare ktrace_session_create e ktrace_events_[single/class] per impostare callback su codici specifici e poi avviarlo con ktrace_start.
Puoi utilizzare questo anche con SIP attivato
Puoi utilizzare come client lâutilitĂ ktrace:
ktrace trace -s -S -t c -c ls | grep "ls("
Or tailspin.
kperf
Questo è usato per fare un profiling a livello di kernel ed è costruito utilizzando le chiamate Kdebug.
Fondamentalmente, la variabile globale kernel_debug_active viene controllata e se è impostata chiama kperf_kdebug_handler con il codice Kdebug e lâindirizzo del frame del kernel chiamante. Se il codice Kdebug corrisponde a uno selezionato, ottiene le âazioniâ configurate come bitmap (controlla osfmk/kperf/action.h per le opzioni).
Kperf ha anche una tabella MIB sysctl: (come root) sysctl kperf. Questi codici possono essere trovati in osfmk/kperf/kperfbsd.c.
Inoltre, un sottoinsieme della funzionalitĂ di Kperf risiede in kpc, che fornisce informazioni sui contatori di prestazioni della macchina.
ProcessMonitor
ProcessMonitor è uno strumento molto utile per controllare le azioni relative ai processi che un processo sta eseguendo (ad esempio, monitorare quali nuovi processi un processo sta creando).
SpriteTree
SpriteTree è uno strumento che stampa le relazioni tra i processi.
Devi monitorare il tuo mac con un comando come sudo eslogger fork exec rename create > cap.json (il terminale che lancia questo richiede FDA). E poi puoi caricare il json in questo strumento per visualizzare tutte le relazioni:
.png)
FileMonitor
FileMonitor consente di monitorare eventi di file (come creazione, modifiche e cancellazioni) fornendo informazioni dettagliate su tali eventi.
Crescendo
Crescendo è uno strumento GUI con lâaspetto e la sensazione che gli utenti Windows potrebbero conoscere da Procmon di Microsoft Sysinternal. Questo strumento consente di registrare vari tipi di eventi da avviare e fermare, consente il filtraggio di questi eventi per categorie come file, processo, rete, ecc., e fornisce la funzionalitĂ di salvare gli eventi registrati in formato json.
Apple Instruments
Apple Instruments fanno parte degli strumenti per sviluppatori di Xcode â utilizzati per monitorare le prestazioni delle applicazioni, identificare perdite di memoria e tracciare lâattivitĂ del filesystem.
.png)
fs_usage
Consente di seguire le azioni eseguite dai processi:
fs_usage -w -f filesys ls #This tracks filesystem actions of proccess names containing ls
fs_usage -w -f network curl #This tracks network actions
TaskExplorer
Taskexplorer è utile per vedere le librerie utilizzate da un binario, i file che sta usando e le connessioni di rete.
Controlla anche i processi binari contro virustotal e mostra informazioni sul binario.
PT_DENY_ATTACH
In questo post del blog puoi trovare un esempio su come debuggare un demone in esecuzione che utilizzava PT_DENY_ATTACH per prevenire il debugging anche se SIP era disabilitato.
lldb
lldb è lo strumento de facto per il debugging di binari macOS.
lldb ./malware.bin
lldb -p 1122
lldb -n malware.bin
lldb -n malware.bin --waitfor
Puoi impostare il sapore intel quando usi lldb creando un file chiamato .lldbinit nella tua cartella home con la seguente riga:
settings set target.x86-disassembly-flavor intel
Warning
Allâinterno di lldb, esegui il dump di un processo con
process save-core
| (lldb) Comando | Descrizione | ||||||||||||||||||||||
| run (r) | Inizia l'esecuzione, che continuerĂ senza interruzioni fino a quando non viene colpito un breakpoint o il processo termina. | ||||||||||||||||||||||
| process launch --stop-at-entry | Inizia l'esecuzione fermandosi al punto di ingresso | ||||||||||||||||||||||
| continue (c) | Continua l'esecuzione del processo in debug. | ||||||||||||||||||||||
| nexti (n / ni) | Esegui la prossima istruzione. Questo comando salterĂ le chiamate di funzione. | ||||||||||||||||||||||
| stepi (s / si) | Esegui la prossima istruzione. A differenza del comando nexti, questo comando entrerĂ nelle chiamate di funzione. | ||||||||||||||||||||||
| finish (f) | Esegui il resto delle istruzioni nella funzione corrente (âframeâ) e ritorna e ferma. | ||||||||||||||||||||||
| control + c | Metti in pausa l'esecuzione. Se il processo è stato eseguito (r) o continuato (c), questo causerà l'arresto del processo ...dove si trova attualmente in esecuzione. | ||||||||||||||||||||||
| breakpoint (b) |
breakpoint delete help breakpoint #Ottieni aiuto sul comando breakpoint help memory write #Ottieni aiuto per scrivere nella memoria reg read reg read $rax reg read $rax --format <format> reg write $rip 0x100035cc0 Questo stamperĂ l'oggetto referenziato dal parametro po $raw Nota che la maggior parte delle API o dei metodi Objective-C di Apple restituiscono oggetti, e quindi dovrebbero essere visualizzati tramite il comando âprint objectâ (po). Se po non produce un output significativo usa dis #Disassembla la funzione corrente dis -n dis -n Tip Quando chiami la funzione I core dumps vengono creati se: In questi casi il core dump viene generato secondo ReportCrash analizza i processi in crash e salva un rapporto di crash su disco. Un rapporto di crash contiene informazioni che possono aiutare uno sviluppatore a diagnosticare la causa di un crash. Se sei preoccupato che i rapporti di crash vengano inviati ad Apple, puoi disabilitarli. Se no, i rapporti di crash possono essere utili per capire come è andato in crash un server. Durante il fuzzing su MacOS è importante non permettere al Mac di andare in sonno: Se stai fuzzando tramite una connessione SSH, è importante assicurarsi che la sessione non si disconnetta. Quindi modifica il file sshd_config con: Controlla la seguente pagina per scoprire come puoi trovare quale app è responsabile della gestione dello schema o protocollo specificato: macOS File Extension & URL scheme app handlers Questo è interessante per trovare i processi che gestiscono i dati di rete: Oppure usa Funziona per strumenti CLI Funziona âsemplicementeâ con strumenti GUI di macOS. Nota che alcune app di macOS hanno requisiti specifici come nomi di file unici, lâestensione corretta, devono leggere i file dalla sandbox ( Alcuni esempi: Tip Impara e pratica il hacking AWS: |
HackTricks


