macOS xpc_connection_get_audit_token Attack
Per ulteriori informazioni consulta il post originale: https://sector7.computest.nl/post/2023-10-xpc-audit-token-spoofing/. Questo è un riassunto:
Informazioni di base sui messaggi Mach
Se non sai cosa sono i messaggi Mach, inizia controllando questa pagina:
pagemacOS IPC - Inter Process CommunicationPer il momento ricorda che (definizione da qui): I messaggi Mach vengono inviati su una porta mach, che è un canale di comunicazione singolo ricevitore, multiplo mittente integrato nel kernel mach. Più processi possono inviare messaggi a una porta mach, ma in qualsiasi momento solo un singolo processo può leggerne. Proprio come i descrittori di file e i socket, le porte mach sono allocate e gestite dal kernel e i processi vedono solo un numero intero, che possono utilizzare per indicare al kernel quale delle loro porte mach desiderano utilizzare.
Connessione XPC
Se non sai come viene stabilita una connessione XPC, controlla:
pagemacOS XPCRiassunto della vulnerabilità
Ciò che è interessante sapere è che l'astrazione di XPC è una connessione uno a uno, ma è basata su una tecnologia che può avere più mittenti, quindi:
Le porte Mach sono un singolo ricevitore, multiplo mittente.
Il token di audit di una connessione XPC è il token di audit copiato dal messaggio più recentemente ricevuto.
Ottenere il token di audit di una connessione XPC è fondamentale per molti controlli di sicurezza.
Anche se la situazione precedente sembra promettente, ci sono alcuni scenari in cui ciò non causerà problemi (da qui):
I token di audit vengono spesso utilizzati per un controllo di autorizzazione per decidere se accettare una connessione. Poiché ciò avviene utilizzando un messaggio alla porta del servizio, non è ancora stata stabilita alcuna connessione. Altri messaggi su questa porta verranno gestiti come richieste di connessione aggiuntive. Quindi eventuali controlli prima di accettare una connessione non sono vulnerabili (ciò significa anche che all'interno di
-listener:shouldAcceptNewConnection:
il token di audit è sicuro). Stiamo quindi cercando connessioni XPC che verifichino azioni specifiche.Gli handler degli eventi XPC vengono gestiti in modo sincrono. Ciò significa che l'handler dell'evento per un messaggio deve essere completato prima di chiamarlo per il successivo, anche su code di invio concorrenti. Quindi all'interno di un gestore di eventi XPC il token di audit non può essere sovrascritto da altri messaggi normali (non di risposta!).
Due diversi metodi con cui ciò potrebbe essere sfruttato:
Variante1:
L'exploit si connette al servizio A e al servizio B
Il servizio B può chiamare una funzionalità privilegiata in servizio A che l'utente non può
Il servizio A chiama
xpc_connection_get_audit_token
mentre non è all'interno dell'handler di evento per una connessione in undispatch_async
.Quindi un messaggio diverso potrebbe sovrascrivere il Token di Audit perché viene inviato in modo asincrono al di fuori dell'handler di evento.
L'exploit passa a servizio B il diritto di invio a servizio A.
Quindi svc B invierà effettivamente i messaggi a servizio A.
L'exploit cerca di chiamare l'azione privilegiata. In un RC svc A controlla l'autorizzazione di questa azione mentre svc B sovrascrive il Token di Audit (dando all'exploit l'accesso per chiamare l'azione privilegiata).
Variante 2:
Il servizio B può chiamare una funzionalità privilegiata in servizio A che l'utente non può
L'exploit si connette con servizio A che invia all'exploit un messaggio che si aspetta una risposta in una specifica porta di risposta.
L'exploit invia al servizio B un messaggio passando quella porta di risposta.
Quando il servizio B risponde, invia il messaggio a servizio A, mentre l'exploit invia un messaggio diverso a servizio A cercando di raggiungere una funzionalità privilegiata e aspettandosi che la risposta da servizio B sovrascriva il Token di Audit nel momento perfetto (Condizione di Gara).
Variante 1: chiamare xpc_connection_get_audit_token al di fuori di un handler di evento
Scenario:
Due servizi mach
A
eB
a cui possiamo entrambi connetterci (in base al profilo sandbox e ai controlli di autorizzazione prima di accettare la connessione).A deve avere un controllo di autorizzazione per un'azione specifica che
B
può superare (ma la nostra app non può).Ad esempio, se B ha alcuni privilegi o viene eseguito come root, potrebbe consentirgli di chiedere ad A di eseguire un'azione privilegiata.
Per questo controllo di autorizzazione,
A
ottiene il token di audit in modo asincrono, ad esempio chiamandoxpc_connection_get_audit_token
dadispatch_async
.
In questo caso un attaccante potrebbe innescare una Condizione di Gara creando un exploit che chiede ad A di eseguire un'azione più volte mentre B invia messaggi ad A
. Quando la CG è riuscita, il token di audit di B verrà copiato in memoria mentre la richiesta del nostro exploit viene gestita da A, dandogli accesso all'azione privilegiata che solo B poteva richiedere.
Ciò è accaduto con A
come smd
e B
come diagnosticd
. La funzione SMJobBless
da smb può essere utilizzata per installare un nuovo strumento helper privilegiato (come root). Se un processo in esecuzione come root contatta smd, non verranno eseguiti altri controlli.
Pertanto, il servizio B è diagnosticd
perché viene eseguito come root e può essere utilizzato per monitorare un processo, quindi una volta avviato il monitoraggio, invierà più messaggi al secondo.
Per eseguire l'attacco:
Inizia una connessione al servizio chiamato
smd
utilizzando il protocollo XPC standard.Forma una secondaria connessione a
diagnosticd
. Contrariamente alla procedura normale, anziché creare e inviare due nuove porte mach, il diritto di invio della porta client viene sostituito con una duplicata del diritto di invio associato alla connessionesmd
.Di conseguenza, i messaggi XPC possono essere inviati a
diagnosticd
, ma le risposte dadiagnosticd
vengono dirottate susmd
. Persmd
, sembra che i messaggi sia dall'utente che dadiagnosticd
provengano dalla stessa connessione.
Il passo successivo consiste nell'istruire
diagnosticd
ad avviare il monitoraggio di un processo scelto (potenzialmente quello dell'utente). Contestualmente, viene inviata una serie di messaggi di routine 1004 asmd
. L'intento qui è quello di installare uno strumento con privilegi elevati.Questa azione scatena una condizione di gara all'interno della funzione
handle_bless
. Il tempismo è critico: la chiamata alla funzionexpc_connection_get_pid
deve restituire il PID del processo dell'utente (poiché lo strumento privilegiato risiede nel bundle dell'applicazione dell'utente). Tuttavia, la funzionexpc_connection_get_audit_token
, specificamente all'interno della subroutineconnection_is_authorized
, deve fare riferimento al token di audit appartenente adiagnosticd
.
Variante 2: inoltro delle risposte
In un ambiente XPC (Comunicazione tra Processi), anche se gli handler degli eventi non vengono eseguiti contemporaneamente, la gestione dei messaggi di risposta ha un comportamento unico. In particolare, esistono due metodi distinti per l'invio di messaggi che si aspettano una risposta:
xpc_connection_send_message_with_reply
: Qui, il messaggio XPC viene ricevuto e elaborato su una coda designata.xpc_connection_send_message_with_reply_sync
: Al contrario, in questo metodo, il messaggio XPC viene ricevuto e elaborato sulla coda di dispacci corrente.
Questa distinzione è cruciale perché permette la possibilità di analizzare i pacchetti di risposta in modo concorrente con l'esecuzione di un gestore di eventi XPC. In particolare, mentre _xpc_connection_set_creds
implementa un blocco per proteggere dalla sovrascrittura parziale del token di audit, non estende questa protezione all'intero oggetto di connessione. Di conseguenza, si crea una vulnerabilità in cui il token di audit può essere sostituito durante l'intervallo tra l'analisi di un pacchetto e l'esecuzione del suo gestore di eventi.
Per sfruttare questa vulnerabilità, è necessaria la seguente configurazione:
Due servizi mach, denominati
A
eB
, entrambi in grado di stabilire una connessione.Il servizio
A
dovrebbe includere un controllo di autorizzazione per un'azione specifica che soloB
può eseguire (l'applicazione dell'utente non può).Il servizio
A
dovrebbe inviare un messaggio che prevede una risposta.L'utente può inviare un messaggio a
B
a cui risponderà.
Il processo di sfruttamento comporta i seguenti passaggi:
Attendere che il servizio
A
invii un messaggio che si aspetta una risposta.Invece di rispondere direttamente a
A
, la porta di risposta viene dirottata e utilizzata per inviare un messaggio al servizioB
.Successivamente, viene inviato un messaggio che coinvolge l'azione vietata, con l'aspettativa che venga elaborato in modo concorrente con la risposta da
B
.
Di seguito è riportata una rappresentazione visiva dello scenario di attacco descritto:
![https://sector7.computest.nl/post/2023-10-xpc-audit-token-spoofing/variant2.png](../../../../../../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1).png)
Problemi di Scoperta
Difficoltà nel Localizzare le Istanze: La ricerca delle istanze di utilizzo di
xpc_connection_get_audit_token
è stata impegnativa, sia staticamente che dinamicamente.Metodologia: Frida è stata utilizzata per agganciare la funzione
xpc_connection_get_audit_token
, filtrando le chiamate non originate dagli handler degli eventi. Tuttavia, questo metodo era limitato al processo agganciato e richiedeva un utilizzo attivo.Strumenti di Analisi: Strumenti come IDA/Ghidra sono stati utilizzati per esaminare i servizi mach raggiungibili, ma il processo era lungo e complicato dalle chiamate che coinvolgevano la cache condivisa dyld.
Limitazioni degli Script: I tentativi di scrivere uno script per l'analisi delle chiamate a
xpc_connection_get_audit_token
dai blocchidispatch_async
sono stati ostacolati dalle complessità nel parsing dei blocchi e dalle interazioni con la cache condivisa dyld.
La correzione
Segnalazione dei Problemi: È stata inviata una segnalazione ad Apple dettagliando i problemi generali e specifici trovati all'interno di
smd
.Risposta di Apple: Apple ha affrontato il problema in
smd
sostituendoxpc_connection_get_audit_token
conxpc_dictionary_get_audit_token
.Natura della Correzione: La funzione
xpc_dictionary_get_audit_token
è considerata sicura poiché recupera il token di audit direttamente dal messaggio mach legato al messaggio XPC ricevuto. Tuttavia, non fa parte dell'API pubblica, simile axpc_connection_get_audit_token
.Assenza di una Correzione Più Ampia: Non è chiaro perché Apple non abbia implementato una correzione più completa, come scartare i messaggi che non si allineano al token di audit salvato della connessione. La possibilità di cambiamenti legittimi del token di audit in determinati scenari (ad esempio, l'uso di
setuid
) potrebbe essere un fattore.Stato Attuale: Il problema persiste in iOS 17 e macOS 14, rappresentando una sfida per coloro che cercano di identificarlo e comprenderlo.
Last updated