Linux arm64 Static Linear Map KASLR Bypass

Tip

AWS ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ:HackTricks Training AWS Red Team Expert (ARTE)
GCP ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: HackTricks Training GCP Red Team Expert (GRTE) Azure ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks ์ง€์›ํ•˜๊ธฐ

๊ฐœ์š”

arm64์šฉ Android kernels๋Š” ๊ฑฐ์˜ ์˜ˆ์™ธ ์—†์ด CONFIG_ARM64_VA_BITS=39 (3-level paging) ๋ฐ **CONFIG_MEMORY_HOTPLUG=y**๋ฅผ ํ™œ์„ฑํ™”ํ•ฉ๋‹ˆ๋‹ค. ์ปค๋„ ๊ฐ€์ƒ ๊ณต๊ฐ„์ด 512 GiB๋กœ ์ œํ•œ๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, Linux ๊ฐœ๋ฐœ์ž๋“ค์€ ํ–ฅํ›„ ํ•ซํ”Œ๋Ÿฌ๊ทธ๋œ RAM์ด ๋งคํ•‘์„ ์œ„๋กœ ํ™•์žฅํ•  ์ˆ˜ ์žˆ๋„๋ก linear map์„ ๊ฐ€๋Šฅํ•œ ๊ฐ€์žฅ ๋‚ฎ์€ ์ปค๋„ VA์— ๊ณ ์ •(anchor)ํ•˜๋„๋ก ๊ฒฐ์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ปค๋ฐ‹ 1db780bafa4c ์ดํ›„, arm64๋Š” ํ•ด๋‹น ์œ„์น˜๋ฅผ ๋ฌด์ž‘์œ„ํ™”ํ•˜๋ ค๋Š” ์‹œ๋„์กฐ์ฐจ ํ•˜์ง€ ์•Š์œผ๋ฉฐ, ์ด๋Š” ๋‹ค์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค:

  • PAGE_OFFSET = 0xffffff8000000000๊ฐ€ ์ปดํŒŒ์ผ๋˜์–ด ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.
  • PHYS_OFFSET๋Š” export๋œ memstart_addr์—์„œ ๊ฐ€์ ธ์˜ค๋ฉฐ, stock Android ๋””๋ฐ”์ด์Šค์—์„œ๋Š” ์‚ฌ์‹ค์ƒ ๋ถˆ๋ณ€(์˜ค๋Š˜๋‚  0x80000000)์ž…๋‹ˆ๋‹ค.

๊ฒฐ๊ณผ์ ์œผ๋กœ, ๋ชจ๋“  ๋ฌผ๋ฆฌ ํŽ˜์ด์ง€๋Š” KASLR slide์™€ ๋ฌด๊ด€ํ•œ ๊ฒฐ์ •๋ก ์  linear-map ๊ฐ€์ƒ ์ฃผ์†Œ๋ฅผ ๊ฐ–์Šต๋‹ˆ๋‹ค:

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

If an attacker can learn or influence a physical address (kernel object, PFN from /proc/pagemap, or even a user-controlled page), they instantly know the corresponding kernel virtual address without leaking the randomized primary kernel mapping.

memstart_addr ์ฝ๊ธฐ ๋ฐ ๋ณ€ํ™˜ ํ™•์ธ

memstart_addr๋Š” /proc/kallsyms์— export๋˜์–ด ์žˆ์œผ๋ฉฐ ๋ฃจํŒ…๋œ ๊ธฐ๊ธฐ๋‚˜ ์ž„์˜์˜ kernel-read primitive๋ฅผ ํ†ตํ•ด ์ฝ์„ ์ˆ˜ ์žˆ๋‹ค. Project Zero๋Š” Jann Horn์˜ tracing-BPF helper (bpf_arb_read)๋ฅผ ์‚ฌ์šฉํ•ด ์ด๋ฅผ ์ง์ ‘ ๋คํ”„ํ–ˆ๋‹ค:

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

๋ฐ”์ดํŠธ 00 00 00 80 00 00 00 00 ๋Š” memstart_addr = 0x80000000์„(๋ฅผ) ํ™•์ธํ•œ๋‹ค. PAGE_OFFSET์™€ PHYS_OFFSET๊ฐ€ ๊ณ ์ •๋˜๋ฉด, arm64 linear map์€ ๋ชจ๋“  ๋ฌผ๋ฆฌ ์ฃผ์†Œ์— ๋Œ€ํ•ด ์ •์ ์ธ affine ๋ณ€ํ™˜์ด ๋œ๋‹ค.

๊ณ ์ •๋œ kernel physbase๋ฅผ ๊ฐ€์ง„ ์žฅ์น˜์—์„œ ์•ˆ์ •์ ์ธ .data ์ฃผ์†Œ ์œ ๋„

๋งŽ์€ Pixel ๊ธฐ๊ธฐ๋“ค์€ ์—ฌ์ „ํžˆ ๋งค ๋ถ€ํŒ…๋งˆ๋‹ค ์ปค๋„์„ phys_kernel_base = 0x80010000 ์— ์••์ถ• ํ•ด์ œํ•œ๋‹ค(/proc/iomem์—์„œ ํ™•์ธ ๊ฐ€๋Šฅ). ์ด๋ฅผ ์ •์  ๋ณ€ํ™˜๊ณผ ๊ฒฐํ•ฉํ•˜๋ฉด ์–ด๋–ค ๋ฐ์ดํ„ฐ ์‹ฌ๋ณผ์— ๋Œ€ํ•ด์„œ๋„ ์žฌ๋ถ€ํŒ… ๊ฐ„์— ์•ˆ์ •์ ์ธ ์ฃผ์†Œ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค:

  1. /proc/kallsyms(๋˜๋Š” ์ •ํ™•ํ•œ vmlinux์—์„œ) _stext์™€ ๋Œ€์ƒ ์‹ฌ๋ณผ์˜ ๋žœ๋คํ™”๋œ kernel ๊ฐ€์ƒ ์ฃผ์†Œ๋ฅผ ๊ธฐ๋กํ•œ๋‹ค.
  2. ์˜คํ”„์…‹์„ ๊ณ„์‚ฐํ•œ๋‹ค: offset = sym_virt - _stext_virt.
  3. ๋ถ€ํŒ… ์‹œ ๊ณ ์ • physbase๋ฅผ ๋”ํ•œ๋‹ค: phys_sym = 0x80010000 + offset.
  4. linear-map VA๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค: virt_sym = phys_to_virt(phys_sym).

์˜ˆ์‹œ(Pixel 9์˜ modprobe_path): offset = 0x1fe2398, phys = 0x81ff2398, virt = 0xffffff8001ff2398. ์—ฌ๋Ÿฌ ๋ฒˆ ์žฌ๋ถ€ํŒ…ํ•œ ํ›„ bpf_arb_read 0xffffff8001ff2398๋Š” ๋™์ผํ•œ ๋ฐ”์ดํŠธ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฏ€๋กœ, ์ต์Šคํ”Œ๋กœ์ž‡ ํŽ˜์ด๋กœ๋“œ๋Š” ๋ชจ๋“  .data ์˜คํ”„์…‹์— ๋Œ€ํ•ด 0xffffff8000010000์„ ํ•ฉ์„ฑ๋œ, ๋น„๋‚œ์ˆ˜ํ™”๋œ(base) ๋ฒ ์ด์Šค๋กœ ์ทจ๊ธ‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

์ด ๋งคํ•‘์€ RW์ด๋ฏ€๋กœ, ๊ณต๊ฒฉ์ž ๋ฐ์ดํ„ฐ๋ฅผ kernel ๊ฐ€์ƒ ๊ณต๊ฐ„์— ๋†“์„ ์ˆ˜ ์žˆ๋Š” ์–ด๋–ค primitive(์˜ˆ: double free, UAF, non-paged heap write ๋“ฑ)๋„ ์‹ค์ œ KASLR slide๋ฅผ leakํ•˜์ง€ ์•Š๊ณ  credentials, LSM hooks, ๋˜๋Š” dispatch tables๋ฅผ ํŒจ์น˜ํ•  ์ˆ˜ ์žˆ๋‹ค. ์œ ์ผํ•œ ์ œ์•ฝ์€ .text๊ฐ€ linear map์—์„œ ๋น„์‹คํ–‰(non-executable)์œผ๋กœ ๋งคํ•‘๋˜์–ด ์žˆ์–ด gadget ์ˆ˜์ง‘์—๋Š” ์—ฌ์ „ํžˆ ์ „ํ†ต์ ์ธ leak์ด ํ•„์š”ํ•˜๋‹ค๋Š” ์ ์ด๋‹ค.

kernel physbase๊ฐ€ ๋žœ๋คํ™”๋œ ๊ฒฝ์šฐ PFN spraying

Samsung๊ณผ ๊ฐ™์€ ๋ฒค๋”๋“ค์€ kernel ๋กœ๋“œ PFN์„ ๋žœ๋คํ™”ํ•˜์ง€๋งŒ, PFN ํ• ๋‹น์ด ์™„์ „ํžˆ ๋žœ๋คํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— static linear map์€ ์—ฌ์ „ํžˆ ์•…์šฉ ๊ฐ€๋Šฅํ•˜๋‹ค:

  1. Spray user pages: mmap()๋กœ ์•ฝ 5 GiB๋ฅผ ํ™•๋ณดํ•˜๊ณ , ๋ชจ๋“  ํŽ˜์ด์ง€๋ฅผ ์ ‘๊ทผํ•˜์—ฌ fault๋ฅผ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค.
  2. Harvest PFNs: ๊ฐ ํŽ˜์ด์ง€์— ๋Œ€ํ•ด /proc/pagemap์„ ์ฝ๊ฑฐ๋‚˜(๋˜๋Š” ๋‹ค๋ฅธ PFN leak์„ ์‚ฌ์šฉํ•˜์—ฌ) backing PFN ๋ชฉ๋ก์„ ์ˆ˜์ง‘ํ•œ๋‹ค.
  3. Repeat and profile: ์žฌ๋ถ€ํŒ…ํ•˜๊ณ  100ร— ์žฌ์‹คํ–‰ํ•˜์—ฌ ๊ฐ PFN์ด ๊ณต๊ฒฉ์ž ์ œ์–ด๋กœ ํ• ๋‹น๋˜๋Š” ๋นˆ๋„๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ํžˆ์Šคํ† ๊ทธ๋žจ์„ ๋งŒ๋“ ๋‹ค. ์ผ๋ถ€ PFN์€ white-hotํ•˜๋‹ค(๋ถ€ํŒ… ์งํ›„ 100/100 ๋ฒˆ ํ• ๋‹น๋จ).
  4. Convert PFN โ†’ kernel VA:
  • phys = (pfn << PAGE_SHIFT) + offset_in_page
  • virt = phys_to_virt(phys)
  1. Forge kernel objects in those pages and victim ํฌ์ธํ„ฐ(UAF, overflow ๋“ฑ)๋ฅผ ์•Œ๋ ค์ง„ linear-map ์ฃผ์†Œ๋กœ ์œ ๋„ํ•œ๋‹ค.

linear map์ด identity-mapped RW ๋ฉ”๋ชจ๋ฆฌ์ด๊ธฐ ๋•Œ๋ฌธ์—, ์ด ๊ธฐ๋ฒ•์€ ์‹ค์ œ kernel base๊ฐ€ ์ด๋™ํ•ด๋„ ๊ฒฐ์ •๋ก ์ ์ธ kernel VA์— ์™„์ „ํ•œ ๊ณต๊ฒฉ์ž ์ œ์–ด ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐฐ์น˜ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค€๋‹ค. ์ต์Šคํ”Œ๋กœ์ž‡์€ ์Šคํ”„๋ ˆ์ด๋œ ํŽ˜์ด์ง€ ๋‚ด๋ถ€์— ๊ฐ€์งœ file_operations, cred, ๋˜๋Š” refcount ๊ตฌ์กฐ์ฒด๋ฅผ ๋ฏธ๋ฆฌ ๋งŒ๋“ค์–ด ๋‘๊ณ  ๊ธฐ์กด kernel ํฌ์ธํ„ฐ๋ฅผ ๊ทธ์ชฝ์œผ๋กœ ํ”ผ๋ฒ—ํ•  ์ˆ˜ ์žˆ๋‹ค.

arm64 Android ์ต์Šคํ”Œ๋กœ์ž‡์„ ์œ„ํ•œ ์‹ค์ „ ์›Œํฌํ”Œ๋กœ

  1. Info gathering
  • Root ๊ถŒํ•œ์„ ์–ป๊ฑฐ๋‚˜ kernel read primitive๋ฅผ ์‚ฌ์šฉํ•ด /proc/kallsyms์—์„œ memstart_addr, _stext, ๋Œ€์ƒ ์‹ฌ๋ณผ์„ ๋คํ”„ํ•œ๋‹ค.
  • Pixel์—์„œ๋Š” /proc/iomem์˜ static physbase๋ฅผ ์‹ ๋ขฐํ•˜๊ณ , ๋‹ค๋ฅธ ๊ธฐ๊ธฐ์—์„œ๋Š” PFN profiler๋ฅผ ์ค€๋น„ํ•œ๋‹ค.
  1. Address calculation
  • ์œ„์˜ offset ์—ฐ์‚ฐ์„ ์ ์šฉํ•˜๊ณ  ๊ฒฐ๊ณผ linear-map VA๋ฅผ ์ต์Šคํ”Œ๋กœ์ž‡์— ์บ์‹œํ•œ๋‹ค.
  • PFN spraying์˜ ๊ฒฝ์šฐ, ๊ณต๊ฒฉ์ž ๋ฉ”๋ชจ๋ฆฌ์— ๋ฐ˜๋ณต์ ์œผ๋กœ ๋“ค์–ด์˜ค๋Š” โ€œreliableโ€ PFN ๋ชฉ๋ก์„ ์œ ์ง€ํ•œ๋‹ค.
  1. Exploit integration
  • arbitrary write๊ฐ€ ๊ฐ€๋Šฅํ•˜๋ฉด ๋ฏธ๋ฆฌ ๊ณ„์‚ฐํ•œ ์ฃผ์†Œ์—์„œ modprobe_path, init_cred, ๋˜๋Š” security ops ๋ฐฐ์—ด๊ณผ ๊ฐ™์€ ํƒ€๊ฒŸ์„ ์ง์ ‘ ํŒจ์น˜ํ•œ๋‹ค.
  • heap corruption๋งŒ ์กด์žฌํ•  ๊ฒฝ์šฐ, ์•Œ๋ ค์ง„ ๊ฐ์‹œ ํŽ˜์ด์ง€๋“ค์— ๊ฐ€์งœ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ณ  ํ”ผํ•ด์ž ํฌ์ธํ„ฐ๋ฅผ ๊ทธ linear-map VA๋กœ ์žฌ์ง€์ •ํ•œ๋‹ค.
  1. Verification
  • ํŒŒ๊ดด์  ์“ฐ๊ธฐ ์ „์— bpf_arb_read ๋˜๋Š” ์ž„์˜์˜ ์•ˆ์ „ํ•œ read primitive๋กœ ๊ณ„์‚ฐํ•œ ์ฃผ์†Œ๊ฐ€ ์˜ˆ์ƒ ๋ฐ”์ดํŠธ๋ฅผ ํฌํ•จํ•˜๊ณ  ์žˆ๋Š”์ง€ ํ™•์ธํ•œ๋‹ค.

์ด ์›Œํฌํ”Œ๋กœ๋Š” Android์—์„œ ๋ฐ์ดํ„ฐ ์ค‘์‹ฌ kernel ์ต์Šคํ”Œ๋กœ์ž‡์— ๋Œ€ํ•ด KASLR-leak ๋‹จ๊ณ„๋ฅผ ์ œ๊ฑฐํ•˜์—ฌ ์ต์Šคํ”Œ๋กœ์ž‡ ๋ณต์žก๋„๋ฅผ ํฌ๊ฒŒ ๋‚ฎ์ถ”๊ณ  ์‹ ๋ขฐ์„ฑ์„ ํ–ฅ์ƒ์‹œํ‚จ๋‹ค.

์ฐธ๊ณ ์ž๋ฃŒ

Tip

AWS ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ:HackTricks Training AWS Red Team Expert (ARTE)
GCP ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: HackTricks Training GCP Red Team Expert (GRTE) Azure ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks ์ง€์›ํ•˜๊ธฐ