Linux arm64 Static Linear Map KASLR Bypass

Tip

Leer en oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer en oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Leer en oefen Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Ondersteun HackTricks

Oorsig

Android-kernels wat vir arm64 gebou is, skakel byna universeel CONFIG_ARM64_VA_BITS=39 (3-vlak paging) en CONFIG_MEMORY_HOTPLUG=y in. Met slegs 512 GiB kernel-virtuele ruimte beskikbaar, het die Linux-ontwikkelaars gekies om die linear map op die laagste moontlike kernel-VA te anker sodat toekomstige hot-plugged RAM net die mapping na bo kan uitbrei. Sedert commit 1db780bafa4c probeer arm64 nie eens meer om daardie plasing te randomiseer nie, wat beteken:

  • PAGE_OFFSET = 0xffffff8000000000 is ingebou.
  • PHYS_OFFSET word verkry uit die uitgevoerde memstart_addr, wat op stock Android-toestelle effektief konstant is (0x80000000 vandag).

Gevolglik het elke fisiese bladsy ’n deterministiese linear-map virtuele adres wat onafhanklik is van die KASLR slide:

#define phys_to_virt(p) (((unsigned long)(p) - 0x80000000UL) | 0xffffff8000000000UL)

As ’n aanvaller ’n fisiese adres kan uitvind of beïnvloed (kernel object, PFN van /proc/pagemap, of selfs ’n bladsy wat deur die gebruiker beheer word), weet hulle onmiddellik die ooreenstemmende kernel virtuele adres sonder om die gerandomiseerde primêre kernel mapping te leaking.

Uitlees van memstart_addr en bevestiging van die transformasie

memstart_addr word in /proc/kallsyms uitgegee en kan op gerootde toestelle of via enige willekeurige kernel-read primitive gelees word. Project Zero het Jann Horn se tracing-BPF helper (bpf_arb_read) gebruik om dit direk uit te lees:

grep memstart /proc/kallsyms
# ... obtains memstart_addr virtual address
./bpf_arb_read <addr_of_memstart_addr> 8

Die bytes 00 00 00 80 00 00 00 00 bevestig memstart_addr = 0x80000000. Sodra PAGE_OFFSET en PHYS_OFFSET vasgemaak is, is die arm64 linear map ’n statiese affiene transformasie van enige fisiese adres.

Deriving stable .data addresses on devices with a fixed kernel physbase

Baie Pixels dekomprimeer steeds die kernel by phys_kernel_base = 0x80010000 elke keer tydens boot (sigbaar in /proc/iomem). Kombineer dit met die statiese transformasie en jy kry oor-herlaai-stabiele adresse vir enige data-simbool:

  1. Noteer die gerandomiseerde kernel virtuele adres van _stext en van jou teikensimbool vanaf /proc/kallsyms (of vanaf die presiese vmlinux).
  2. Bereken die offset: offset = sym_virt - _stext_virt.
  3. Voeg die statiese boot-time physbase by: phys_sym = 0x80010000 + offset.
  4. Skakel na ’n linear-map VA: virt_sym = phys_to_virt(phys_sym).

Voorbeeld (modprobe_path op ’n Pixel 9): offset = 0x1fe2398, phys = 0x81ff2398, virt = 0xffffff8001ff2398. Na veelvuldige herlaaisels gee bpf_arb_read 0xffffff8001ff2398 dieselfde bytes terug, so exploit payloads kan 0xffffff8000010000 as ’n sintetiese, nie-gerandomiseerde basis vir alle .data offsets behandel.

Hierdie mapping is RW, so enige primitive wat aanvaller-data in kernel virtuele ruimte kan plaas (double free, UAF, non-paged heap write, ens.) kan credentials, LSM hooks of dispatch-tabelle patch sonder om ooit die ware KASLR slide te leak. Die enigste beperking is dat .text nie-uitvoerbaar in die linear map gemap is, so gadget hunting vereis nog steeds ’n tradisionele leak.

PFN spraying when the kernel physbase is randomized

Verskaffers soos Samsung randomiseer die kernel load PFN, maar die statiese linear map is steeds misbruikbaar omdat PFN-toekenning nie heeltemal ewekansig is nie:

  1. Spray user pages: mmap() ~5 GiB, raak elke bladsy om dit in te fault.
  2. Harvest PFNs: lees /proc/pagemap vir elke bladsy (of gebruik ’n ander PFN leak) om die agterliggende PFN-lys te versamel.
  3. Repeat and profile: herbegin, hardloop 100×, bou ’n histogram wat wys hoe dikwels elke PFN deur die aanvaller beheer is. Sommige PFNs is witheet (toegeken 100/100 keer kort ná boot).
  4. Convert PFN → kernel VA:
  • phys = (pfn << PAGE_SHIFT) + offset_in_page
  • virt = phys_to_virt(phys)
  1. Forge kernel objects in those pages en stuur victimpointers (UAF, overflow, ens.) na die bekende linear-map adresse.

Omdat die linear map identity-mapped RW geheue is, laat hierdie tegniek jou toe om volledig aanvaller-gekontroleerde data op deterministiese kernel VAs te plaas, selfs wanneer die werklike kernel basis skuif. Exploits kan vooraf fake file_operations, cred, of refcount-strukture in die gesprayde bladsye bou en dan bestaande kernel-pointers daarheen pivot.

Practical workflow for arm64 Android exploits

  1. Info gathering
  • Root of gebruik ’n kernel read primitive om memstart_addr, _stext, en die teikensimbool vanaf /proc/kallsyms uit te dumpe.
  • Op Pixels, vertrou die statiese physbase vanuit /proc/iomem; op ander toestelle, berei die PFN profiler voor.
  1. Address calculation
  • Pas die offset-wiskunde hierbo toe en cache die resulterende linear-map VAs in jou exploit.
  • Vir PFN spraying, hou ’n lys van “betroubare” PFNs wat herhaaldelik in aanvaller-geheue beland.
  1. Exploit integration
  • Wanneer ’n arbitrary write beskikbaar is, patch direk teikens soos modprobe_path, init_cred, of security ops arrays by die vooraf-berekende adresse.
  • Wanneer slegs heap-corruption bestaan, vervaardig fake objects in die bekende-gesuperviseerde bladsye en herlei victimpointers na daardie linear-map VAs.
  1. Verification
  • Gebruik bpf_arb_read of enige veilige read primitive om te kontroleer dat die berekende adres die verwagte bytes bevat vóór destruktiewe skrywes.

Hierdie werkstroom elimineer die KASLR-leak fase vir data-sentriese kernel exploits op Android, wat exploit-kompleksiteit drasties verlaag en betroubaarheid verbeter.

References

Tip

Leer en oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer en oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Leer en oefen Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Ondersteun HackTricks