macOS - AMFI - AppleMobileFileIntegrity
AppleMobileFileIntegrity.kext e amfid
Si concentra sull'applicazione dell'integrità del codice in esecuzione sul sistema fornendo la logica dietro la verifica della firma del codice di XNU. È anche in grado di controllare i diritti e gestire altre operazioni sensibili come consentire il debug o ottenere porte di task.
Inoltre, per alcune operazioni, il kext preferisce contattare il demone in user space /usr/libexec/amfid
. Questa relazione di fiducia è stata abusata in diversi jailbreak.
AMFI utilizza politiche MACF e registra i suoi hook nel momento in cui viene avviato. Inoltre, impedire il suo caricamento o scaricamento potrebbe innescare un kernel panic. Tuttavia, ci sono alcuni argomenti di avvio che consentono di indebolire AMFI:
amfi_unrestricted_task_for_pid
: Consente a task_for_pid di essere consentito senza diritti richiestiamfi_allow_any_signature
: Consente qualsiasi firma del codicecs_enforcement_disable
: Argomento a livello di sistema utilizzato per disabilitare l'applicazione della firma del codiceamfi_prevent_old_entitled_platform_binaries
: Annulla i binari di piattaforma con dirittiamfi_get_out_of_my_way
: Disabilita completamente amfi
Queste sono alcune delle politiche MACF che registra:
cred_check_label_update_execve:
L'aggiornamento dell'etichetta verrà eseguito e restituirà 1cred_label_associate
: Aggiorna lo slot dell'etichetta mac di AMFI con l'etichettacred_label_destroy
: Rimuove lo slot dell'etichetta mac di AMFIcred_label_init
: Sposta 0 nello slot dell'etichetta mac di AMFIcred_label_update_execve
: Controlla i diritti del processo per vedere se dovrebbe essere consentito modificare le etichette.file_check_mmap
: Controlla se mmap sta acquisendo memoria e impostandola come eseguibile. In tal caso, verifica se è necessaria la convalida della libreria e, in tal caso, chiama la funzione di convalida della libreria.file_check_library_validation
: Chiama la funzione di convalida della libreria che controlla, tra le altre cose, se un binario di piattaforma sta caricando un altro binario di piattaforma o se il processo e il nuovo file caricato hanno lo stesso TeamID. Alcuni diritti consentiranno anche di caricare qualsiasi libreria.policy_initbsd
: Configura le chiavi NVRAM fidatepolicy_syscall
: Controlla le politiche DYLD come se il binario ha segmenti non limitati, se dovrebbe consentire le variabili d'ambiente... questo viene chiamato anche quando un processo viene avviato tramiteamfi_check_dyld_policy_self()
.proc_check_inherit_ipc_ports
: Controlla se quando un processo esegue un nuovo binario altri processi con diritti SEND sulla porta del task del processo dovrebbero mantenerli o meno. I binari di piattaforma sono consentiti, il dirittoget-task-allow
lo consente, i dirittitask_for_pid-allow
sono consentiti e i binari con lo stesso TeamID.proc_check_expose_task
: applica i dirittiamfi_exc_action_check_exception_send
: Un messaggio di eccezione viene inviato al debuggeramfi_exc_action_label_associate & amfi_exc_action_label_copy/populate & amfi_exc_action_label_destroy & amfi_exc_action_label_init & amfi_exc_action_label_update
: Ciclo di vita dell'etichetta durante la gestione delle eccezioni (debugging)proc_check_get_task
: Controlla i diritti comeget-task-allow
che consente ad altri processi di ottenere la porta dei task etask_for_pid-allow
, che consente al processo di ottenere le porte dei task di altri processi. Se nessuno di questi, chiamaamfid permitunrestricteddebugging
per controllare se è consentito.proc_check_mprotect
: Negato semprotect
viene chiamato con il flagVM_PROT_TRUSTED
che indica che la regione deve essere trattata come se avesse una firma del codice valida.vnode_check_exec
: Viene chiamato quando i file eseguibili vengono caricati in memoria e impostacs_hard | cs_kill
che ucciderà il processo se una delle pagine diventa non validavnode_check_getextattr
: MacOS: Controllacom.apple.root.installed
eisVnodeQuarantined()
vnode_check_setextattr
: Come get + com.apple.private.allow-bless e diritto equivalente di internal-installervnode_check_signature
: Codice che chiama XNU per controllare la firma del codice utilizzando diritti, cache di fiducia eamfid
proc_check_run_cs_invalid
: Intercetta le chiamateptrace()
(PT_ATTACH
ePT_TRACE_ME
). Controlla per eventuali dirittiget-task-allow
,run-invalid-allow
erun-unsigned-code
e se nessuno, verifica se il debug è consentito.proc_check_map_anon
: Se mmap viene chiamato con il flagMAP_JIT
, AMFI controllerà il dirittodynamic-codesigning
.
AMFI.kext
espone anche un'API per altre estensioni del kernel, ed è possibile trovare le sue dipendenze con:
amfid
Questo è il demone in modalità utente che AMFI.kext
utilizzerà per controllare le firme del codice in modalità utente.
Per consentire a AMFI.kext
di comunicare con il demone, utilizza messaggi mach attraverso la porta HOST_AMFID_PORT
, che è la porta speciale 18
.
Si noti che in macOS non è più possibile per i processi root di dirottare porte speciali poiché sono protette da SIP
e solo launchd può accedervi. In iOS viene verificato che il processo che invia la risposta abbia il CDHash hardcoded di amfid
.
È possibile vedere quando amfid
viene richiesto di controllare un binario e la sua risposta eseguendo il debug e impostando un breakpoint in mach_msg
.
Una volta ricevuto un messaggio tramite la porta speciale, MIG viene utilizzato per inviare ogni funzione alla funzione che sta chiamando. Le funzioni principali sono state analizzate e spiegate all'interno del libro.
Provisioning Profiles
Un provisioning profile può essere utilizzato per firmare il codice. Ci sono profili Developer che possono essere utilizzati per firmare il codice e testarlo, e profili Enterprise che possono essere utilizzati su tutti i dispositivi.
Dopo che un'app è stata inviata all'Apple Store, se approvata, viene firmata da Apple e il provisioning profile non è più necessario.
Un profilo di solito utilizza l'estensione .mobileprovision
o .provisionprofile
e può essere estratto con:
Sebbene a volte siano chiamati certificati, questi profili di provisioning hanno più di un certificato:
AppIDName: L'Identificatore dell'Applicazione
AppleInternalProfile: Designa questo come un profilo Interno Apple
ApplicationIdentifierPrefix: Preceduto da AppIDName (stesso di TeamIdentifier)
CreationDate: Data nel formato
YYYY-MM-DDTHH:mm:ssZ
DeveloperCertificates: Un array di (di solito uno) certificato(i), codificato come dati Base64
Entitlements: I diritti consentiti con i diritti per questo profilo
ExpirationDate: Data di scadenza nel formato
YYYY-MM-DDTHH:mm:ssZ
Name: Il Nome dell'Applicazione, lo stesso di AppIDName
ProvisionedDevices: Un array (per certificati di sviluppatore) di UDID per cui questo profilo è valido
ProvisionsAllDevices: Un booleano (true per certificati aziendali)
TeamIdentifier: Un array di (di solito uno) stringhe alfanumeriche utilizzate per identificare lo sviluppatore per scopi di interazione tra app
TeamName: Un nome leggibile dall'uomo utilizzato per identificare lo sviluppatore
TimeToLive: Validità (in giorni) del certificato
UUID: Un Identificatore Universale Unico per questo profilo
Version: Attualmente impostato su 1
Nota che l'entry degli entitlements conterrà un insieme ristretto di diritti e il profilo di provisioning sarà in grado di fornire solo quegli specifici diritti per prevenire la concessione di diritti privati ad Apple.
Nota che i profili si trovano solitamente in /var/MobileDeviceProvisioningProfiles
ed è possibile controllarli con security cms -D -i /path/to/profile
libmis.dyld
Questa è la libreria esterna che amfid
chiama per chiedere se dovrebbe consentire qualcosa o meno. Questo è stato storicamente abusato nel jailbreak eseguendo una versione backdoored di essa che consentirebbe tutto.
In macOS questo si trova all'interno di MobileDevice.framework
.
Cache di Fiducia AMFI
iOS AMFI mantiene un elenco di hash noti che sono firmati ad-hoc, chiamato Trust Cache e trovato nella sezione __TEXT.__const
del kext. Nota che in operazioni molto specifiche e sensibili è possibile estendere questa Trust Cache con un file esterno.
Riferimenti
Last updated