
kfd, abbreviazione di kernel file descriptor, è un progetto per leggere e scrivere la memoria del kernel su dispositivi Apple.
Dichiarazione rapida: non ho intenzione di aggiungere offset per altri dispositivi e versioni iOS.
kfd, abbreviazione di kernel file descriptor, è un progetto per leggere e scrivere la memoria del kernel sui dispositivi Apple. Sfrutta varie vulnerabilità che possono essere sfruttate per ottenere PTE dangling, che verranno indicate come primitiva PUAF, abbreviazione di "physical use-after-free". Quindi rialloca alcuni oggetti del kernel all'interno di quelle pagine fisiche e li manipola direttamente dallo spazio utente tramite le PTE dangling per ottenere una primitiva KRKW, abbreviazione di "kernel read/write". Il codice dell'exploit è interamente contenuto in una libreria, libkfd, ma il progetto contiene anche semplici wrapper eseguibili per iOS e macOS. L'API pubblica di libkfd è piuttosto piccola e intuitiva:
enum puaf_method {
puaf_physpuppet,
puaf_smith,
puaf_landa,
};
enum kread_method {
kread_kqueue_workloop_ctl,
kread_sem_open,
};
enum kwrite_method {
kwrite_dup,
kwrite_sem_open,
};
u64 kopen(u64 puaf_pages, u64 puaf_method, u64 kread_method, u64 kwrite_method);
void kread(u64 kfd, u64 kaddr, void* uaddr, u64 size);
void kwrite(u64 kfd, void* uaddr, u64 kaddr, u64 size);
void kclose(u64 kfd);
kopen() apre concettualmente un "descrittore di file del kernel". Accetta i seguenti 4 argomenti:
puaf_pages: Il numero target di pagine fisiche con PTE dangling.puaf_method: Il metodo usato per ottenere la primitiva PUAF, con le seguenti opzioni:
puaf_physpuppet:
puaf_smith:
puaf_landa:
kread_method: Il metodo usato per ottenere la primitiva kread() iniziale.kwrite_method: Il metodo usato per ottenere la primitiva iniziale.Se l'exploit ha successo, kopen() restituisce un descrittore di file opaco a 64 bit. In pratica, si tratta solo di un puntatore nello spazio utente a una struttura necessaria a libkfd. Tuttavia, poiché tale struttura non dovrebbe essere accessibile al di fuori della libreria, viene restituita come intero opaco. Se l'exploit non riesce, la libreria stampa un messaggio di errore, dorme per 30 secondi, quindi esce con un codice di stato 1. Dorme per 30 secondi perché il kernel potrebbe andare in panico all'uscita per alcuni metodi PUAF che richiedono una pulizia post-KRKW (ad es. puaf_smith).
kread() e kwrite() sono l'equivalente nello spazio utente rispettivamente di copyout() e copyin(). Nota che le opzioni per kread_method e kwrite_method sono descritte in un write-up separato. Inoltre, le primitive iniziali fornite da questi metodi possono essere usate per avviare una migliore primitiva KRKW. Infine, kclose() chiude semplicemente il descrittore di file del kernel. Tutte accettano come primo argomento l'intero opaco restituito da kopen().
In Xcode, apri la cartella principale del progetto e collega il tuo dispositivo iOS.
In un terminale, spostati nella cartella principale del progetto.
Facoltativamente, per aumentare i limiti globali e per-processo dei descrittori di file, il che migliorerà il tasso di successo soprattutto su più esecuzioni consecutive, inserisci il comando make s e digita la password di sudo.
make b.make r.make br.Questo README ha presentato una panoramica ad alto livello del progetto kfd. Una volta ottenuta una primitiva PUAF, il resto dell'exploit è generico. Pertanto, ho raccolto la parte comune degli exploit in un write-up dedicato:
Inoltre, ho suddiviso la parte specifica della vulnerabilità degli exploit usati per ottenere la primitiva PUAF in write-up distinti, elencati di seguito in ordine cronologico di scoperta:
Tuttavia, tieni presente che questi write-up sono stati scritti per un pubblico già familiare con il sistema di memoria virtuale XNU.
kwrite()