iOS Exploiting
Physical use-after-free
Ovo je sažetak iz posta sa https://alfiecg.uk/2024/09/24/Kernel-exploit.html, a dodatne informacije o eksploatu korišćenjem ove tehnike mogu se naći na https://github.com/felix-pb/kfd
Memory management in XNU
Virtuelni adresni prostor za korisničke procese na iOS-u se proteže od 0x0 do 0x8000000000. Međutim, ove adrese se ne mapiraju direktno na fizičku memoriju. Umesto toga, kernel koristi tabele stranica za prevođenje virtuelnih adresa u stvarne fizičke adrese.
Levels of Page Tables in iOS
Tabele stranica su organizovane hijerarhijski u tri nivoa:
L1 Page Table (Nivo 1):
Svaki unos ovde predstavlja veliki opseg virtuelne memorije.
Pokriva 0x1000000000 bajtova (ili 256 GB) virtuelne memorije.
L2 Page Table (Nivo 2):
Unos ovde predstavlja manju oblast virtuelne memorije, specifično 0x2000000 bajtova (32 MB).
L1 unos može ukazivati na L2 tabelu ako ne može da mapira celu oblast sam.
L3 Page Table (Nivo 3):
Ovo je najfiniji nivo, gde svaki unos mapira jednu 4 KB memorijsku stranicu.
L2 unos može ukazivati na L3 tabelu ako je potrebna detaljnija kontrola.
Mapping Virtual to Physical Memory
Direktno mapiranje (Block Mapping):
Neki unosi u tabeli stranica direktno mapiraju opseg virtuelnih adresa na kontiguitetni opseg fizičkih adresa (poput prečice).
Pokazivač na Child Page Table:
Ako je potrebna finija kontrola, unos u jednom nivou (npr. L1) može ukazivati na child page table na sledećem nivou (npr. L2).
Example: Mapping a Virtual Address
Recimo da pokušavate da pristupite virtuelnoj adresi 0x1000000000:
L1 Tabela:
Kernel proverava L1 unos tabele stranica koji odgovara ovoj virtuelnoj adresi. Ako ima pokazivač na L2 tabelu, odlazi na tu L2 tabelu.
L2 Tabela:
Kernel proverava L2 tabelu stranica za detaljnije mapiranje. Ako ovaj unos ukazuje na L3 tabelu, nastavlja tamo.
L3 Tabela:
Kernel traži konačni L3 unos, koji ukazuje na fizičku adresu stvarne memorijske stranice.
Example of Address Mapping
Ako upišete fizičku adresu 0x800004000 u prvi indeks L2 tabele, tada:
Virtuelne adrese od 0x1000000000 do 0x1002000000 mapiraju se na fizičke adrese od 0x800004000 do 0x802004000.
Ovo je block mapping na L2 nivou.
Alternativno, ako L2 unos ukazuje na L3 tabelu:
Svaka 4 KB stranica u opsegu virtuelnih adresa 0x1000000000 -> 0x1002000000 biće mapirana pojedinačnim unosima u L3 tabeli.
Physical use-after-free
Fizički use-after-free (UAF) se dešava kada:
Proces alokira neku memoriju kao čitljivu i zapisivu.
Tabele stranica se ažuriraju da mapiraju ovu memoriju na određenu fizičku adresu kojoj proces može pristupiti.
Proces dealokira (oslobađa) memoriju.
Međutim, zbog greške, kernel zaboravlja da ukloni mapiranje iz tabela stranica, iako označava odgovarajuću fizičku memoriju kao slobodnu.
Kernel može zatim ponovo alocirati ovu "oslobođenu" fizičku memoriju za druge svrhe, poput kernel podataka.
Pošto mapiranje nije uklonjeno, proces može i dalje čitati i pisati u ovu fizičku memoriju.
To znači da proces može pristupiti stranicama kernel memorije, koje mogu sadržati osetljive podatke ili strukture, potencijalno omogućavajući napadaču da manipuliše kernel memorijom.
Exploitation Strategy: Heap Spray
Pošto napadač ne može kontrolisati koje specifične kernel stranice će biti alocirane na oslobođenoj memoriji, koriste tehniku nazvanu heap spray:
Napadač stvara veliki broj IOSurface objekata u kernel memoriji.
Svaki IOSurface objekat sadrži magijsku vrednost u jednom od svojih polja, što olakšava identifikaciju.
Oni skeniraju oslobođene stranice da vide da li je neki od ovih IOSurface objekata sleteo na oslobođenu stranicu.
Kada pronađu IOSurface objekat na oslobođenoj stranici, mogu ga koristiti za čitati i pisati kernel memoriju.
Više informacija o ovome u https://github.com/felix-pb/kfd/tree/main/writeups
Step-by-Step Heap Spray Process
Spray IOSurface Objects: Napadač stvara mnogo IOSurface objekata sa posebnim identifikatorom ("magijska vrednost").
Scan Freed Pages: Proveravaju da li su neki od objekata alocirani na oslobođenoj stranici.
Read/Write Kernel Memory: Manipulacijom polja u IOSurface objektu, stiču mogućnost da izvrše arbitrarne čitanja i pisanja u kernel memoriji. Ovo im omogućava:
Da koriste jedno polje za čitati bilo koju 32-bitnu vrednost u kernel memoriji.
Da koriste drugo polje za pisanje 64-bitnih vrednosti, postizajući stabilnu kernel read/write primitivu.
Generišite IOSurface objekte sa magičnom vrednošću IOSURFACE_MAGIC da biste ih kasnije tražili:
Pretražite IOSurface
objekte u jednoj oslobođenoj fizičkoj stranici:
Postizanje Kernel Read/Write sa IOSurface
Nakon što postignemo kontrolu nad IOSurface objektom u kernel memoriji (mapiranim na oslobođenu fizičku stranicu dostupnu iz korisničkog prostora), možemo ga koristiti za arbitrarne kernel read i write operacije.
Ključna Polja u IOSurface
IOSurface objekat ima dva ključna polja:
Pokazivač na Broj Korišćenja: Omogućava 32-bitno čitanje.
Pokazivač na Indeksirani Vremepečat: Omogućava 64-bitno pisanje.
Prepisivanjem ovih pokazivača, preusmeravamo ih na arbitrarne adrese u kernel memoriji, omogućavajući read/write mogućnosti.
32-Bitno Kernel Čitanje
Da bismo izvršili čitanje:
Prepišite pokazivač na broj korišćenja da pokazuje na ciljnu adresu minus 0x14-bajtni ofset.
Koristite
get_use_count
metodu da pročitate vrednost na toj adresi.
64-Bit Kernel Write
Da biste izvršili pisanje:
Prepišite pokazivač indeksiranog vremenskog pečata na ciljnu adresu.
Koristite metodu
set_indexed_timestamp
da biste napisali 64-bitnu vrednost.
Exploit Flow Recap
Pokreni fizičko korišćenje nakon oslobađanja: Oslobođene stranice su dostupne za ponovnu upotrebu.
Prskanje IOSurface objekata: Alociraj mnogo IOSurface objekata sa jedinstvenom "čarobnom vrednošću" u kernel memoriji.
Identifikuj dostupni IOSurface: Pronađi IOSurface na oslobođenoj stranici koju kontrolišeš.
Zloupotrebi korišćenje nakon oslobađanja: Izmeni pokazivače u IOSurface objektu da omogućiš proizvoljno čitanje/pisanje u kernel putem IOSurface metoda.
Sa ovim primitivima, exploit omogućava kontrolisano 32-bitno čitanje i 64-bitno pisanje u kernel memoriju. Dalji koraci za jailbreak mogu uključivati stabilnije primitivne operacije čitanja/pisanja, što može zahtevati zaobilaženje dodatnih zaštita (npr., PPL na novijim arm64e uređajima).
Last updated