Nell'ultimo post sul blog di Project Zero, il team ha scoperto un modo per aggirare la protezione del kernel in tempo reale di Samsung, chiamato Knox Hypervisor.
Il team Project Zero di Google ha verificato una serie di exploit che consentono di attaccare i telefoni Samsung che eseguono la suite di sicurezza Samsung Knox presumibilmente sicura. Il blog rileva che tutte le vulnerabilità sono state passate a Samsung che ha effettivamente rilasciato le correzioni in un aggiornamento software di gennaio.
Sfondo
Come parte della suite di software di sicurezza Samsung Knox introdotta da Samsung, c'è un pezzo di software che si trova tra le applicazioni Android e il kernel chiamato a Hypervisor. Questo può essere utilizzato come livello aggiuntivo per proteggere ulteriormente i dispositivi Android. L'Hypervisor Samsung Knox si chiama "Protezione del kernel in tempo reale" o RKP in breve, come farò riferimento nel resto di questo articolo.
Il kernel si trova sotto RKP nello stack del software Android e le applicazioni eseguite sul dispositivo si trovano in alto. L'idea alla base di RKP è quella di fornire un ulteriore livello di sicurezza per il dispositivo poiché tutte le richieste (memoria e altre risorse) effettuate da le applicazioni al kernel devono prima passare attraverso Knox, che tenta di rilevare se un'applicazione sta facendo qualcosa non dovrebbe. RKP fornisce inoltre sicurezza attraverso l'oscurità con un livello aggiuntivo per nascondere le informazioni sensibili che un'applicazione potrebbe utilizzare per compromettere il dispositivo.
Il post del blog approfondisce il funzionamento della memoria Android, dell'RKP e dei sistemi operativi in generale, quindi l'ho condensato e semplificato per fornire una rapida panoramica di ciò che è stato scoperto. Ti incoraggio però a leggere l'articolo completo se hai tempo, perché è molto illuminante.
Sfruttamento n. 1:
KASLR o La randomizzazione del layout dello spazio dell'indirizzo del kernel è il processo di modifica della posizione del codice del kernel in memoria in modo casuale all'avvio. Ogni volta che il dispositivo viene avviato, il kernel viene caricato in uno spazio di indirizzi diverso (area in memoria). L'idea è di rendere più difficile trovare dove si trova il codice del kernel per attaccarlo perché dopo ogni avvio il codice del kernel "si sposta" in modo casuale nella memoria. Sembra un ottimo passo per prevenire potenziali aggressori, ma recente ricerca ha dimostrato che è possibile sconfiggere questo problema senza richiedere un bug o una vulnerabilità del software, poiché KASLR è in realtà molto difficile da implementare in modo efficace contro gli aggressori locali.
Nel caso del software RKP, la possibilità di bypassare KASLR è in realtà più semplice della ricerca sopra citata. La memoria di tutti i dispositivi Android è referenziata da puntatori e, al fine di proteggere i dispositivi dagli attacchi, ogni volta che i dispositivi Android stampano o inviano output (sia su schermo che nel file per i log o per il debug), i riferimenti ai puntatori vengono resi anonimi, rendendo impossibile scoprire dove punta effettivamente il puntatore durante la lettura del produzione.
Pensa ai puntatori della memoria come a un segnale stradale che indica una posizione e pensa all'anonimizzazione come a offuscarlo. Proprio come la televisione, l'anonimizzazione avviene dopo le riprese, anche Android applica questa anonimizzazione al momento dell'uscita e solo se l'anonimizzazione è configurata correttamente, e l'autore afferma che ogni dispositivo [che] ha incontrato aveva l'anonimizzazione del puntatore configurata correttamente. Potrebbe sembrare molto difficile da decifrare, ma tutto ciò che devi fare è trovare un singolo puntatore (ad esempio un segnale stradale) che non sia stato reso anonimo (sfocato) dallo sviluppatore del kernel (attenzione, questo non è lo sviluppatore medio di app Android) quando il puntatore viene scritto nei log o in un'altra posizione, ad es. schermo o a file.
Quindi, se riesci a trovare un puntatore che non è stato reso anonimo, puoi calcolare lo spostamento casuale dell'indirizzo del kernel come differenza tra i due. È interessante notare che l'autore non è riuscito a trovare un puntatore sfruttabile nel kernel ma lo ha trovato all'interno dell'RPK dove gli sviluppatori si sono dimenticati di rendere anonimo un puntatore nell'output di debug (logging), cosa che è avvenuta tramite un errore di battitura. Per anonimizzare i puntatori in Android bisogna utilizzare un codice speciale e si scopre che gli sviluppatori RPK hanno erroneamente utilizzato un "k" minuscola invece di un 'K' maiuscola. Pertanto è stato relativamente semplice capire la quantità di spostamento casuale del codice del kernel e attaccarlo.
Sfruttamento n.2:
Il prossimo exploit è un po' più complesso: Samsung Knox protegge il tuo dispositivo applicando una serie di regole alla memoria del dispositivo per bloccare il codice dannoso. Le regole sono le seguenti:
- Tutte le pagine (codice in memoria), ad eccezione del codice del kernel, sono contrassegnate come "Privileged Execute Never" (il che significa che il codice qui non potrà mai essere eseguito)
- Le pagine di dati del kernel (dati utilizzati dal programma in memoria) non sono mai contrassegnate come eseguibili (quindi il codice qui non potrà mai essere eseguito)
- Le code page del kernel (codice in memoria) non sono mai contrassegnate come scrivibili (quindi nessun codice dannoso può modificarle)
- Tutte le pagine del kernel sono contrassegnate come di sola lettura nella tabella di traduzione della fase 2 (la tabella che si trova tra l'applicazione e il kernel per impedire ulteriormente alle applicazioni di conoscere le reali posizioni di memoria)
- Tutte le voci di traduzione della memoria sono contrassegnate come di sola lettura per le applicazioni.
Ci concentreremo sulla regola 3 poiché è qui che l'autore ha riscontrato un problema con l'implementazione delle regole di cui sopra. RPK in effetti contrassegna la memoria del kernel come di sola lettura, tuttavia per una svista del KASL è stato scoperto un buco, che ha portato a scrivendo codice nella sezione presumibilmente "di sola lettura".. Per offuscare la posizione del kernel al momento dell'avvio, la memoria viene allocata al kernel, ma questa quantità di memoria è molto più grande del segmento di testo del kernel. Allocando una maggiore quantità di memoria diventa molto più difficile trovare il codice del kernel effettivo che potrebbe trovarsi ovunque e, come abbiamo visto sopra, viene spostato in modo casuale ad ogni avvio del dispositivo.
L'autore è stato in grado di confermare che la memoria utilizzata dal kernel era effettivamente contrassegnata come "sola lettura", tuttavia il resto della grande quantità di memoria utilizzata per nascondere il kernel era non contrassegnato come "sola lettura". Questo perché RKP protegge solo la regione contenente il testo del kernel dopo aver applicato la diapositiva KASLR.
Sfruttamento n.3
Nel terzo exploit l'autore è riuscito ad accedere ad un'altra area della memoria che dovrebbe essere anch'essa limitata alla sola lettura. L'RKP protegge la memoria e utilizza a Registro di configurazione dell'hypervisor (HCR) per controllare le operazioni chiave del kernel. Lo scopo dell'HCR è consentire a operazioni valide e reali del kernel di accedere ai registri e bloccare attacchi dannosi. Lo fa controllando le chiamate effettuate ai registri che regolano le funzionalità di virtualizzazione. L'HCR è configurato per bloccare operazioni specifiche che verrebbero gestite normalmente consentendo a RKP di scegliere se consentire o meno una richiesta.
In questo exploit c'era il controllo dell'HCR non copre due registri questo si è rivelato molto importante. L'autore ha approfondito il manuale di riferimento ARM e ha scoperto che il primo registro gli permetteva sostanzialmente di disattivare RKP per le applicazioni. IL "Il registro di controllo del sistema per EL1 (SCTLR_EL1) fornisce il controllo di livello superiore sul sistema, incluso il sistema di memoria." In un mondo perfetto l'applicazione utilizzerebbe la memoria mappata tramite RKP in modo che l'RKP possa controllare a cosa può accedere l'applicazione. Tuttavia, la disattivazione di questo registro ha consentito al RKP da disabilitare riportando effettivamente il dispositivo allo stato in cui funzionava prima dell'installazione di RKP, il che significa che il dispositivo è mappato sulla memoria fisica senza la sicurezza aggiuntiva fornita da RKP. Ciò a sua volta significava che l'autore poteva leggere e scrivere nella memoria originariamente e correttamente bloccata dal software RKP.
Il secondo registro mancato ha avuto un effetto più sottile, ma alla fine altrettanto devastante per la sicurezza. IL Registro di controllo della traduzione per EL1 Il registro (TCR_EL1) si riferisce direttamente alla quantità di memoria con cui lavora un'applicazione chiamata pagina. RKP è codificato su una dimensione di pagina di 4 KB perché i kernel Linux AARCH64 (come Android) utilizzano una dimensione di traduzione di 4 KB. Il registro in questione (TCR_EL1) imposta i chipset ARM sulla dimensione della memoria che deve essere restituita. Si scopre che questo registro non è protetto dall'HCR e quindi un utente malintenzionato può modificarlo poiché l'autore lo ha modificato in una dimensione di pagina di 64kb.
Ciò significa che quando la richiesta viene soddisfatta da RKP, la quantità effettiva di memoria accessibile è ora 64kb invece di 4kb. Il motivo è che il chipset ARM controlla ancora la dimensione della pagina ed è stata impostata su 64kb dall'exploit. Poiché l'RKP protegge la memoria dalla scrittura, come parte delle regole elencate nell'exploit n. 2, la memoria è comunque effettivamente protetta. Ma ecco il problema: poiché RKP è codificato a 4kb, non cambia in una dimensione di pagina di 64kb quando il registro è stato aggiornato, quindi solo i primi 4kb di memoria sono protetti permettendo all'aggressore di farlo quello che vuole con i restanti 60kb.
Sfruttamento n.4
L'ultimo exploit mostrato dall'autore fa riferimento alla memoria in cui si trova il software RKP, quindi l'aggressore potrebbe attaccare il software RKP stesso. Un trucco per fermare questo tipo di attacco utilizzato anche dai kernel Linux è rimuovere la mappatura del programma dallo spazio degli indirizzi della memoria virtuale in modo che nessuna applicazione possa attaccarlo perché non può farvi riferimento.
Ricorda che la memoria è tutta una questione di puntatori e tabelle che mappano la memoria fisica in memoria virtuale. Come per la normale difesa in questo tipo di attacco, RKP si smappa in modo da non poter essere attaccato. Tuttavia, laddove il kernel non fornisce tali capacità, RKP consente di mappare una porzione di memoria e contrassegnarla come Lettura/Scrittura. L'unico controllo è che non si tratti del kernel sottostante stesso poiché RKP non effettua controlli per vedere se gli indirizzi di cui è richiesta la mappatura sono l'area in cui RKP stesso risiede in memoria. Fondamentalmente, RKP si lascia ri-mappare nuovamente nello spazio degli indirizzi a cui le applicazioni possono accedere e, come lato, influenzano il file la memoria viene automaticamente contrassegnata come Lettura/Scrittura quindi un utente malintenzionato ora può utilizzare la memoria come vuole.
Conclusione
Uno dei maggiori problemi con i quattro exploit sopra elencati è che l'autore menziona quanto sarebbero difficili da eseguire a causa della mancanza di funzioni nel kernel Android di base. Per ironia della sorte, il sicuro Hypervisor RKP ha fornito tutti gli strumenti necessari per sferrare gli attacchi. Ciò dimostra che a volte il software ben intenzionato causa più problemi di quanti ne risolva e siamo fortunati ad avere persone come Gal Beniamini disposto a sporcarsi le mani e testare che la documentazione corrisponda a ciò che effettivamente il software fa.
Sebbene questi exploit sembrino spaventosi e facciano sembrare la Knox molto vulnerabile, vorrei rassicurare tutti che questi problemi sono stati tutti affrontati risolto nell'aggiornamento di gennaio da Samsung. Inoltre, questi exploit richiedono una conoscenza molto approfondita dei processori e della programmazione ARM, quindi la barriera all’ingresso nell’utilizzo di questi exploit è astronomicamente alta.
Fonte: Progetto Zero