iOS ์ต์Šคํ”Œ๋กœ์ž‡

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 ์ง€์›ํ•˜๊ธฐ

iOS Exploit Mitigations

1. Code Signing / Runtime Signature Verification

Introduced early (iPhone OS โ†’ iOS) ์ด๊ฒƒ์€ ๊ธฐ๋ณธ์ ์ธ ๋ณดํ˜ธ ์žฅ์น˜ ์ค‘ ํ•˜๋‚˜๋กœ: ๋ชจ๋“  ์‹คํ–‰ ๊ฐ€๋Šฅ ์ฝ”๋“œ(์•ฑ, dynamic libraries, JIT-ed code, extensions, frameworks, caches)๋Š” Apple์˜ ์‹ ๋ขฐ ๋ฃจํŠธ์— ๊ธฐ๋ฐ˜ํ•œ ์ธ์ฆ์„œ ์ฒด์ธ์œผ๋กœ ์•”ํ˜ธํ™” ์„œ๋ช…๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋Ÿฐํƒ€์ž„์—์„œ ๋ฐ”์ด๋„ˆ๋ฆฌ๋ฅผ ๋ฉ”๋ชจ๋ฆฌ์— ๋กœ๋“œํ•˜๊ธฐ ์ „์—(๋˜๋Š” ํŠน์ • ๊ฒฝ๊ณ„๋ฅผ ๋„˜๋Š” ์ ํ”„๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์ „์—) ์‹œ์Šคํ…œ์€ ์„œ๋ช…์„ ๊ฒ€์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์ฝ”๋“œ๊ฐ€ ์ˆ˜์ •(๋น„ํŠธ ํ”Œ๋ฆฝ, ํŒจ์น˜)๋˜์—ˆ๊ฑฐ๋‚˜ ์„œ๋ช…์ด ์—†์œผ๋ฉด ๋กœ๋“œ๊ฐ€ ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค.

  • ์ฐจ๋‹จ ๋Œ€์ƒ: ์ต์Šคํ”Œ๋กœ์ž‡ ์ฒด์ธ์—์„œ์˜ โ€œclassic payload drop + executeโ€ ๋‹จ๊ณ„; ์ž„์˜ ์ฝ”๋“œ ์ฃผ์ž…; ๊ธฐ์กด ๋ฐ”์ด๋„ˆ๋ฆฌ๋ฅผ ์ˆ˜์ •ํ•ด ์•…์˜์  ๋กœ์ง์„ ์‚ฝ์ž…ํ•˜๋Š” ๊ฒƒ.
  • ๋ฉ”์ปค๋‹ˆ์ฆ˜ ์„ธ๋ถ€:
  • Mach-O ๋กœ๋”(๋ฐ dynamic linker)๋Š” ์ฝ”๋“œ ํŽ˜์ด์ง€, ์„ธ๊ทธ๋จผํŠธ, entitlements, team IDs, ๊ทธ๋ฆฌ๊ณ  ์„œ๋ช…์ด ํŒŒ์ผ ๋‚ด์šฉ ์ „์ฒด๋ฅผ ํฌํ•จํ•˜๋Š”์ง€๋ฅผ ๊ฒ€์‚ฌํ•ฉ๋‹ˆ๋‹ค.
  • JIT ์บ์‹œ๋‚˜ ๋™์ ์œผ๋กœ ์ƒ์„ฑ๋œ ์ฝ”๋“œ์™€ ๊ฐ™์€ ๋ฉ”๋ชจ๋ฆฌ ์˜์—ญ์˜ ๊ฒฝ์šฐ, Apple์€ ํŽ˜์ด์ง€๊ฐ€ ์„œ๋ช…๋˜๊ฑฐ๋‚˜ ํŠน์ˆ˜ API(์˜ˆ: mprotect์™€ code-sign ์ฒดํฌ)๋ฅผ ํ†ตํ•ด ๊ฒ€์ฆ๋˜๋„๋ก ๊ฐ•์ œํ•ฉ๋‹ˆ๋‹ค.
  • ์„œ๋ช…์€ entitlements์™€ ์‹๋ณ„์ž๋ฅผ ํฌํ•จํ•˜๋ฉฐ, OS๋Š” ํŠน์ • API๋‚˜ ๊ถŒํ•œ ์žˆ๋Š” ๊ธฐ๋Šฅ์ด ํŠน์ • entitlements๋ฅผ ์š”๊ตฌํ•จ์„ ๊ฐ•์ œํ•ฉ๋‹ˆ๋‹ค(์œ„์กฐ ๋ถˆ๊ฐ€).
์˜ˆ์‹œ ์ต์Šคํ”Œ๋กœ์ž‡์ด ํ”„๋กœ์„ธ์Šค์—์„œ ์ฝ”๋“œ ์‹คํ–‰์„ ์–ป๊ณ  ํž™์— shellcode๋ฅผ ์“ฐ๊ณ  ๊ทธ๊ณณ์œผ๋กœ ์ ํ”„ํ•˜๋ ค๊ณ  ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ์‹œ๋‹ค. iOS์—์„œ๋Š” ํ•ด๋‹น ํŽ˜์ด์ง€๊ฐ€ executable๋กœ ํ‘œ์‹œ๋˜๋Š” ๊ฒƒ๋ฟ ์•„๋‹ˆ๋ผ code-signature ์ œ์•ฝ์„ ๋งŒ์กฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. shellcode๊ฐ€ Apple์˜ ์ธ์ฆ์„œ๋กœ ์„œ๋ช…๋˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ์ ํ”„๊ฐ€ ์‹คํŒจํ•˜๊ฑฐ๋‚˜ ์‹œ์Šคํ…œ์ด ํ•ด๋‹น ๋ฉ”๋ชจ๋ฆฌ ์˜์—ญ์„ executable๋กœ ๋งŒ๋“œ๋Š” ๊ฒƒ์„ ๊ฑฐ๋ถ€ํ•ฉ๋‹ˆ๋‹ค.

2. CoreTrust

Introduced around iOS 14+ era (or gradually in newer devices / later iOS) CoreTrust๋Š” ๋ฐ”์ด๋„ˆ๋ฆฌ(์‹œ์Šคํ…œ ๋ฐ ์‚ฌ์šฉ์ž ๋ฐ”์ด๋„ˆ๋ฆฌ ํฌํ•จ)์˜ ๋Ÿฐํƒ€์ž„ ์„œ๋ช… ๊ฒ€์ฆ์„ Apple์˜ ๋ฃจํŠธ ์ธ์ฆ์„œ์— ๋Œ€ํ•˜์—ฌ ์ˆ˜ํ–‰ํ•˜๋Š” ์„œ๋ธŒ์‹œ์Šคํ…œ์œผ๋กœ, ๋กœ์ปฌ ์œ ์ €๋žœ๋“œ ์‹ ๋ขฐ ์ €์žฅ์†Œ์— ์˜์กดํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

  • ์ฐจ๋‹จ ๋Œ€์ƒ: ์„ค์น˜ ํ›„ ๋ฐ”์ด๋„ˆ๋ฆฌ ๋ณ€์กฐ, ์‹œ์Šคํ…œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋‚˜ ์‚ฌ์šฉ์ž ์•ฑ์„ ๊ต์ฒด/ํŒจ์น˜ํ•˜๋ ค๋Š” ํƒˆ์˜ฅ ๊ธฐ๋ฒ•; ์‹ ๋ขฐ๋œ ๋ฐ”์ด๋„ˆ๋ฆฌ๋ฅผ ์•…์„ฑ ๋ฐ”์ด๋„ˆ๋ฆฌ๋กœ ๊ต์ฒดํ•ด ์‹œ์Šคํ…œ์„ ์†์ด๋Š” ๊ฒƒ.
  • ๋ฉ”์ปค๋‹ˆ์ฆ˜ ์„ธ๋ถ€:
  • ๋กœ์ปฌ ์‹ ๋ขฐ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋‚˜ ์ธ์ฆ์„œ ์บ์‹œ๋ฅผ ์‹ ๋ขฐํ•˜๋Š” ๋Œ€์‹ , CoreTrust๋Š” Apple์˜ ๋ฃจํŠธ๋ฅผ ์ง์ ‘ ์ฐธ์กฐํ•˜๊ฑฐ๋‚˜ ๋ณด์•ˆ ์ฒด์ธ์—์„œ ์ค‘๊ฐ„ ์ธ์ฆ์„œ๋ฅผ ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค.
  • ๊ธฐ์กด ๋ฐ”์ด๋„ˆ๋ฆฌ์— ๋Œ€ํ•œ ํŒŒ์ผ์‹œ์Šคํ…œ ์ƒ์˜ ๋ณ€๊ฒฝ(์˜ˆ: ํŒจ์น˜)์„ ๊ฐ์ง€ํ•˜๊ณ  ๊ฑฐ๋ถ€ํ•ฉ๋‹ˆ๋‹ค.
  • entitlements, team IDs, ์ฝ”๋“œ ์„œ๋ช… ํ”Œ๋ž˜๊ทธ ๋ฐ ๊ธฐํƒ€ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ๋กœ๋“œ ์‹œ์ ์— ๋ฐ”์ด๋„ˆ๋ฆฌ์™€ ์—ฐ๊ณ„ํ•ฉ๋‹ˆ๋‹ค.
์˜ˆ์‹œ ํƒˆ์˜ฅ ์‹œ๋„๊ฐ€ `SpringBoard`๋‚˜ `libsystem`์„ ํŒจ์น˜๋œ ๋ฒ„์ „์œผ๋กœ ๊ต์ฒดํ•ด ์˜์†์„ฑ์„ ์–ป์œผ๋ ค ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ OS์˜ ๋กœ๋”๋‚˜ CoreTrust๊ฐ€ ๊ฒ€์‚ฌํ•˜๋ฉด ์„œ๋ช… ๋ถˆ์ผ์น˜(๋˜๋Š” ๋ณ€๊ฒฝ๋œ entitlements)๋ฅผ ๊ฐ์ง€ํ•˜๊ณ  ์‹คํ–‰์„ ๊ฑฐ๋ถ€ํ•ฉ๋‹ˆ๋‹ค.

3. Data Execution Prevention (DEP / NX / W^X)

Introduced in many OSes earlier; iOS had NX-bit / w^x for a long time DEP๋Š” ์“ฐ๊ธฐ ๊ฐ€๋Šฅํ•œ(๋ฐ์ดํ„ฐ) ํŽ˜์ด์ง€๋Š” ์‹คํ–‰ ๋ถˆ๊ฐ€, ์‹คํ–‰ ๊ฐ€๋Šฅํ•œ ํŽ˜์ด์ง€๋Š” ์“ฐ๊ธฐ๊ฐ€ ๋ถˆ๊ฐ€ํ•˜๋„๋ก ๊ฐ•์ œํ•ฉ๋‹ˆ๋‹ค. ํž™์ด๋‚˜ ์Šคํƒ ์˜์—ญ์— shellcode๋ฅผ ์“ฐ๊ณ  ์‹คํ–‰ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

  • ์ฐจ๋‹จ ๋Œ€์ƒ: ์ง์ ‘์ ์ธ shellcode ์‹คํ–‰; ๊ณ ์ „์ ์ธ ๋ฒ„ํผ ์˜ค๋ฒ„ํ”Œ๋กœ โ†’ ์ฃผ์ž…๋œ shellcode๋กœ ์ ํ”„.
  • ๋ฉ”์ปค๋‹ˆ์ฆ˜ ์„ธ๋ถ€:
  • MMU / ๋ฉ”๋ชจ๋ฆฌ ๋ณดํ˜ธ ํ”Œ๋ž˜๊ทธ(ํŽ˜์ด์ง€ ํ…Œ์ด๋ธ” ํ†ตํ•ด)๊ฐ€ ๋ถ„๋ฆฌ๋ฅผ ๊ฐ•์ œํ•ฉ๋‹ˆ๋‹ค.
  • writable ํŽ˜์ด์ง€๋ฅผ executable๋กœ ํ‘œ์‹œํ•˜๋ ค๋Š” ์‹œ๋„๋Š” ์‹œ์Šคํ…œ ๊ฒ€์‚ฌ๋ฅผ ํŠธ๋ฆฌ๊ฑฐํ•˜๋ฉฐ(๊ธˆ์ง€๋˜๊ฑฐ๋‚˜ ์ฝ”๋“œ ์„œ๋ช… ์Šน์ธ์ด ํ•„์š”).
  • ๋งŽ์€ ๊ฒฝ์šฐ, ํŽ˜์ด์ง€๋ฅผ executable๋กœ ๋งŒ๋“œ๋Š” ๊ฒƒ์€ ์ถ”๊ฐ€ ์ œ์•ฝ์ด๋‚˜ ๊ฒ€์‚ฌ๋ฅผ ์‹œํ–‰ํ•˜๋Š” OS API๋ฅผ ํ†ตํ•ด์„œ๋งŒ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
์˜ˆ์‹œ ์˜ค๋ฒ„ํ”Œ๋กœ๊ฐ€ ํž™์— shellcode๋ฅผ ์”๋‹ˆ๋‹ค. ๊ณต๊ฒฉ์ž๋Š” `mprotect(heap_addr, size, PROT_EXEC)`๋ฅผ ์‹œ๋„ํ•ด ๊ทธ๊ฒƒ์„ ์‹คํ–‰ ๊ฐ€๋Šฅ์œผ๋กœ ๋งŒ๋“ค๋ ค ํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์‹œ์Šคํ…œ์€ ๊ฑฐ๋ถ€ํ•˜๊ฑฐ๋‚˜ ์ƒˆ๋กœ์šด ํŽ˜์ด์ง€๊ฐ€ code-sign ์ œ์•ฝ์„ ํ†ต๊ณผํ•ด์•ผ ํ•œ๋‹ค๊ณ  ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค(์ฆ‰, shellcode๋Š” ํ†ต๊ณผ ๋ถˆ๊ฐ€).

4. Address Space Layout Randomization (ASLR)

Introduced in iOS ~4โ€“5 era (roughly iOS 4โ€“5 timeframe) ASLR์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ, heap, stack ๋“ฑ ์ฃผ์š” ๋ฉ”๋ชจ๋ฆฌ ์˜์—ญ์˜ ๋ฒ ์ด์Šค ์ฃผ์†Œ๋ฅผ ๊ฐ ํ”„๋กœ์„ธ์Šค ์‹คํ–‰๋งˆ๋‹ค ๋ฌด์ž‘์œ„ํ™”ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ€์ ฏ์˜ ์ฃผ์†Œ๋Š” ์‹คํ–‰ ๊ฐ„์— ๋ฐ”๋€๋‹ˆ๋‹ค.

  • ์ฐจ๋‹จ ๋Œ€์ƒ: ROP/JOP ๊ฐ€์ ฏ ์ฃผ์†Œ ํ•˜๋“œ์ฝ”๋”ฉ; ์ •์  ์ต์Šคํ”Œ๋กœ์ž‡ ์ฒด์ธ; ์•Œ๋ ค์ง„ ์˜คํ”„์…‹์œผ๋กœ์˜ ๋ธ”๋ผ์ธ๋“œ ์ ํ”„.
  • ๋ฉ”์ปค๋‹ˆ์ฆ˜ ์„ธ๋ถ€:
  • ๋กœ๋“œ๋œ ๊ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ / ๋™์  ๋ชจ๋“ˆ์€ ๋ฌด์ž‘์œ„ ์˜คํ”„์…‹์œผ๋กœ rebased ๋ฉ๋‹ˆ๋‹ค.
  • ์Šคํƒ๊ณผ ํž™์˜ ๋ฒ ์ด์Šค ํฌ์ธํ„ฐ๋Š”(์ผ์ •ํ•œ ์—”ํŠธ๋กœํ”ผ ํ•œ๋„ ๋‚ด์—์„œ) ๋ฌด์ž‘์œ„ํ™”๋ฉ๋‹ˆ๋‹ค.
  • ๋•Œ๋กœ๋Š” mmap ํ• ๋‹น ๋“ฑ ๋‹ค๋ฅธ ์˜์—ญ๋„ ๋ฌด์ž‘์œ„ํ™”๋ฉ๋‹ˆ๋‹ค.
  • ์ •๋ณด-๋ˆ„์ถœ(leak) ์™„ํ™”์™€ ๊ฒฐํ•ฉ๋˜์–ด, ๊ณต๊ฒฉ์ž๋Š” ๋Ÿฐํƒ€์ž„์— ์ฃผ์†Œ๋‚˜ ํฌ์ธํ„ฐ๋ฅผ ๋จผ์ € leakํ•ด์•ผ ๋ฒ ์ด์Šค ์ฃผ์†Œ๋ฅผ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์˜ˆ์‹œ ROP ์ฒด์ธ์€ `0xโ€ฆ.lib + offset`์— ์žˆ๋Š” ๊ฐ€์ ฏ์„ ๊ธฐ๋Œ€ํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ `lib`๊ฐ€ ๋งค ์‹คํ–‰๋งˆ๋‹ค ๋‹ค๋ฅธ ๊ณณ์œผ๋กœ relocated ๋˜๋ฏ€๋กœ ํ•˜๋“œ์ฝ”๋”ฉ๋œ ์ฒด์ธ์€ ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค. ์ต์Šคํ”Œ๋กœ์ž‡์€ ๋ชจ๋“ˆ์˜ ๋ฒ ์ด์Šค ์ฃผ์†Œ๋ฅผ leakํ•œ ๋’ค ๊ฐ€์ ฏ ์ฃผ์†Œ๋ฅผ ๊ณ„์‚ฐํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

5. Kernel Address Space Layout Randomization (KASLR)

Introduced in iOS ~ (iOS 5 / iOS 6 timeframe) ์œ ์ € ASLR๊ณผ ์œ ์‚ฌํ•˜๊ฒŒ, KASLR์€ ๋ถ€ํŒ… ์‹œ ์ปค๋„ ํ…์ŠคํŠธ ๋ฐ ๊ธฐํƒ€ ์ปค๋„ ๊ตฌ์กฐ์˜ ๋ฒ ์ด์Šค๋ฅผ ๋ฌด์ž‘์œ„ํ™”ํ•ฉ๋‹ˆ๋‹ค.

  • ์ฐจ๋‹จ ๋Œ€์ƒ: ์ปค๋„ ์ฝ”๋“œ๋‚˜ ๋ฐ์ดํ„ฐ์˜ ๊ณ ์ • ์œ„์น˜์— ์˜์กดํ•˜๋Š” ์ปค๋„ ์ˆ˜์ค€ ์ต์Šคํ”Œ๋กœ์ž‡; ์ •์  ์ปค๋„ ์ต์Šคํ”Œ๋กœ์ž‡.
  • ๋ฉ”์ปค๋‹ˆ์ฆ˜ ์„ธ๋ถ€:
  • ๊ฐ ๋ถ€ํŒ…๋งˆ๋‹ค ์ปค๋„ ๋ฒ ์ด์Šค ์ฃผ์†Œ๊ฐ€ ๋ฌด์ž‘์œ„ํ™”๋ฉ๋‹ˆ๋‹ค(๋ฒ”์œ„ ๋‚ด).
  • task_structs, vm_map ๊ฐ™์€ ์ปค๋„ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋„ ์žฌ๋ฐฐ์น˜๋˜๊ฑฐ๋‚˜ ์˜คํ”„์…‹์ด ์ ์šฉ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๊ณต๊ฒฉ์ž๋Š” ๋จผ์ € ์ปค๋„ ํฌ์ธํ„ฐ๋ฅผ leakํ•˜๊ฑฐ๋‚˜ ์ •๋ณด ๊ณต๊ฐœ ์ทจ์•ฝ์ ์„ ์ด์šฉํ•ด ์˜คํ”„์…‹์„ ๊ณ„์‚ฐํ•ด์•ผ ์ปค๋„ ๊ตฌ์กฐ๋‚˜ ์ฝ”๋“œ๋ฅผ ์ œ์–ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์˜ˆ์‹œ ๋กœ์ปฌ ์ทจ์•ฝ์ ์ด ์ปค๋„ ํ•จ์ˆ˜ ํฌ์ธํ„ฐ(์˜ˆ: `vtable` ๋‚ด๋ถ€)๋ฅผ `KERN_BASE + offset`์—์„œ ์†์ƒ์‹œํ‚ค๋ ค ํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ `KERN_BASE`๋ฅผ ์•Œ ์ˆ˜ ์—†์œผ๋ฏ€๋กœ ๊ณต๊ฒฉ์ž๋Š” ๋จผ์ € ์ด๋ฅผ leak(์˜ˆ: read primitive)ํ•œ ๋’ค ์˜ฌ๋ฐ”๋ฅธ ์ฃผ์†Œ๋ฅผ ๊ณ„์‚ฐํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

6. Kernel Patch Protection (KPP / AMCC)

Introduced in newer iOS / A-series hardware (post around iOS 15โ€“16 era or newer chips) KPP(aka AMCC)๋Š” ์ปค๋„ ํ…์ŠคํŠธ ํŽ˜์ด์ง€์˜ ๋ฌด๊ฒฐ์„ฑ์„ ์ง€์†์ ์œผ๋กœ ๋ชจ๋‹ˆํ„ฐ๋ง(ํ•ด์‹œ ๋˜๋Š” ์ฒดํฌ์„ฌ์„ ํ†ตํ•ด)ํ•ฉ๋‹ˆ๋‹ค. ํ—ˆ์šฉ๋œ ์ฐฝ(window) ์™ธ์—์„œ ํŒจ์น˜(์ธ๋ผ์ธ ํ›…, ์ฝ”๋“œ ์ˆ˜์ •)๊ฐ€ ๊ฐ์ง€๋˜๋ฉด ์ปค๋„ ํŒจ๋‹‰์ด๋‚˜ ์žฌ๋ถ€ํŒ…์„ ํŠธ๋ฆฌ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.

  • ์ฐจ๋‹จ ๋Œ€์ƒ: ์˜์†์ ์ธ ์ปค๋„ ํŒจ์นญ(์ปค๋„ ๋ช…๋ น์–ด ์ˆ˜์ •), ์ธ๋ผ์ธ ํ›…, ์ •์  ํ•จ์ˆ˜ ๋ฎ์–ด์“ฐ๊ธฐ.
  • ๋ฉ”์ปค๋‹ˆ์ฆ˜ ์„ธ๋ถ€:
  • ํ•˜๋“œ์›จ์–ด ๋˜๋Š” ํŽŒ์›จ์–ด ๋ชจ๋“ˆ์ด ์ปค๋„ ํ…์ŠคํŠธ ์˜์—ญ์„ ๋ชจ๋‹ˆํ„ฐํ•ฉ๋‹ˆ๋‹ค.
  • ์ฃผ๊ธฐ์ ์œผ๋กœ ๋˜๋Š” ํ•„์š” ์‹œ ํŽ˜์ด์ง€๋ฅผ ๋‹ค์‹œ ํ•ด์‹œํ•˜์—ฌ ๊ธฐ๋Œ€๊ฐ’๊ณผ ๋น„๊ตํ•ฉ๋‹ˆ๋‹ค.
  • ํ—ˆ์šฉ๋œ ์—…๋ฐ์ดํŠธ ์ฐฝ ์™ธ์—์„œ ๋ถˆ์ผ์น˜๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ๊ธฐ๊ธฐ๋ฅผ ํŒจ๋‹‰์‹œ์ผœ(์•…์„ฑ ์ง€์†์„ ๋ฐฉ์ง€) ์žฌ๋ถ€ํŒ…ํ•ฉ๋‹ˆ๋‹ค.
  • ๊ณต๊ฒฉ์ž๋Š” ํƒ์ง€ ์ฐฝ์„ ํ”ผํ•˜๊ฑฐ๋‚˜ ํ•ฉ๋ฒ•์ ์ธ ํŒจ์น˜ ๊ฒฝ๋กœ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
์˜ˆ์‹œ ์ต์Šคํ”Œ๋กœ์ž‡์ด ์ปค๋„ ํ•จ์ˆ˜ ํ”„๋กœ๋กœ๊ทธ(์˜ˆ: `memcmp`)๋ฅผ ํŒจ์น˜ํ•ด ํ˜ธ์ถœ์„ ๊ฐ€๋กœ์ฑ„๋ ค ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ KPP๋Š” ์ฝ”๋“œ ํŽ˜์ด์ง€์˜ ํ•ด์‹œ๊ฐ€ ์˜ˆ์ƒ๊ฐ’๊ณผ ์ผ์น˜ํ•˜์ง€ ์•Š์Œ์„ ๊ฐ์ง€ํ•˜๊ณ  ์ปค๋„ ํŒจ๋‹‰์„ ์œ ๋ฐœํ•ด ํŒจ์น˜๊ฐ€ ์•ˆ์ •ํ™”๋˜๊ธฐ ์ „์— ๊ธฐ๊ธฐ๋ฅผ ํฌ๋ž˜์‹œ์‹œํ‚ต๋‹ˆ๋‹ค.

7. Kernel Text Readโ€Only Region (KTRR)

Introduced in modern SoCs (post ~A12 / newer hardware) KTRR๋Š” ํ•˜๋“œ์›จ์–ด๋กœ ๊ฐ•์ œ๋˜๋Š” ๋ฉ”์ปค๋‹ˆ์ฆ˜์œผ๋กœ: ๋ถ€ํŠธ ์ดˆ๊ธฐ์— ์ปค๋„ ํ…์ŠคํŠธ๊ฐ€ ์ž ๊ธฐ๋ฉด EL1(์ปค๋„)์—์„œ ํ•ด๋‹น ์ฝ”๋“œ ํŽ˜์ด์ง€๋“ค์— ๋Œ€ํ•ด ์“ฐ๊ธฐ ๊ธˆ์ง€๊ฐ€ ์„ค์ •๋ฉ๋‹ˆ๋‹ค.

  • ์ฐจ๋‹จ ๋Œ€์ƒ: ๋ถ€ํŒ… ํ›„ ์ปค๋„ ์ฝ”๋“œ ์ˆ˜์ •(์˜ˆ: ํŒจ์น˜, ์ธํ”Œ๋ ˆ์ด์Šค ์ฝ”๋“œ ์ฃผ์ž…) โ€” EL1 ๊ถŒํ•œ๋งŒ์œผ๋กœ๋Š” ๋ถˆ๊ฐ€๋Šฅ.
  • ๋ฉ”์ปค๋‹ˆ์ฆ˜ ์„ธ๋ถ€:
  • ๋ถ€ํŠธ(secure/bootloader ๋‹จ๊ณ„) ๋™์•ˆ ๋ฉ”๋ชจ๋ฆฌ ์ปจํŠธ๋กค๋Ÿฌ(๋˜๋Š” ๋ณด์•ˆ ํ•˜๋“œ์›จ์–ด ์œ ๋‹›)๊ฐ€ ์ปค๋„ ํ…์ŠคํŠธ๋ฅผ ํฌํ•จํ•˜๋Š” ๋ฌผ๋ฆฌ ํŽ˜์ด์ง€๋ฅผ read-only๋กœ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.
  • ์ต์Šคํ”Œ๋กœ์ž‡์ด ์ „์ฒด ์ปค๋„ ๊ถŒํ•œ์„ ์–ป๋”๋ผ๋„ ํ•ด๋‹น ํŽ˜์ด์ง€๋ฅผ ์จ์„œ ๋ช…๋ น์–ด๋ฅผ ํŒจ์น˜ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
  • ์ด๋ฅผ ๋ณ€๊ฒฝํ•˜๋ ค๋ฉด ๋ถ€ํŠธ ์ฒด์ธ์„ ์šฐํšŒํ•˜๊ฑฐ๋‚˜ KTRR ์ž์ฒด๋ฅผ ํƒ€๊นƒ์œผ๋กœ ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
์˜ˆ์‹œ ๊ถŒํ•œ ์ƒ์Šน ์ต์Šคํ”Œ๋กœ์ž‡์ด EL1๋กœ ์ ํ”„ํ•ด ์ปค๋„ ํ•จ์ˆ˜(์˜ˆ: `syscall` ํ•ธ๋“ค๋Ÿฌ)์— ํŠธ๋žจํด๋ฆฐ์„ ์“ฐ๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ KTRR์ด ํŽ˜์ด์ง€๋ฅผ read-only๋กœ ์ž ๊ถˆ ๋‘์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์“ฐ๊ธฐ๊ฐ€ ์‹คํŒจํ•˜๊ฑฐ๋‚˜ ํดํŠธ๋ฅผ ๋ฐœ์ƒ์‹œ์ผœ ํŒจ์น˜๊ฐ€ ์ ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

8. Pointer Authentication Codes (PAC)

Introduced with ARMv8.3 (hardware), Apple beginning with A12 / iOS ~12+

  • PAC๋Š” ํฌ์ธํ„ฐ ๊ฐ’(๋ฆฌํ„ด ์ฃผ์†Œ, ํ•จ์ˆ˜ ํฌ์ธํ„ฐ, ํŠน์ • ๋ฐ์ดํ„ฐ ํฌ์ธํ„ฐ)์˜ ๋ณ€์กฐ๋ฅผ ํƒ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ํฌ์ธํ„ฐ์˜ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ์ƒ์œ„ ๋น„ํŠธ์— ์ž‘์€ ์•”ํ˜ธํ™” ์„œ๋ช…(โ€œMACโ€)์„ ์‚ฝ์ž…ํ•˜๋Š” ํ•˜๋“œ์›จ์–ด ๊ธฐ๋Šฅ์œผ๋กœ ARMv8.3-A์—์„œ ๋„์ž…๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
  • ์„œ๋ช…(โ€œPACโ€)์€ ํฌ์ธํ„ฐ ๊ฐ’๊ณผ modifier(์ปจํ…์ŠคํŠธ ๊ฐ’, ์˜ˆ: ์Šคํƒ ํฌ์ธํ„ฐ๋‚˜ ๊ตฌ๋ถ„์ž)๋ฅผ ํ•จ๊ป˜ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋™์ผํ•œ ํฌ์ธํ„ฐ ๊ฐ’๋„ ์„œ๋กœ ๋‹ค๋ฅธ ์ปจํ…์ŠคํŠธ์—์„œ๋Š” ๋‹ค๋ฅธ PAC๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค.
  • ์‚ฌ์šฉ ์‹œ์ ์— ํฌ์ธํ„ฐ๋ฅผ ์—ญ์ฐธ์กฐํ•˜๊ฑฐ๋‚˜ ๋ถ„๊ธฐํ•˜๊ธฐ ์ „์— authenticate ๋ช…๋ น์–ด๊ฐ€ PAC๋ฅผ ๊ฒ€์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์œ ํšจํ•˜๋ฉด PAC๋Š” ์ œ๊ฑฐ๋˜๊ณ  ์ˆœ์ˆ˜ ํฌ์ธํ„ฐ๊ฐ€ ์–ป์–ด์ง‘๋‹ˆ๋‹ค; ์œ ํšจํ•˜์ง€ ์•Š์œผ๋ฉด ํฌ์ธํ„ฐ๊ฐ€ โ€œpoisonedโ€๋˜๊ฑฐ๋‚˜ ํดํŠธ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.
  • PAC๋ฅผ ์ƒ์„ฑ/๊ฒ€์ฆํ•˜๋Š” ํ‚ค๋Š” ํŠน๊ถŒ ๋ ˆ์ง€์Šคํ„ฐ(EL1, ์ปค๋„)์— ๋ณด๊ด€๋˜๋ฉฐ ์œ ์ € ๋ชจ๋“œ์—์„œ ์ง์ ‘ ์ฝ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
  • ๋งŽ์€ ์‹œ์Šคํ…œ์—์„œ ํฌ์ธํ„ฐ์˜ ๋ชจ๋“  64๋น„ํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ธฐ(์˜ˆ: 48๋น„ํŠธ ์ฃผ์†Œ ๊ณต๊ฐ„) ๋•Œ๋ฌธ์— ์ƒ์œ„ ๋น„ํŠธ ์—ฌ์œ  ๊ณต๊ฐ„์— PAC๋ฅผ ๋„ฃ์–ด๋„ ์œ ํšจ ์ฃผ์†Œ์—๋Š” ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

Architectural Basis & Key Types

  • ARMv8.3์€ ๋‹ค์„ฏ ๊ฐœ์˜ 128-bit ํ‚ค(๊ฐ๊ฐ ๋‘ ๊ฐœ์˜ 64-bit ์‹œ์Šคํ…œ ๋ ˆ์ง€์Šคํ„ฐ๋กœ ๊ตฌํ˜„)๋ฅผ ๋„์ž…ํ•ฉ๋‹ˆ๋‹ค.

  • APIAKey โ€” instruction pointers ์šฉ(๋„๋ฉ”์ธ โ€œIโ€, key A)

  • APIBKey โ€” ๋‘ ๋ฒˆ์งธ instruction pointer ํ‚ค(๋„๋ฉ”์ธ โ€œIโ€, key B)

  • APDAKey โ€” data pointers ์šฉ(๋„๋ฉ”์ธ โ€œDโ€, key A)

  • APDBKey โ€” data pointers ์šฉ(๋„๋ฉ”์ธ โ€œDโ€, key B)

  • APGAKey โ€” โ€œgenericโ€ ํ‚ค, ํฌ์ธํ„ฐ๊ฐ€ ์•„๋‹Œ ๋ฐ์ดํ„ฐ๋‚˜ ์ผ๋ฐ˜์  ์šฉ๋„ ์„œ๋ช…์šฉ

  • ์ด ํ‚ค๋“ค์€ ํŠน๊ถŒ ์‹œ์Šคํ…œ ๋ ˆ์ง€์Šคํ„ฐ(EL1/EL2 ๋“ฑ) ์•ˆ์— ์ €์žฅ๋˜์–ด ์œ ์ € ๋ชจ๋“œ์—์„œ ์ ‘๊ทผ ๋ถˆ๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

  • PAC๋Š” ์•”ํ˜ธํ™” ํ•จ์ˆ˜(ARM์€ QARMA๋ฅผ ์ œ์•ˆ)๋กœ ๊ณ„์‚ฐ๋˜๋ฉฐ ์ž…๋ ฅ์€:

  1. ํฌ์ธํ„ฐ ๊ฐ’(์ •๊ทœํ™”๋œ ๋ถ€๋ถ„)
  2. modifier(์ปจํ…์ŠคํŠธ ๊ฐ’, ์˜ˆ: salt)
  3. ๋น„๋ฐ€ ํ‚ค
  4. ๋‚ด๋ถ€ ํŠธ์œ… ๋กœ์ง ๊ฒฐ๊ณผ PAC๊ฐ€ ํฌ์ธํ„ฐ ์ƒ์œ„ ๋น„ํŠธ์— ์ €์žฅ๋œ ๊ฐ’๊ณผ ์ผ์น˜ํ•˜๋ฉด ์ธ์ฆ ์„ฑ๊ณต์ž…๋‹ˆ๋‹ค.

Instruction Families

๋ช…๋ช… ๊ทœ์น™์€: PAC / AUT / XPAC, ๊ทธ ๋‹ค์Œ ๋„๋ฉ”์ธ ๋ฌธ์ž์ž…๋‹ˆ๋‹ค.

  • PACxx ๋ช…๋ น์–ด๋Š” ํฌ์ธํ„ฐ์— ์„œ๋ช…ํ•˜์—ฌ PAC๋ฅผ ์‚ฝ์ž…ํ•ฉ๋‹ˆ๋‹ค.
  • AUTxx ๋ช…๋ น์–ด๋Š” ์ธ์ฆ + ์ œ๊ฑฐ(PAC ๊ฒ€์ฆ ๋ฐ ์ œ๊ฑฐ)๋ฅผ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.
  • XPACxx ๋ช…๋ น์–ด๋Š” ๊ฒ€์ฆ ์—†์ด PAC๋ฅผ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.

๋„๋ฉ”์ธ / ์ ‘๋ฏธ์‚ฌ:

MnemonicMeaning / DomainKey / DomainExample Usage in Assembly
PACIASign instruction pointer with APIAKeyโ€œI, Aโ€PACIA X0, X1 โ€” sign pointer in X0 using APIAKey with modifier X1
PACIBSign instruction pointer with APIBKeyโ€œI, Bโ€PACIB X2, X3
PACDASign data pointer with APDAKeyโ€œD, Aโ€PACDA X4, X5
PACDBSign data pointer with APDBKeyโ€œD, Bโ€PACDB X6, X7
PACG / PACGAGeneric (non-pointer) signing with APGAKeyโ€œGโ€PACGA X8, X9, X10 (sign X9 with modifier X10 into X8)
AUTIAAuthenticate APIA-signed instruction pointer & strip PACโ€œI, Aโ€AUTIA X0, X1 โ€” check PAC on X0 using modifier X1, then strip
AUTIBAuthenticate APIB domainโ€œI, Bโ€AUTIB X2, X3
AUTDAAuthenticate APDA-signed data pointerโ€œD, Aโ€AUTDA X4, X5
AUTDBAuthenticate APDB-signed data pointerโ€œD, Bโ€AUTDB X6, X7
AUTGAAuthenticate generic / blob (APGA)โ€œGโ€AUTGA X8, X9, X10 (validate generic)
XPACIStrip PAC (instruction pointer, no validation)โ€œIโ€XPACI X0 โ€” remove PAC from X0 (instruction domain)
XPACDStrip PAC (data pointer, no validation)โ€œDโ€XPACD X4 โ€” remove PAC from data pointer in X4

ํŠน์ˆ˜ํ™”๋œ / ๋ณ„์นญ ํ˜•ํƒœ๋“ค๋„ ์žˆ์Šต๋‹ˆ๋‹ค:

  • PACIASP๋Š” PACIA X30, SP์˜ ์ถ•์•ฝํ˜•(๋งํฌ ๋ ˆ์ง€์Šคํ„ฐ๋ฅผ SP๋ฅผ modifier๋กœ ์„œ๋ช…)
  • AUTIASP๋Š” AUTIA X30, SP(๋งํฌ ๋ ˆ์ง€์Šคํ„ฐ๋ฅผ SP๋กœ ์ธ์ฆ)
  • RETAA, RETAB(์ธ์ฆ ํ›„ ๋ฐ˜ํ™˜)๋‚˜ BLRAA(์ธ์ฆ ํ›„ ๋ถ„๊ธฐ) ๊ฐ™์€ ๊ฒฐํ•ฉํ˜•์ด ARM ํ™•์žฅ/์ปดํŒŒ์ผ๋Ÿฌ ์ง€์›์— ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.
  • modifier๊ฐ€ 0์œผ๋กœ ์•”๋ฌต์ ์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ์ œ๋กœ-๋ชจ๋””ํŒŒ์ด์–ด ๋ณ€ํ˜•๋“ค: PACIZA / PACIZB ๋“ฑ๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

Modifiers

modifier์˜ ์ฃผ๋œ ๋ชฉ์ ์€ PAC๋ฅผ ํŠน์ • ์ปจํ…์ŠคํŠธ์— ๋ฐ”์ธ๋”ฉํ•ด ๋™์ผํ•œ ์ฃผ์†Œ๊ฐ€ ๋‹ค๋ฅธ ์ปจํ…์ŠคํŠธ์—์„œ ์žฌ์‚ฌ์šฉ๋˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ•ด์‹œ์— salt๋ฅผ ๋”ํ•˜๋Š” ๊ฒƒ๊ณผ ์œ ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ:

  • modifier๋Š” ์ปจํ…์ŠคํŠธ ๊ฐ’(๋‹ค๋ฅธ ๋ ˆ์ง€์Šคํ„ฐ)์œผ๋กœ PAC ๊ณ„์‚ฐ์— ํ˜ผํ•ฉ๋ฉ๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์ธ ์„ ํƒ: stack pointer(SP), frame pointer, ๊ฐ์ฒด ID ๋“ฑ.
  • SP๋ฅผ modifier๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ๋ฆฌํ„ด ์ฃผ์†Œ ์„œ๋ช…์— ํ”ํžˆ ์“ฐ์ž…๋‹ˆ๋‹ค: PAC๋Š” ํŠน์ • ์Šคํƒ ํ”„๋ ˆ์ž„์— ๋ฌถ์ด๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ํ”„๋ ˆ์ž„์—์„œ LR์„ ์žฌ์‚ฌ์šฉํ•˜๋ฉด modifier๊ฐ€ ๋‹ฌ๋ผ PAC ๊ฒ€์ฆ์ด ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค.
  • ๋™์ผํ•œ ํฌ์ธํ„ฐ ๊ฐ’์ด๋ผ๋„ ๋‹ค๋ฅธ modifier๋กœ ์„œ๋ช…ํ•˜๋ฉด ๋‹ค๋ฅธ PAC๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.
  • modifier๋Š” ๋ฐ˜๋“œ์‹œ ๋น„๋ฐ€์ผ ํ•„์š”๋Š” ์—†์ง€๋งŒ ์ด์ƒ์ ์œผ๋กœ๋Š” ๊ณต๊ฒฉ์ž๊ฐ€ ์ œ์–ดํ•  ์ˆ˜ ์—†๋Š” ๊ฐ’์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • ์˜๋ฏธ ์žˆ๋Š” modifier๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ ์ผ๋ถ€ ๋ช…๋ น์€ 0์ด๋‚˜ ์•”๋ฌต ์ƒ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

Apple / iOS / XNU Customizations & Observations

  • Apple์˜ PAC ๊ตฌํ˜„์€ ๋ถ€ํŒ…๋ณ„ diversifiers๋ฅผ ํฌํ•จํ•˜์—ฌ ๋ถ€ํŒ…๋งˆ๋‹ค ํ‚ค๋‚˜ ํŠธ์œ…์ด ๋ณ€๊ฒฝ๋˜์–ด ๋ถ€ํŒ… ๊ฐ„ ์žฌ์‚ฌ์šฉ์„ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค.
  • ๋˜ํ•œ PAC๊ฐ€ ์œ ์ € ๋ชจ๋“œ์—์„œ ์„œ๋ช…๋œ ๊ฐ’์„ ์ปค๋„ ๋ชจ๋“œ์—์„œ ์‰ฝ๊ฒŒ ์žฌ์‚ฌ์šฉํ•˜์ง€ ๋ชปํ•˜๋„๋ก ํ•˜๋Š” ๊ต์ฐจ ๋„๋ฉ”์ธ ์™„ํ™”๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.
  • Apple Silicon(M1) ๋ฆฌ๋ฒ„์Šค ์—”์ง€๋‹ˆ์–ด๋ง์—์„œ 9๊ฐ€์ง€ modifier ํƒ€์ž…๊ณผ Apple ์ „์šฉ ํ‚ค ์ œ์–ด ์‹œ์Šคํ…œ ๋ ˆ์ง€์Šคํ„ฐ๊ฐ€ ์žˆ๋Š” ๊ฒƒ์œผ๋กœ ๋“œ๋Ÿฌ๋‚ฌ์Šต๋‹ˆ๋‹ค.
  • Apple์€ return address signing, ์ปค๋„ ๋ฐ์ดํ„ฐ์˜ ํฌ์ธํ„ฐ ๋ฌด๊ฒฐ์„ฑ, ์„œ๋ช…๋œ ์Šค๋ ˆ๋“œ ์ปจํ…์ŠคํŠธ ๋“ฑ ๋งŽ์€ ์ปค๋„ ์„œ๋ธŒ์‹œ์Šคํ…œ์— PAC๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • Google Project Zero๋Š” ๊ฐ•๋ ฅํ•œ ๋ฉ”๋ชจ๋ฆฌ ์ฝ๊ธฐ/์“ฐ๊ธฐ ํ”„๋ฆฌ๋ฏธํ‹ฐ๋ธŒ๊ฐ€ ์žˆ์„ ๊ฒฝ์šฐ(์ปค๋„์—์„œ) A ํ‚ค๋กœ ์ปค๋„ PAC๋ฅผ ์œ„์กฐํ•  ์ˆ˜ ์žˆ์Œ์„ ๋ณด์—ฌ์ฃผ์—ˆ๊ณ (A12-era ์žฅ์น˜), Apple์€ ๋งŽ์€ ๊ฒฝ๋กœ๋ฅผ ํŒจ์น˜ํ–ˆ์Šต๋‹ˆ๋‹ค.
  • Apple ์‹œ์Šคํ…œ์—์„œ๋Š” ์ผ๋ถ€ ํ‚ค๊ฐ€ ์ปค๋„ ์ „์ฒด์—์„œ ๊ธ€๋กœ๋ฒŒ์ด๊ณ , ์‚ฌ์šฉ์ž ํ”„๋กœ์„ธ์Šค๋Š” ํ”„๋กœ์„ธ์Šค๋ณ„ ํ‚ค ๋ฌด์ž‘์œ„์„ฑ์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

PAC Bypasses

  1. Kernel-mode PAC: theoretical vs real bypasses
  • ์ปค๋„ PAC ํ‚ค์™€ ๋กœ์ง์€ ์—„๊ฒฉํžˆ ์ œ์–ด๋˜๋ฏ€๋กœ(ํŠน๊ถŒ ๋ ˆ์ง€์Šคํ„ฐ, diversifier, ๋„๋ฉ”์ธ ๋ถ„๋ฆฌ) ์ž„์˜์˜ ์„œ๋ช…๋œ ์ปค๋„ ํฌ์ธํ„ฐ๋ฅผ ์œ„์กฐํ•˜๋Š” ๊ฒƒ์€ ๋งค์šฐ ์–ด๋ ต์Šต๋‹ˆ๋‹ค.
  • Azad์˜ 2020 โ€œiOS Kernel PAC, One Year Laterโ€œ๋Š” iOS 12-13์—์„œ ๋ช‡๋ช‡ ๋ถ€๋ถ„์  ์šฐํšŒ(์„œ๋ช… ๊ฐ€์ ฏ ์žฌ์‚ฌ์šฉ, ์„œ๋ช…๋œ ์ƒํƒœ ์žฌ์‚ฌ์šฉ, ๋ณดํ˜ธ๋˜์ง€ ์•Š์€ ๊ฐ„์ ‘ ๋ถ„๊ธฐ)๋ฅผ ์ฐพ์•˜์ง€๋งŒ ์™„์ „ํ•œ ์ผ๋ฐ˜์  ์šฐํšŒ๋Š” ์—†์—ˆ๋‹ค๊ณ  ๋ณด๊ณ ํ•ฉ๋‹ˆ๋‹ค. bazad.github.io
  • Apple์˜ โ€œDark Magicโ€ ์ปค์Šคํ„ฐ๋งˆ์ด์ฆˆ๋Š” exploitable surface๋ฅผ ๋” ์ขํ˜”์Šต๋‹ˆ๋‹ค(๋„๋ฉ”์ธ ์ „ํ™˜, ํ‚ค๋ณ„ ํ™œ์„ฑํ™” ๋น„ํŠธ). i.blackhat.com
  • Apple silicon(M1/M2)์—์„œ ์•Œ๋ ค์ง„ ์ปค๋„ PAC ์šฐํšŒ CVE-2023-32424๊ฐ€ Zecao Cai ๋“ฑ์—๊ฒŒ ๋ณด๊ณ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. i.blackhat.com
  • ํ•˜์ง€๋งŒ ์ด๋Ÿฌํ•œ ์šฐํšŒ๋Š” ์ข…์ข… ๋งค์šฐ ํŠน์ •ํ•œ ๊ฐ€์ ฏ์ด๋‚˜ ๊ตฌํ˜„ ๋ฒ„๊ทธ์— ์˜์กดํ•˜๋ฉฐ, ์ผ๋ฐ˜ ๋ชฉ์ ์˜ ์šฐํšŒ๋Š” ์•„๋‹™๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ์ปค๋„ PAC๋Š” ๋งค์šฐ ๊ฒฌ๊ณ ํ•œ ๋ณดํ˜ธ๋กœ ๊ฐ„์ฃผ๋˜์ง€๋งŒ ์™„๋ฒฝํ•˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค.

  1. User-mode / runtime PAC bypass techniques

์œ ์ € ๋ชจ๋“œ ์ชฝ ์šฐํšŒ๊ฐ€ ๋” ํ”ํ•˜๋ฉฐ, PAC๊ฐ€ ๋™์  ๋งํฌ/๋Ÿฐํƒ€์ž„ ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ์ ์šฉ๋˜๋Š” ๋ถˆ์™„์ „ํ•จ์„ ์•…์šฉํ•ฉ๋‹ˆ๋‹ค. ์•„๋ž˜๋Š” ๋ถ„๋ฅ˜์™€ ์˜ˆ์‹œ์ž…๋‹ˆ๋‹ค.

2.1 Shared Cache / A key issues

  • dyld shared cache๋Š” ์‹œ์Šคํ…œ ํ”„๋ ˆ์ž„์›Œํฌ์™€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ํฐ ์‚ฌ์ „ ๋งํฌ๋œ ๋ธ”๋ž์ž…๋‹ˆ๋‹ค. ๋„๋ฆฌ ๊ณต์œ ๋˜๊ธฐ ๋•Œ๋ฌธ์— shared cache ๋‚ด๋ถ€์˜ ํ•จ์ˆ˜ ํฌ์ธํ„ฐ๋Š” ์ด๋ฏธ ์„œ๋ช…๋˜์–ด ์—ฌ๋Ÿฌ ํ”„๋กœ์„ธ์Šค์—์„œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ๊ณต๊ฒฉ์ž๋Š” ์ด๋Ÿฌํ•œ ์ด๋ฏธ ์„œ๋ช…๋œ ํฌ์ธํ„ฐ๋“ค์„ โ€œPAC oracleโ€œ๋กœ ํ‘œ์ ํ™”ํ•ฉ๋‹ˆ๋‹ค.
  • ๋ช‡๋ช‡ ์šฐํšŒ ๊ธฐ๋ฒ•์€ shared cache์— ์กด์žฌํ•˜๋Š” A-key ์„œ๋ช… ํฌ์ธํ„ฐ๋ฅผ ์ถ”์ถœํ•˜๊ฑฐ๋‚˜ ์žฌ์‚ฌ์šฉํ•ด ์šฐํšŒํ•˜๋ ค ํ•ฉ๋‹ˆ๋‹ค.
  • โ€œNo Clicks Requiredโ€ ๋ฐœํ‘œ๋Š” shared cache ์œ„์— ์˜ค๋ผํด์„ ๊ตฌ์ถ•ํ•ด ์ƒ๋Œ€ ์ฃผ์†Œ๋ฅผ ์œ ์ถ”ํ•˜๊ณ  ์„œ๋ช…๋œ ํฌ์ธํ„ฐ์™€ ๊ฒฐํ•ฉํ•ด PAC๋ฅผ ์šฐํšŒํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. saelo.github.io
  • ๋˜ํ•œ ์œ ์ €์ŠคํŽ˜์ด์Šค์—์„œ shared libraries๋กœ๋ถ€ํ„ฐ ์ž„ํฌํŠธ๋œ ํ•จ์ˆ˜ ํฌ์ธํ„ฐ๊ฐ€ PAC๋กœ ์ถฉ๋ถ„ํžˆ ๋ณดํ˜ธ๋˜์ง€ ์•Š์•„ ๊ณต๊ฒฉ์ž๊ฐ€ ์„œ๋ช…์„ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๊ณ ๋„ ํ•จ์ˆ˜ ํฌ์ธํ„ฐ๋ฅผ ์–ป๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋ฐœ๊ฒฌ๋˜์—ˆ์Šต๋‹ˆ๋‹ค(Project Zero ๋ฒ„๊ทธ). bugs.chromium.org

2.2 dlsym(3) / dynamic symbol resolution

  • ์•Œ๋ ค์ง„ ์šฐํšŒ ์ค‘ ํ•˜๋‚˜๋Š” dlsym()์„ ํ˜ธ์ถœํ•ด ์ด๋ฏธ ์„œ๋ช…๋œ ํ•จ์ˆ˜ ํฌ์ธํ„ฐ(A-key๋กœ ์„œ๋ช…, diversifier zero)๋ฅผ ์–ป์–ด ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. dlsym์ด ํ•ฉ๋ฒ•์ ์œผ๋กœ ์„œ๋ช…๋œ ํฌ์ธํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด PAC๋ฅผ ์œ„์กฐํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.
  • Epsilon ๋ธ”๋กœ๊ทธ๋Š” ๋ช‡๋ช‡ ์šฐํšŒ๊ฐ€ ์ด๋ฅผ ์•…์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ž์„ธํžˆ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค: dlsym("someSym")์€ ์„œ๋ช…๋œ ํฌ์ธํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ  ๊ฐ„์ ‘ ํ˜ธ์ถœ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. blog.epsilon-sec.com
  • Synacktiv์˜ โ€œiOS 18.4 โ€” dlsym considered harmfulโ€œ๋Š” iOS 18.4์—์„œ dlsym์œผ๋กœ ํ•ด๊ฒฐ๋œ ์ผ๋ถ€ ์‹ฌ๋ณผ์ด ์ž˜๋ชป ์„œ๋ช…๋˜์—ˆ๊ฑฐ๋‚˜ diversifier์— ๋ฒ„๊ทธ๊ฐ€ ์žˆ์–ด ์˜๋„์น˜ ์•Š์€ PAC ์šฐํšŒ๋ฅผ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ–ˆ๋‹ค๋Š” ๋ฒ„๊ทธ๋ฅผ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. Synacktiv
  • dyld์˜ dlsym ๋กœ์ง์€: result->isCode์ผ ๋•Œ ๋ฐ˜ํ™˜๋œ ํฌ์ธํ„ฐ๋ฅผ __builtin_ptrauth_sign_unauthenticated(..., key_asia, 0)๋กœ ์„œ๋ช…ํ•œ๋‹ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค(์ฆ‰, ์ปจํ…์ŠคํŠธ 0). blog.epsilon-sec.com

๋”ฐ๋ผ์„œ dlsym์€ ์œ ์ €๋ชจ๋“œ PAC ์šฐํšŒ์—์„œ ์ž์ฃผ ์ด์šฉ๋˜๋Š” ๋ฒกํ„ฐ์ž…๋‹ˆ๋‹ค.

2.3 Other DYLD / runtime relocations

  • DYLD ๋กœ๋”์™€ ๋™์  ์žฌ๋ฐฐ์น˜ ๋กœ์ง์€ ๋ณต์žกํ•˜๊ณ  ๋•Œ๋กœ๋Š” ์žฌ๋ฐฐ์น˜๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ํŽ˜์ด์ง€๋ฅผ ์ผ์‹œ์ ์œผ๋กœ read/write๋กœ ๋งคํ•‘ํ•œ ๋’ค ๋‹ค์‹œ read-only๋กœ ๋ฐ”๊ฟ‰๋‹ˆ๋‹ค. ๊ณต๊ฒฉ์ž๋Š” ์ด๋Ÿฌํ•œ ์ฐฝ์„ ์•…์šฉํ•ฉ๋‹ˆ๋‹ค. Synacktiv์˜ ๋ฐœํ‘œ๋Š” ๋™์  ์žฌ๋ฐฐ์น˜๋ฅผ ํ†ตํ•œ ํƒ€์ด๋ฐ ๊ธฐ๋ฐ˜ PAC ์šฐํšŒ(โ€œOperation Triangulationโ€)๋ฅผ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. Synacktiv
  • DYLD ํŽ˜์ด์ง€๋Š” ์ด์ œ SPRR / VM_FLAGS_TPRO ๊ฐ™์€ ๋ณดํ˜ธ๋กœ ๋ณดํ˜ธ๋˜์ง€๋งŒ ์ด์ „ ๋ฒ„์ „์€ ๋” ์•ฝํ•œ ๋ณดํ˜ธ๋ฅผ ๊ฐ€์กŒ์Šต๋‹ˆ๋‹ค. Synacktiv
  • WebKit ์ต์Šคํ”Œ๋กœ์ž‡ ์ฒด์ธ์—์„œ๋Š” DYLD ๋กœ๋”๊ฐ€ PAC ์šฐํšŒ์˜ ํ‘œ์ ์ด ๋˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์Šต๋‹ˆ๋‹ค(์žฌ๋ฐฐ์น˜, interposer ํ›… ๋“ฑ์„ ํ†ตํ•ด). Synacktiv

2.4 NSPredicate / NSExpression / ObjC / SLOP

  • ์œ ์ €๋žœ๋“œ ์ต์Šคํ”Œ๋กœ์ž‡ ์ฒด์ธ์—์„œ๋Š” Objective-C ๋Ÿฐํƒ€์ž„ ๋ฉ”์„œ๋“œ๋“ค(NSPredicate, NSExpression, NSInvocation ๋“ฑ)์„ ์‚ฌ์šฉํ•ด ์ œ์–ด ํ๋ฆ„ ํ˜ธ์ถœ์„ ์€๋ฐ€ํžˆ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.
  • PAC ์ด์ „์˜ ์˜ค๋ž˜๋œ iOS์—์„œ๋Š” fake NSInvocation ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด ์ž„์˜์˜ ์…€๋ ‰ํ„ฐ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ธฐ๋ฒ•์ด ์‚ฌ์šฉ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. PAC๊ฐ€ ๋„์ž…๋˜๋ฉด์„œ ์ˆ˜์ •์ด ํ•„์š”ํ–ˆ์ง€๋งŒ SLOP(SeLector Oriented Programming) ๊ธฐ๋ฒ•์€ PAC ํ™˜๊ฒฝ์—์„œ๋„ ํ™•์žฅ๋˜์–ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. Project Zero
  • ์›๋ž˜ SLOP ๊ธฐ๋ฒ•์€ ๊ฐ€์งœ invocation์„ ๋งŒ๋“ค์–ด ObjC ํ˜ธ์ถœ์„ ์ฒด์ธํ™”ํ–ˆ๋Š”๋ฐ, ISA๋‚˜ selector ํฌ์ธํ„ฐ๊ฐ€ ํ•ญ์ƒ PAC๋กœ ์™„์ „ํžˆ ๋ณดํ˜ธ๋˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ ์šฐํšŒ๊ฐ€ ๊ฐ€๋Šฅํ–ˆ์Šต๋‹ˆ๋‹ค. Project Zero
  • ํฌ์ธํ„ฐ ์ธ์ฆ์ด ๋ถ€๋ถ„์ ์œผ๋กœ๋งŒ ์ ์šฉ๋˜๋Š” ํ™˜๊ฒฝ์—์„œ๋Š” method / selector / target ํฌ์ธํ„ฐ๊ฐ€ ํ•ญ์ƒ PAC ๋ณดํ˜ธ๋ฅผ ๋ฐ›์ง€ ์•Š์•„ ์šฐํšŒ ์—ฌ์ง€๊ฐ€ ์ƒ๊น๋‹ˆ๋‹ค.

์˜ˆ์‹œ ํ”Œ๋กœ์šฐ

์˜ˆ: ์„œ๋ช… ๋ฐ ์ธ์ฆ ``` ; Example: function prologue / return address protection my_func: stp x29, x30, [sp, #-0x20]! ; push frame pointer + LR mov x29, sp PACIASP ; sign LR (x30) using SP as modifier ; โ€ฆ body โ€ฆ mov sp, x29 ldp x29, x30, [sp], #0x20 ; restore AUTIASP ; authenticate & strip PAC ret

; Example: indirect function pointer stored in a struct ; suppose X1 contains a function pointer PACDA X1, X2 ; sign data pointer X1 with context X2 STR X1, [X0] ; store signed pointer

; later retrieval: LDR X1, [X0] AUTDA X1, X2 ; authenticate & strip BLR X1 ; branch to valid target

; Example: stripping for comparison (unsafe) LDR X1, [X0] XPACI X1 ; strip PAC (instruction domain) CMP X1, #some_label_address BEQ matched_label

</details>

<details>
<summary>Example</summary>
๋ฒ„ํผ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ๊ฐ€ ์Šคํƒ์˜ return address๋ฅผ ๋ฎ์–ด์“ด๋‹ค. ๊ณต๊ฒฉ์ž๋Š” ๋Œ€์ƒ gadget ์ฃผ์†Œ๋ฅผ ์“ด๋‹ค์ง€๋งŒ ์˜ฌ๋ฐ”๋ฅธ PAC๋ฅผ ๊ณ„์‚ฐํ•˜์ง€ ๋ชปํ•œ๋‹ค. ํ•จ์ˆ˜๊ฐ€ ๋ฐ˜ํ™˜๋  ๋•Œ CPU์˜ `AUTIA` ๋ช…๋ น์ด PAC ๋ถˆ์ผ์น˜๋กœ ์˜ˆ์™ธ๋ฅผ ์ผ์œผํ‚จ๋‹ค. ์ฒด์ธ์€ ์‹คํŒจํ•œ๋‹ค.
Project Zero์˜ A12 (iPhone XS) ๋ถ„์„์€ Apple์˜ PAC ์‚ฌ์šฉ ๋ฐฉ์‹๊ณผ, ๊ณต๊ฒฉ์ž๊ฐ€ memory read/write primitive๋ฅผ ๊ฐ€์งˆ ๋•Œ PAC์„ ์œ„์กฐํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ฃผ์—ˆ๋‹ค.
</details>


### 9. **Branch Target Identification (BTI)**
**Introduced with ARMv8.5 (later hardware)**
BTI๋Š” ๊ฐ„์ ‘ ๋ถ„๊ธฐ ๋Œ€์ƒ(indirect branch targets)์„ ๊ฒ€์‚ฌํ•˜๋Š” ํ•˜๋“œ์›จ์–ด ๊ธฐ๋Šฅ์ด๋‹ค: `blr` ๋˜๋Š” ๊ฐ„์ ‘ ํ˜ธ์ถœ/์ ํ”„๋ฅผ ์‹คํ–‰ํ•  ๋•Œ, ๋Œ€์ƒ์€ **BTI landing pad**(`BTI j` ๋˜๋Š” `BTI c`)๋กœ ์‹œ์ž‘ํ•ด์•ผ ํ•œ๋‹ค. landing pad๊ฐ€ ์—†๋Š” gadget ์ฃผ์†Œ๋กœ ์ ํ”„ํ•˜๋ฉด ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

LLVM์˜ ๊ตฌํ˜„ ๋…ธํŠธ๋Š” BTI ๋ช…๋ น์˜ ์„ธ ๊ฐ€์ง€ ๋ณ€ํ˜•๊ณผ ์ด๋“ค์ด ๋ถ„๊ธฐ ์œ ํ˜•์— ์–ด๋–ป๊ฒŒ ๋งคํ•‘๋˜๋Š”์ง€ ๊ธฐ์ˆ ํ•œ๋‹ค.

| BTI Variant | What it permits (which branch types) | Typical placement / use case |
|-------------|----------------------------------------|-------------------------------|
| **BTI C** | Targets of *call*-style indirect branches (e.g. `BLR`, or `BR` using X16/X17) | Put at entry of functions that may be called indirectly |
| **BTI J** | Targets of *jump*-style branches (e.g. `BR` used for tail calls) | Placed at the beginning of blocks reachable by jump tables or tail-calls |
| **BTI JC** | Acts as both C and J | Can be targeted by either call or jump branches |

- branch target enforcement๋กœ ์ปดํŒŒ์ผ๋œ ์ฝ”๋“œ์—์„œ๋Š” ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ๊ฐ ์œ ํšจํ•œ ๊ฐ„์ ‘-๋ถ„๊ธฐ ๋Œ€์ƒ(๊ฐ„์ ‘ ํ˜ธ์ถœ๋  ์ˆ˜ ์žˆ๋Š” ํ•จ์ˆ˜ ์‹œ์ž‘ ๋˜๋Š” ์ ํ”„๋กœ ๋„๋‹ฌ ๊ฐ€๋Šฅํ•œ ๋ธ”๋ก)์— BTI ๋ช…๋ น(C, J, ๋˜๋Š” JC)์„ ์‚ฝ์ž…ํ•˜์—ฌ, ๊ฐ„์ ‘ ๋ถ„๊ธฐ๊ฐ€ ์˜ค์ง ๊ทธ๋Ÿฌํ•œ ์œ„์น˜๋กœ๋งŒ ์„ฑ๊ณตํ•˜๋„๋ก ํ•œ๋‹ค.
- **Direct branches / calls**(์˜ˆ: ๊ณ ์ • ์ฃผ์†Œ `B`, `BL`)์€ BTI์˜ ์ œํ•œ์„ ๋ฐ›์ง€ ์•Š๋Š”๋‹ค. ์ด๋Š” ์ฝ”๋“œ ํŽ˜์ด์ง€๊ฐ€ ์‹ ๋ขฐ๋œ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๊ณ  ๊ณต๊ฒฉ์ž๊ฐ€ ์ด๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†์œผ๋ฏ€๋กœ(๋”ฐ๋ผ์„œ direct branches๋Š” ์•ˆ์ „ํ•˜๋‹ค๊ณ  ๊ฐ„์ฃผ)์ด๋‹ค.
- ๋˜ํ•œ, **RET / return** ๋ช…๋ น์€ ์ผ๋ฐ˜์ ์œผ๋กœ PAC ๋˜๋Š” return signing ๋ฉ”์ปค๋‹ˆ์ฆ˜์œผ๋กœ return ์ฃผ์†Œ๊ฐ€ ๋ณดํ˜ธ๋˜๊ธฐ ๋•Œ๋ฌธ์— BTI์˜ ์ œํ•œ์„ ๋ฐ›์ง€ ์•Š๋Š”๋‹ค.

#### Mechanism and enforcement

- CPU๊ฐ€ โ€œguarded / BTI-enabledโ€๋กœ ํ‘œ์‹œ๋œ ํŽ˜์ด์ง€์—์„œ **indirect branch (`BLR` / `BR`)**๋ฅผ ๋””์ฝ”๋“œํ•  ๋•Œ, ๋Œ€์ƒ ์ฃผ์†Œ์˜ ์ฒซ ๋ช…๋ น์ด ํ—ˆ์šฉ๋œ BTI(C, J, ๋˜๋Š” JC)์ธ์ง€ ๊ฒ€์‚ฌํ•œ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด **Branch Target Exception**์ด ๋ฐœ์ƒํ•œ๋‹ค.
- BTI ๋ช…๋ น ์ธ์ฝ”๋”ฉ์€ ์ด์ „ ARM ๋ฒ„์ „์—์„œ NOP๋กœ ์˜ˆ์•ฝ๋˜์—ˆ๋˜ opcode๋ฅผ ์žฌ์‚ฌ์šฉํ•˜๋„๋ก ์„ค๊ณ„๋˜์—ˆ๋‹ค. ๋”ฐ๋ผ์„œ BTI-enabled ๋ฐ”์ด๋„ˆ๋ฆฌ๋Š” BTI๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š๋Š” ํ•˜๋“œ์›จ์–ด์—์„œ๋„ ํ˜ธํ™˜์„ฑ์„ ์œ ์ง€ํ•œ๋‹ค: ๊ทธ ๋ช…๋ น๋“ค์€ NOP๋กœ ๋™์ž‘ํ•œ๋‹ค.
- BTI๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ์ปดํŒŒ์ผ๋Ÿฌ ํŒจ์Šค๋Š” ํ•„์š”ํ•œ ๊ณณ์—๋งŒ BTI๋ฅผ ์‚ฝ์ž…ํ•œ๋‹ค: ๊ฐ„์ ‘์ ์œผ๋กœ ํ˜ธ์ถœ๋  ์ˆ˜ ์žˆ๋Š” ํ•จ์ˆ˜๋“ค์ด๋‚˜ ์ ํ”„๋กœ ๋„๋‹ฌ ๊ฐ€๋Šฅํ•œ ๊ธฐ๋ณธ ๋ธ”๋ก๋“ค.
- ์ผ๋ถ€ ํŒจ์น˜์™€ LLVM ์ฝ”๋“œ๋Š” BTI๊ฐ€ ๋ชจ๋“  ๊ธฐ๋ณธ ๋ธ”๋ก์— ์‚ฝ์ž…๋˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผโ€”์Šค์œ„์น˜/์ ํ”„ ํ…Œ์ด๋ธ” ๋“ฑ์œผ๋กœ๋ถ€ํ„ฐ์˜ ๊ฐ€๋Šฅํ•œ ๋ถ„๊ธฐ ๋Œ€์ƒ์ธ ๋ธ”๋ก๋“ค์—๋งŒ ์‚ฝ์ž…๋œ๋‹ค๋Š” ์ ์„ ๋ณด์ธ๋‹ค.

#### BTI + PAC synergy

PAC๋Š” ํฌ์ธํ„ฐ ๊ฐ’(์†Œ์Šค)์„ ๋ณดํ˜ธํ•œ๋‹ค โ€” ๊ฐ„์ ‘ ํ˜ธ์ถœ/๋ฐ˜ํ™˜ ์ฒด์ธ์ด ๋ณ€์กฐ๋˜์ง€ ์•Š์•˜์Œ์„ ๋ณด์žฅํ•œ๋‹ค.

BTI๋Š” ์œ ํšจํ•œ ํฌ์ธํ„ฐ๋ผ ํ•˜๋”๋ผ๋„ ์˜ค์ง ์ ์ ˆํžˆ ํ‘œ์‹œ๋œ ์ง„์ž…์ ์œผ๋กœ๋งŒ ํ–ฅํ•ด์•ผ ํ•จ์„ ๋ณด์žฅํ•œ๋‹ค.

๊ฒฐํ•ฉํ•˜๋ฉด, ๊ณต๊ฒฉ์ž๋Š” ์˜ฌ๋ฐ”๋ฅธ PAC๋ฅผ ๊ฐ€์ง„ ์œ ํšจํ•œ ํฌ์ธํ„ฐ๋ฟ ์•„๋‹ˆ๋ผ ๋Œ€์ƒ์— BTI๊ฐ€ ๋ฐฐ์น˜๋˜์–ด ์žˆ์–ด์•ผ ํ•œ๋‹ค. ์ด๋Š” exploit gadget์„ ๊ตฌ์„ฑํ•˜๋Š” ๋‚œ์ด๋„๋ฅผ ์ฆ๊ฐ€์‹œํ‚จ๋‹ค.

#### Example


<details>
<summary>Example</summary>
์ต์Šคํ”Œ๋กœ์ž‡์ด `0xABCDEF`์˜ gadget์œผ๋กœ ํ”ผ๋ฒ—ํ•˜๋ ค ํ•˜๋Š”๋ฐ ๊ทธ๊ณณ์€ `BTI c`๋กœ ์‹œ์ž‘ํ•˜์ง€ ์•Š๋Š”๋‹ค. CPU๊ฐ€ `blr x0`๋ฅผ ์‹คํ–‰ํ•  ๋•Œ, ๋Œ€์ƒ ๊ฒ€์‚ฌ๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ณ  ์œ ํšจํ•œ landing pad๊ฐ€ ์—†์œผ๋ฏ€๋กœ ํดํŠธ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ๋งŽ์€ gadgets๋Š” BTI ํ”„๋ฆฌํ”ฝ์Šค๊ฐ€ ์—†์œผ๋ฉด ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค.
</details>


### 10. **Privileged Access Never (PAN) & Privileged Execute Never (PXN)**
**Introduced in more recent ARMv8 extensions / iOS support (for hardened kernel)**

#### PAN (Privileged Access Never)

- **PAN**์€ **ARMv8.1-A**์—์„œ ๋„์ž…๋œ ๊ธฐ๋Šฅ์œผ๋กœ, **privileged code**(EL1 ๋˜๋Š” EL2)๊ฐ€ **user-accessible (EL0)**๋กœ ํ‘œ์‹œ๋œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ **์ฝ๊ฑฐ๋‚˜ ์“ฐ์ง€ ๋ชปํ•˜๋„๋ก** ํ•œ๋‹ค. PAN์„ ๋ช…์‹œ์ ์œผ๋กœ ๋น„ํ™œ์„ฑํ™”ํ•˜์ง€ ์•Š๋Š” ํ•œ ์ ‘๊ทผ์ด ์ฐจ๋‹จ๋œ๋‹ค.
- ์•„์ด๋””์–ด๋Š”: ์ปค๋„์ด ์†์ž„์„ ๋‹นํ•˜๊ฑฐ๋‚˜ ์†์ƒ๋˜๋”๋ผ๋„, ๋จผ์ € PAN์„ *ํ•ด์ œ*ํ•˜์ง€ ์•Š๋Š” ํ•œ ์ž„์˜๋กœ user-space ํฌ์ธํ„ฐ๋ฅผ ์—ญ์ฐธ์กฐํ•  ์ˆ˜ ์—†๊ฒŒ ํ•˜์—ฌ **`ret2usr`** ์Šคํƒ€์ผ์˜ ์ต์Šคํ”Œ๋กœ์ž‡์ด๋‚˜ ์‚ฌ์šฉ์ž ์ œ์–ด ๋ฒ„ํผ์˜ ์˜ค์šฉ ์œ„ํ—˜์„ ์ค„์ธ๋‹ค.
- PAN์ด ํ™œ์„ฑํ™”๋˜์–ด ์žˆ์„ ๋•Œ(PSTATE.PAN = 1), privileged load/store๊ฐ€ EL0์—์„œ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ ๊ฐ€์ƒ ์ฃผ์†Œ์— ์ ‘๊ทผํ•˜๋ฉด **permission fault**๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.
- ์ปค๋„์ด ์ •๋‹นํ•˜๊ฒŒ user-space ๋ฉ”๋ชจ๋ฆฌ์— ์ ‘๊ทผํ•ด์•ผ ํ•  ๊ฒฝ์šฐ(์˜ˆ: ์‚ฌ์šฉ์ž ๋ฒ„ํผ๋กœ์˜ ๋ฐ์ดํ„ฐ ๋ณต์‚ฌ), ์ปค๋„์€ **์ผ์‹œ์ ์œผ๋กœ PAN์„ ๋น„ํ™œ์„ฑํ™”**ํ•˜๊ฑฐ๋‚˜ โ€œunprivileged load/storeโ€ ๋ช…๋ น์„ ์‚ฌ์šฉํ•ด์•ผ ๊ทธ ์ ‘๊ทผ์„ ํ—ˆ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
- ARM64์˜ Linux์—์„œ๋Š” PAN ์ง€์›์ด 2015๋…„๊ฒฝ ๋„์ž…๋˜์—ˆ๋‹ค: ์ปค๋„ ํŒจ์น˜๋“ค์ด ์ด ๊ธฐ๋Šฅ์˜ ๊ฐ์ง€๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  `get_user` / `put_user` ๋“ฑ์˜ ํ˜ธ์ถœ์„ PAN์„ ํ•ด์ œํ•˜๋Š” ๋ณ€ํ˜•์œผ๋กœ ๊ต์ฒดํ–ˆ๋‹ค.

**Key nuance / limitation / bug**
- Siguza ๋“ฑ์€ ARM ์„ค๊ณ„์˜ ๋ช…์„ธ ๋ฒ„๊ทธ(๋˜๋Š” ์• ๋งคํ•œ ๋™์ž‘)๊ฐ€ ์žˆ๋‹ค๋Š” ์ ์„ ์ง€์ ํ–ˆ๋Š”๋ฐ, ์ด๋Š” **execute-only user mappings**(`--x`)์ด **PAN์„ ๋ฐœ์ƒ์‹œํ‚ค์ง€ ์•Š์„ ์ˆ˜ ์žˆ๋‹ค**๋Š” ๊ฒƒ์ด๋‹ค. ์ฆ‰, ์‚ฌ์šฉ์ž ํŽ˜์ด์ง€๊ฐ€ ์ฝ๊ธฐ ๊ถŒํ•œ ์—†์ด ์‹คํ–‰๋งŒ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ‘œ์‹œ๋˜์–ด ์žˆ์œผ๋ฉด, ์ปค๋„์˜ ์ฝ๊ธฐ ์‹œ๋„๊ฐ€ PAN์„ ์šฐํšŒํ•  ์ˆ˜ ์žˆ๋‹ค โ€” ์•„ํ‚คํ…์ฒ˜๊ฐ€ โ€œEL0์—์„œ ์ ‘๊ทผ ๊ฐ€๋Šฅโ€์„ ํŒ์ •ํ•  ๋•Œ ์ฝ๊ธฐ ๊ถŒํ•œ์„ ์š”๊ตฌํ•˜๊ณ  ์‹คํ–‰ ๊ถŒํ•œ๋งŒ์œผ๋กœ๋Š” ๊ณ ๋ คํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์ด๋Š” ํŠน์ • ๊ตฌ์„ฑ์—์„œ PAN ์šฐํšŒ๋กœ ์ด์–ด์งˆ ์ˆ˜ ์žˆ๋‹ค.
- ๋”ฐ๋ผ์„œ iOS / XNU๊ฐ€ execute-only ์‚ฌ์šฉ์ž ํŽ˜์ด์ง€๋ฅผ ํ—ˆ์šฉ(์˜ˆ: ์ผ๋ถ€ JIT ๋˜๋Š” ์ฝ”๋“œ ์บ์‹œ ์„ค์ •)ํ•˜๋ฉด, ์ปค๋„์€ PAN์ด ํ™œ์„ฑํ™”๋˜์–ด ์žˆ์–ด๋„ ํ•ด๋‹น ํŽ˜์ด์ง€์—์„œ ์ฝ์–ด์˜ฌ ์ˆ˜ ์žˆ์–ด ์˜๋„์น˜ ์•Š์€ ๊ฒฝ๋กœ๊ฐ€ ์ƒ๊ธธ ์ˆ˜ ์žˆ๋‹ค. ์ด๋Š” ์ผ๋ถ€ ARMv8+ ์‹œ์Šคํ…œ์—์„œ ์•Œ๋ ค์ง„ ๋ฏธ๋ฌ˜ํ•œ ์ทจ์•ฝ ์ง€์ ์ด๋‹ค.

#### PXN (Privileged eXecute Never)

- **PXN**์€ ํŽ˜์ด์ง€ ํ…Œ์ด๋ธ” ์—”ํŠธ๋ฆฌ(leaf ๋˜๋Š” block ์—”ํŠธ๋ฆฌ)์— ์žˆ๋Š” ํ”Œ๋ž˜๊ทธ๋กœ, ํ•ด๋‹น ํŽ˜์ด์ง€๊ฐ€ **privileged ๋ชจ๋“œ(์˜ˆ: EL1)์—์„œ ์‹คํ–‰ ๋ถˆ๊ฐ€**์ž„์„ ํ‘œ์‹œํ•œ๋‹ค.
- PXN์€ ์ปค๋„(๋˜๋Š” ๋ชจ๋“  privileged ์ฝ”๋“œ)์ด user-space ํŽ˜์ด์ง€์—์„œ ๋ช…๋ น์„ ์ ํ”„ํ•˜๊ฑฐ๋‚˜ ์‹คํ–‰ํ•˜์ง€ ๋ชปํ•˜๊ฒŒ ๋ง‰๋Š”๋‹ค. ์‹ค์งˆ์ ์œผ๋กœ ์ปค๋„ ์ˆ˜์ค€์˜ ์ œ์–ด ํ๋ฆ„์„ ์‚ฌ์šฉ์ž ๋ฉ”๋ชจ๋ฆฌ๋กœ ๋ฆฌ๋””๋ ‰์…˜ํ•˜๋Š” ๊ฒƒ์„ ์ฐจ๋‹จํ•œ๋‹ค.
- PAN๊ณผ ๊ฒฐํ•ฉํ•˜๋ฉด ๋‹ค์Œ์„ ๋ณด์žฅํ•œ๋‹ค:
  1. ๊ธฐ๋ณธ์ ์œผ๋กœ ์ปค๋„์€ ์‚ฌ์šฉ์ž ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๊ฑฐ๋‚˜ ์“ธ ์ˆ˜ ์—†๋‹ค (PAN)
  2. ์ปค๋„์€ ์‚ฌ์šฉ์ž ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์—†๋‹ค (PXN)
- ARMv8 ํŽ˜์ด์ง€ ํ…Œ์ด๋ธ” ํฌ๋งท์—์„œ ๋ฆฌํ”„ ์—”ํŠธ๋ฆฌ๋“ค์€ ์†์„ฑ ๋น„ํŠธ์— `PXN` ๋น„ํŠธ(๋ฐ ๋น„๊ถŒํ•œ์ž ์‹คํ–‰ ๊ธˆ์ง€์šฉ `UXN`)๋ฅผ ๊ฐ€์ง„๋‹ค.

๋”ฐ๋ผ์„œ ์ปค๋„์ด ์†์ƒ๋˜์–ด ์‚ฌ์šฉ์ž ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ์ž˜๋ชป๋œ ํ•จ์ˆ˜ ํฌ์ธํ„ฐ๋ฅผ ๊ฐ–๊ณ  ์žˆ๋‹ค ํ•˜๋”๋ผ๋„, ๊ทธ ์ฃผ์†Œ๋กœ ๋ถ„๊ธฐํ•˜๋ ค ํ•˜๋ฉด PXN ๋น„ํŠธ๊ฐ€ ํดํŠธ๋ฅผ ์œ ๋ฐœํ•œ๋‹ค.

#### Memory-permission model & how PAN and PXN map to page table bits

PAN / PXN์ด ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ•˜๋Š”์ง€ ์ดํ•ดํ•˜๋ ค๋ฉด ARM์˜ ๋ณ€ํ™˜ ๋ฐ ๊ถŒํ•œ ๋ชจ๋ธ์„(๋‹จ์ˆœํ™”ํ•˜์—ฌ) ๋ด์•ผ ํ•œ๋‹ค:

- ๊ฐ ํŽ˜์ด์ง€ ๋˜๋Š” ๋ธ”๋ก ์—”ํŠธ๋ฆฌ๋Š” ์ฝ๊ธฐ/์“ฐ๊ธฐ, ํŠน๊ถŒ/๋น„ํŠน๊ถŒ ๋“ฑ์„ ๋‚˜ํƒ€๋‚ด๋Š” **AP[2:1]** ํ•„๋“œ์™€ ์‹คํ–‰ ๊ธˆ์ง€ ์ œ์•ฝ์„ ์œ„ํ•œ **UXN / PXN** ๋น„ํŠธ ๋“ฑ์„ ๊ฐ€์ง„๋‹ค.
- PSTATE.PAN์ด 1๋กœ ์„ค์ •๋˜๋ฉด ํ•˜๋“œ์›จ์–ด๋Š” ์ˆ˜์ •๋œ ์˜๋ฏธ๋ก ์„ ์‹œํ–‰ํ•œ๋‹ค: EL0์—์„œ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ ํŽ˜์ด์ง€(์ฆ‰ user-accessible)๋กœ ํ‘œ์‹œ๋œ ํŽ˜์ด์ง€์— ๋Œ€ํ•ด privileged ์ ‘๊ทผ์„ ๊ธˆ์ง€ํ•œ๋‹ค.
- ์•ž์„œ ์–ธ๊ธ‰ํ•œ ๋ฒ„๊ทธ ๋•Œ๋ฌธ์—, ์ฝ๊ธฐ ๊ถŒํ•œ ์—†์ด ์‹คํ–‰๋งŒ ํ—ˆ์šฉ๋œ ํŽ˜์ด์ง€๋Š” ์ผ๋ถ€ ๊ตฌํ˜„์—์„œ โ€œEL0์—์„œ ์ ‘๊ทผ ๊ฐ€๋Šฅโ€์œผ๋กœ ๊ฐ„์ฃผ๋˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์–ด PAN์„ ์šฐํšŒํ•  ์ˆ˜ ์žˆ๋‹ค.
- ํŽ˜์ด์ง€์— PXN ๋น„ํŠธ๊ฐ€ ์„ค์ •๋˜๋ฉด, ์ƒ์œ„ ๊ถŒํ•œ์—์„œ์˜ ๋ช…๋ น ํŽ˜์น˜๋ผ ํ• ์ง€๋ผ๋„ ์‹คํ–‰์ด ๊ธˆ์ง€๋œ๋‹ค.

#### Kernel usage of PAN / PXN in a hardened OS (e.g. iOS / XNU)

ํ•˜๋“œ๋‹๋œ ์ปค๋„ ์„ค๊ณ„(์˜ˆ: Apple์ด ์‚ฌ์šฉํ•  ๋ฒ•ํ•œ ์„ค๊ณ„)์—์„œ๋Š”:

- ์ปค๋„์ด ๊ธฐ๋ณธ์ ์œผ๋กœ PAN์„ ํ™œ์„ฑํ™”ํ•œ๋‹ค(๋”ฐ๋ผ์„œ privileged ์ฝ”๋“œ๊ฐ€ ์ œ์•ฝ์„ ๋ฐ›๋Š”๋‹ค).
- ์‚ฌ์šฉ์ž ๋ฒ„ํผ๋ฅผ ์ •๋‹นํ•˜๊ฒŒ ์ฝ๊ฑฐ๋‚˜ ์จ์•ผ ํ•˜๋Š” ๊ฒฝ๋กœ(์˜ˆ: syscall ๋ฒ„ํผ ๋ณต์‚ฌ, I/O, ์‚ฌ์šฉ์ž ํฌ์ธํ„ฐ ์ฝ๊ธฐ/์“ฐ๊ธฐ)์—์„œ๋Š” ์ปค๋„์ด ์ผ์‹œ์ ์œผ๋กœ **PAN์„ ๋น„ํ™œ์„ฑํ™”**ํ•˜๊ฑฐ๋‚˜ PAN์„ ์šฐํšŒํ•˜๋Š” ํŠน์ˆ˜ ๋ช…๋ น์„ ์‚ฌ์šฉํ•œ๋‹ค.
- ์‚ฌ์šฉ์ž ํŽ˜์ด์ง€์—๋Š” PXN = 1๋กœ ์„ค์ •ํ•˜์—ฌ(ํŽ˜์ด์ง€ ํ…Œ์ด๋ธ”์„ ํ†ตํ•ด) ์ปค๋„์ด ์‹คํ–‰ํ•˜์ง€ ๋ชปํ•˜๋„๋ก ํ•˜๊ณ , ์ปค๋„ ํŽ˜์ด์ง€์—๋Š” PXN์ด ์„ค์ •๋˜์ง€ ์•Š๋Š”๋‹ค.
- ์ปค๋„์€ ์–ด๋–ค ์ฝ”๋“œ ๊ฒฝ๋กœ๋„ ์‚ฌ์šฉ์ž ๋ฉ”๋ชจ๋ฆฌ ์˜์—ญ์œผ๋กœ ์‹คํ–‰ ํ๋ฆ„์„ ์ด๋™์‹œํ‚ค์ง€ ์•Š๋„๋ก ๋ณด์žฅํ•ด์•ผ ํ•œ๋‹ค(๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด PXN์„ ์šฐํšŒํ•  ์ˆ˜ ์žˆ์Œ). ๋”ฐ๋ผ์„œ โ€œ์‚ฌ์šฉ์ž ์ œ์–ด shellcode๋กœ ์ ํ”„โ€์— ์˜์กดํ•œ ์ต์Šคํ”Œ๋กœ์ž‡ ์ฒด์ธ์€ ์ฐจ๋‹จ๋œ๋‹ค.

์•ž์„œ ์–ธ๊ธ‰ํ•œ execute-only ํŽ˜์ด์ง€๋ฅผ ํ†ตํ•œ PAN ์šฐํšŒ ๊ฐ€๋Šฅ์„ฑ ๋•Œ๋ฌธ์—, ์‹ค์ œ ์‹œ์Šคํ…œ์—์„œ๋Š” Apple์ด execute-only ์‚ฌ์šฉ์ž ํŽ˜์ด์ง€๋ฅผ ๋น„ํ™œ์„ฑํ™”ํ•˜๊ฑฐ๋‚˜ ๋ช…์„ธ์ƒ ์•ฝ์ ์„ ํŒจ์น˜ํ–ˆ์„ ์ˆ˜ ์žˆ๋‹ค.

#### Attack surfaces, bypasses, and mitigations

- **PAN bypass via execute-only pages**: ์•ž์„œ ๋…ผ์˜ํ•œ ๋Œ€๋กœ, ๋ช…์„ธ๋Š” ๊ฐญ์„ ํ—ˆ์šฉํ•œ๋‹ค: ์ฝ๊ธฐ ๊ถŒํ•œ ์—†์ด ์‹คํ–‰๋งŒ ๊ฐ€๋Šฅํ•œ ์‚ฌ์šฉ์ž ํŽ˜์ด์ง€๋Š” ์ผ๋ถ€ ๊ตฌํ˜„์—์„œ โ€œEL0์—์„œ ์ ‘๊ทผ ๊ฐ€๋Šฅโ€์œผ๋กœ ๊ฐ„์ฃผ๋˜์ง€ ์•Š์•„ PAN์ด ์ปค๋„์˜ ์ฝ๊ธฐ๋ฅผ ์ฐจ๋‹จํ•˜์ง€ ๋ชปํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋Š” ๊ณต๊ฒฉ์ž์—๊ฒŒ execute-only ์„น์…˜์„ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋Š” ๋น„์ •์ƒ์  ๊ฒฝ๋กœ๋ฅผ ์ œ๊ณตํ•œ๋‹ค.
- **Temporal window exploit**: ์ปค๋„์ด ํ•„์š”ํ•œ ๊ฒƒ๋ณด๋‹ค ๋” ๊ธด ์‹œ๊ฐ„ ๋™์•ˆ PAN์„ ๋น„ํ™œ์„ฑํ™”ํ•˜๋ฉด, ๋ ˆ์ด์Šค๋‚˜ ์•…์˜์  ๊ฒฝ๋กœ๊ฐ€ ๊ทธ ์ฐฝ์„ ์ด์šฉํ•ด ์˜๋„ํ•˜์ง€ ์•Š์€ ์‚ฌ์šฉ์ž ๋ฉ”๋ชจ๋ฆฌ ์ ‘๊ทผ์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.
- **Forgotten re-enable**: PAN์„ ๋‹ค์‹œ ํ™œ์„ฑํ™”ํ•˜์ง€ ์•Š๋Š” ์ฝ”๋“œ ๊ฒฝ๋กœ๊ฐ€ ์žˆ์œผ๋ฉด, ์ดํ›„์˜ ์ปค๋„ ์ž‘์—…์ด ์ž˜๋ชปํ•ด์„œ ์‚ฌ์šฉ์ž ๋ฉ”๋ชจ๋ฆฌ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค.
- **Misconfiguration of PXN**: ํŽ˜์ด์ง€ ํ…Œ์ด๋ธ”์ด ์‚ฌ์šฉ์ž ํŽ˜์ด์ง€์— PXN์„ ์„ค์ •ํ•˜์ง€ ์•Š๊ฑฐ๋‚˜ ์‚ฌ์šฉ์ž ์ฝ”๋“œ ํŽ˜์ด์ง€๋ฅผ ์ž˜๋ชป ๋งคํ•‘ํ•˜๋ฉด, ์ปค๋„์ด ์‚ฌ์šฉ์ž ๊ณต๊ฐ„ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋„๋ก ์†์„ ์ˆ˜ ์žˆ๋‹ค.
- **Speculation / side-channels**: ํˆฌ๊ธฐ์  ์šฐํšŒ์™€ ์œ ์‚ฌํ•˜๊ฒŒ, PAN / PXN ๊ฒ€์‚ฌ์— ๋Œ€ํ•œ ์ผ์‹œ์  ์œ„๋ฐ˜์„ ์ดˆ๋ž˜ํ•˜๋Š” ๋งˆ์ดํฌ๋กœ์•„ํ‚คํ…์ฒ˜์  ๋ถ€์ž‘์šฉ์ด ์žˆ์„ ์ˆ˜ ์žˆ๋‹ค(๊ทธ๋Ÿฌ๋‚˜ ์ด๋Ÿฐ ๊ณต๊ฒฉ์€ CPU ์„ค๊ณ„์— ํฌ๊ฒŒ ์˜์กดํ•œ๋‹ค).
- **Complex interactions**: JIT, shared memory, JIT ์ฝ”๋“œ ์˜์—ญ ๋“ฑ ๊ณ ๊ธ‰ ๊ธฐ๋Šฅ์—์„œ๋Š” ์ปค๋„์ด ํŠน์ • ์‚ฌ์šฉ์ž ๋งคํ•‘์— ๋Œ€ํ•ด ์„ธ๋ฐ€ํ•œ ์ œ์–ด๋ฅผ ํ—ˆ์šฉํ•ด์•ผ ํ•  ์ˆ˜ ์žˆ๋‹ค; PAN/PXN ์ œ์•ฝ ์•„๋ž˜์—์„œ ์ด๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ์„ค๊ณ„ํ•˜๋Š” ๊ฒƒ์€ ๊นŒ๋‹ค๋กญ๋‹ค.

#### Example

<details>
<summary>Code Example</summary>
๋‹ค์Œ์€ ์‚ฌ์šฉ์ž ๋ฉ”๋ชจ๋ฆฌ ์ ‘๊ทผ ์ฃผ๋ณ€์—์„œ PAN์„ ํ™œ์„ฑ/๋น„ํ™œ์„ฑํ™”ํ•˜๋Š” ๊ฒƒ์„ ๋ณด์—ฌ์ฃผ๋Š” ์˜ˆ์‹œ ์˜์‚ฌ ์–ด์…ˆ๋ธ”๋ฆฌ ์‹œํ€€์Šค์ด๋‹ค.

// Suppose kernel entry point, PAN is enabled (privileged code cannot access user memory by default)

; Kernel receives a syscall with user pointer in X0 ; wants to read an integer from user space mov X1, X0 ; X1 = user pointer

; disable PAN to allow privileged access to user memory MSR PSTATE.PAN, #0 ; clear PAN bit, disabling the restriction

ldr W2, [X1] ; now allowed load from user address

; re-enable PAN before doing other kernel logic MSR PSTATE.PAN, #1 ; set PAN

; โ€ฆ further kernel work โ€ฆ

; Later, suppose an exploit corrupts a pointer to a user-space code page and jumps there BR X3 ; branch to X3 (which points into user memory)

; Because the target page is marked PXN = 1 for privileged execution, ; the CPU throws an exception (fault) and rejects execution

If the kernel had **์„ค์ •ํ•˜์ง€ ์•Š์•˜๋‹ค๋ฉด** PXN on that user page, then the branch might succeed โ€” which would be insecure.

If the kernel forgets to re-enable PAN after user memory access, it opens a window where further kernel logic might accidentally read/write arbitrary user memory.

If the user pointer is into an execute-only page (user page with only execute permission, no read/write), under the PAN spec bug, `ldr W2, [X1]` might **์˜ค๋ฅ˜๋ฅผ ์ผ์œผํ‚ค์ง€ ์•Š์„ ์ˆ˜ ์žˆ๋‹ค** even with PAN enabled, enabling a bypass exploit, depending on implementation.

</details>

<details>
<summary>Example</summary>
A kernel vulnerability tries to take a user-provided function pointer and call it in kernel context (i.e. `call user_buffer`). Under PAN/PXN, that operation is disallowed or faults.
</details>

---

### 11. **Top Byte Ignore (TBI) / Pointer Tagging**
**Introduced in ARMv8.5 / newer (or optional extension)**
TBI means the top byte (most-significant byte) of a 64-bit pointer is ignored by address translation. This lets OS or hardware embed **tag bits** in the pointerโ€™s top byte without affecting the actual address.

- TBI stands for **Top Byte Ignore** (sometimes called *Address Tagging*). It is a hardware feature (available in many ARMv8+ implementations) that **ignores the top 8 bits** (bits 63:56) of a 64-bit pointer when performing **address translation / load/store / instruction fetch**.
- In effect, the CPU treats a pointer `0xTTxxxx_xxxx_xxxx` (where `TT` = top byte) as `0x00xxxx_xxxx_xxxx` for the purposes of address translation, ignoring (masking off) the top byte. The top byte can be used by software to store **metadata / tag bits**.
- This gives software โ€œfreeโ€ in-band space to embed a byte of tag in each pointer without altering which memory location it refers to.
- The architecture ensures that loads, stores, and instruction fetch treat the pointer with its top byte masked (i.e. tag stripped off) before performing the actual memory access.

Thus TBI decouples the **logical pointer** (pointer + tag) from the **physical address** used for memory operations.

#### Why TBI: Use cases and motivation

- **Pointer tagging / metadata**: You can store extra metadata (e.g. object type, version, bounds, integrity tags) in that top byte. When you later use the pointer, the tag is ignored at hardware level, so you donโ€™t need to strip manually for the memory access.
- **Memory tagging / MTE (Memory Tagging Extension)**: TBI is the base hardware mechanism that MTE builds on. In ARMv8.5, the **Memory Tagging Extension** uses bits 59:56 of the pointer as a **logical tag** and checks it against an **allocation tag** stored in memory.
- **Enhanced security & integrity**: By combining TBI with pointer authentication (PAC) or runtime checks, you can force not just the pointer value but also the tag to be correct. An attacker overwriting a pointer without the correct tag will produce a mismatched tag.
- **Compatibility**: Because TBI is optional and tag bits are ignored by hardware, existing untagged code continues to operate normally. The tag bits effectively become โ€œdonโ€™t careโ€ bits for legacy code.

#### Example
<details>
<summary>Example</summary>
A function pointer included a tag in its top byte (say `0xAA`). An exploit overwrites the pointer low bits but neglects the tag, so when the kernel verifies or sanitizes, the pointer fails or is rejected.
</details>

---

### 12. **Page Protection Layer (PPL)**
**Introduced in late iOS / modern hardware (iOS ~17 / Apple silicon / high-end models)** (some reports show PPL circa macOS / Apple silicon, but Apple is bringing analogous protections to iOS)

- PPL is designed as an **intra-kernel protection boundary**: even if the kernel (EL1) is compromised and has read/write capabilities, **it should not be able to freely modify** certain **sensitive pages** (especially page tables, code-signing metadata, kernel code pages, entitlements, trust caches, etc.).
- It effectively creates a **โ€œkernel within the kernelโ€** โ€” a smaller trusted component (PPL) with **elevated privileges** that alone can modify protected pages. Other kernel code must call into PPL routines to effect changes.
- This reduces the attack surface for kernel exploits: even with full arbitrary R/W/execute in kernel mode, exploit code must also somehow get into the PPL domain (or bypass PPL) to modify critical structures.
- On newer Apple silicon (A15+ / M2+), Apple is transitioning to **SPTM (Secure Page Table Monitor)**, which in many cases replaces PPL for page-table protection on those platforms.

Hereโ€™s how PPL is believed to operate, based on public analysis:

#### Use of APRR / permission routing (APRR = Access Permission ReRouting)

- Apple hardware uses a mechanism called **APRR (Access Permission ReRouting)**, which allows page table entries (PTEs) to contain small indices, rather than full permission bits. Those indices are mapped via APRR registers to actual permissions. This allows dynamic remapping of permissions per domain.
- PPL leverages APRR to segregate privilege within kernel context: only the PPL domain is permitted to update the mapping between indices and effective permissions. That is, when non-PPL kernel code writes a PTE or tries to flip permission bits, the APRR logic disallows it (or enforces read-only mapping).
- PPL code itself runs in a restricted region (e.g. `__PPLTEXT`) which is normally non-executable or non-writable until entry gates temporarily allow it. The kernel calls PPL entry points (โ€œPPL routinesโ€) to perform sensitive operations.

#### Gate / Entry & Exit

- When the kernel needs to modify a protected page (e.g. change permissions of a kernel code page, or modify page tables), it calls into a **PPL wrapper** routine, which does validation and then transitions into the PPL domain. Outside that domain, the protected pages are effectively read-only or non-modifiable by the main kernel.
- During PPL entry, the APRR mappings are adjusted so that memory pages in the PPL region are set to **executable & writable** within PPL. Upon exit, they are returned to read-only / non-writable. This ensures that only well-audited PPL routines can write to protected pages.
- Outside PPL, attempts by kernel code to write to those protected pages will fault (permission denied) because the APRR mapping for that code domain doesnโ€™t permit writing.

#### Protected page categories

The pages that PPL typically protects include:

- Page table structures (translation table entries, mapping metadata)
- Kernel code pages, especially those containing critical logic
- Code-sign metadata (trust caches, signature blobs)
- Entitlement tables, signature enforcement tables
- Other high-value kernel structures where a patch would allow bypassing signature checks or credentials manipulation

The idea is that even if the kernel memory is fully controlled, the attacker cannot simply patch or rewrite these pages, unless they also compromise PPL routines or bypass PPL.


#### Known Bypasses & Vulnerabilities

1. **Project Zeroโ€™s PPL bypass (stale TLB trick)**

- A public writeup by Project Zero describes a bypass involving **stale TLB entries**.
- The idea:

1. Allocate two physical pages A and B, mark them as PPL pages (so they are protected).
2. Map two virtual addresses P and Q whose L3 translation table pages come from A and B.
3. Spin a thread to continuously access Q, keeping its TLB entry alive.
4. Call `pmap_remove_options()` to remove mappings starting at P; due to a bug, the code mistakenly removes the TTEs for both P and Q, but only invalidates the TLB entry for P, leaving Qโ€™s stale entry live.
5. Reuse B (page Qโ€™s table) to map arbitrary memory (e.g. PPL-protected pages). Because the stale TLB entry still maps Qโ€™s old mapping, that mapping remains valid for that context.
6. Through this, the attacker can put writable mapping of PPL-protected pages in place without going through PPL interface.

- This exploit required fine control of physical mapping and TLB behavior. It demonstrates that a security boundary relying on TLB / mapping correctness must be extremely careful about TLB invalidations and mapping consistency.

- Project Zero commented that bypasses like this are subtle and rare, but possible in complex systems. Still, they regard PPL as a solid mitigation.

2. **Other potential hazards & constraints**

- If a kernel exploit can directly enter PPL routines (via calling the PPL wrappers), it might bypass restrictions. Thus argument validation is critical.
- Bugs in the PPL code itself (e.g. arithmetic overflow, boundary checks) can allow out-of-bounds modifications inside PPL. Project Zero observed that such a bug in `pmap_remove_options_internal()` was exploited in their bypass.
- The PPL boundary is irrevocably tied to hardware enforcement (APRR, memory controller), so it's only as strong as the hardware implementation.



#### Example
<details>
<summary>Code Example</summary>
Hereโ€™s a simplified pseudocode / logic showing how a kernel might call into PPL to modify protected pages:
```c
// In kernel (outside PPL domain)
function kernel_modify_pptable(pt_addr, new_entry) {
// validate arguments, etc.
return ppl_call_modify(pt_addr, new_entry)  // call PPL wrapper
}

// In PPL (trusted domain)
function ppl_call_modify(pt_addr, new_entry) {
// temporarily enable write access to protected pages (via APRR adjustments)
aprr_set_index_for_write(PPL_INDEX)
// perform the modification
*pt_addr = new_entry
// restore permissions (make pages read-only again)
aprr_restore_default()
return success
}

// If kernel code outside PPL does:
*pt_addr = new_entry  // a direct write
// It will fault because APRR mapping for non-PPL domain disallows write to that page

The kernel can do many normal operations, but only through ppl_call_* routines can it change protected mappings or patch code.

Example A kernel exploit tries to overwrite the entitlement table, or disable code-sign enforcement by modifying a kernel signature blob. Because that page is PPL-protected, the write is blocked unless going through the PPL interface. So even with kernel code execution, you cannot bypass code-sign constraints or modify credential data arbitrarily. On iOS 17+ certain devices use SPTM to further isolate PPL-managed pages.

PPL โ†’ SPTM / Replacements / Future

  • On Appleโ€™s modern SoCs (A15 or later, M2 or later), Apple supports SPTM (Secure Page Table Monitor), which replaces PPL for page table protections.
  • Apple calls out in documentation: โ€œPage Protection Layer (PPL) and Secure Page Table Monitor (SPTM) enforce execution of signed and trusted code โ€ฆ PPL manages the page table permission overrides โ€ฆ Secure Page Table Monitor replaces PPL on supported platforms.โ€
  • The SPTM architecture likely shifts more policy enforcement into a higher-privileged monitor outside kernel control, further reducing the trust boundary.

MTE | EMTE | MIE

Hereโ€™s a higher-level description of how EMTE operates under Appleโ€™s MIE setup:

  1. Tag assignment
  • When memory is allocated (e.g. in kernel or user space via secure allocators), a secret tag is assigned to that block.
  • The pointer returned to the user or kernel includes that tag in its high bits (using TBI / top byte ignore mechanisms).
  1. Tag checking on access
  • Whenever a load or store is executed using a pointer, the hardware checks that the pointerโ€™s tag matches the memory blockโ€™s tag (allocation tag). If mismatch, it faults immediately (since synchronous).
  • Because itโ€™s synchronous, there is no โ€œdelayed detectionโ€ window.
  1. Retagging on free / reuse
  • When memory is freed, the allocator changes the blockโ€™s tag (so older pointers with old tags no longer match).
  • A use-after-free pointer would therefore have a stale tag and mismatch when accessed.
  1. Neighbor-tag differentiation to catch overflows
  • Adjacent allocations are given distinct tags. If a buffer overflow spills into neighborโ€™s memory, tag mismatch causes a fault.
  • This is especially powerful in catching small overflows that cross boundary.
  1. Tag confidentiality enforcement
  • Apple must prevent tag values being leaked (because if attacker learns the tag, they could craft pointers with correct tags).
  • They include protections (microarchitectural / speculative controls) to avoid side-channel leakage of tag bits.
  1. Kernel and user-space integration
  • Apple uses EMTE not just in user-space but also in kernel / OS-critical components (to guard kernel against memory corruption).
  • The hardware/OS ensures tag rules apply even when kernel is executing on behalf of user space.
Example ``` Allocate A = 0x1000, assign tag T1 Allocate B = 0x2000, assign tag T2

// pointer P points into A with tag T1 P = (T1 << 56) | 0x1000

// Valid store *(P + offset) = value // tag T1 matches allocation โ†’ allowed

// Overflow attempt: Pโ€™ = P + size_of_A (into B region) *(Pโ€™ + delta) = value โ†’ pointer includes tag T1 but memory block has tag T2 โ†’ mismatch โ†’ fault

// Free A, allocator retags it to T3 free(A)

// Use-after-free: *(P) = value โ†’ pointer still has old tag T1, memory region is now T3 โ†’ mismatch โ†’ fault

</details>

#### ํ•œ๊ณ„์  & ๋„์ „ ๊ณผ์ œ

- **Intrablock overflows**: ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ๊ฐ€ ๋™์ผํ•œ ํ• ๋‹น ๋‚ด์—์„œ๋งŒ ๋ฐœ์ƒ(๊ฒฝ๊ณ„๋ฅผ ๋„˜์ง€ ์•Š์Œ)ํ•˜๊ณ  ํƒœ๊ทธ๊ฐ€ ๋™์ผํ•˜๊ฒŒ ์œ ์ง€๋˜๋ฉด tag mismatch๋กœ๋Š” ํƒ์ง€๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
- **Tag width limitation**: ํƒœ๊ทธ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋น„ํŠธ ์ˆ˜๊ฐ€ ์ œํ•œ์ (์˜ˆ: 4๋น„ํŠธ ๋˜๋Š” ์ž‘์€ ๋„๋ฉ”์ธ)์ด๋ผ ๋„ค์ž„์ŠคํŽ˜์ด์Šค๊ฐ€ ์ œํ•œ๋ฉ๋‹ˆ๋‹ค.
- **Side-channel leaks**: ํƒœ๊ทธ ๋น„ํŠธ๊ฐ€ (์บ์‹œ / speculative execution ๋“ฑ์„ ํ†ตํ•ด) leaked ๋  ์ˆ˜ ์žˆ๋‹ค๋ฉด ๊ณต๊ฒฉ์ž๊ฐ€ ์œ ํšจํ•œ ํƒœ๊ทธ๋ฅผ ์•Œ์•„๋‚ด ์šฐํšŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Apple์˜ tag confidentiality enforcement๋Š” ์ด๋ฅผ ์™„ํ™”ํ•˜๋ ค๊ณ  ์„ค๊ณ„๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
- **Performance overhead**: ๊ฐ ๋กœ๋“œ/์Šคํ† ์–ด๋งˆ๋‹ค ํƒœ๊ทธ ์ฒดํฌ๊ฐ€ ์ถ”๊ฐ€ ๋น„์šฉ์„ ์œ ๋ฐœํ•˜๋ฏ€๋กœ Apple์€ ํ•˜๋“œ์›จ์–ด ์ตœ์ ํ™”๋ฅผ ํ†ตํ•ด ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ๋‚ฎ์ถฐ์•ผ ํ•ฉ๋‹ˆ๋‹ค.
- **Compatibility & fallback**: ๊ตฌํ˜• ํ•˜๋“œ์›จ์–ด๋‚˜ EMTE๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š๋Š” ๊ตฌ์„ฑ ์š”์†Œ์—์„œ๋Š” ํŽ˜์ผ๋ฐฑ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. Apple์€ MIE๊ฐ€ ์ง€์›๋˜๋Š” ์žฅ์น˜์—์„œ๋งŒ ํ™œ์„ฑํ™”๋œ๋‹ค๊ณ  ์ฃผ์žฅํ•ฉ๋‹ˆ๋‹ค.
- **Complex allocator logic**: ํ• ๋‹น์ž๋Š” ํƒœ๊ทธ ๊ด€๋ฆฌ, retagging, ๊ฒฝ๊ณ„ ์ •๋ ฌ, ํƒœ๊ทธ ์ถฉ๋Œ ํšŒํ”ผ ๋“ฑ์„ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ• ๋‹น์ž ๋กœ์ง์˜ ๋ฒ„๊ทธ๋Š” ์ทจ์•ฝ์ ์„ ์œ ๋ฐœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
- **Mixed memory / hybrid areas**: ์ผ๋ถ€ ๋ฉ”๋ชจ๋ฆฌ๋Š” untagged(๋ ˆ๊ฑฐ์‹œ)๋กœ ๋‚จ์•„ ์žˆ์–ด ์ƒํ˜ธ์šด์šฉ์„ฑ์ด ๊นŒ๋‹ค๋กœ์›Œ์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
- **Speculative / transient attacks**: ๋‹ค๋ฅธ ๋งˆ์ดํฌ๋กœ์•„ํ‚คํ…์ฒ˜ ๋ณดํ˜ธ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ speculative execution์ด๋‚˜ micro-op fusion์ด ๊ฒ€์‚ฌ๋ฅผ ์ผ์‹œ์ ์œผ๋กœ ์šฐํšŒํ•˜๊ฑฐ๋‚˜ ํƒœ๊ทธ ๋น„ํŠธ๋ฅผ leak ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
- **Limited to supported regions**: Apple์€ EMTE๋ฅผ ์ปค๋„์ด๋‚˜ ๋ณด์•ˆ์— ์ค‘์š”ํ•œ ์„œ๋ธŒ์‹œ์Šคํ…œ ๋“ฑ ์„ ๋ณ„๋œ ๊ณ ์œ„ํ—˜ ์˜์—ญ์—์„œ๋งŒ ์ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

---

## ํ‘œ์ค€ MTE ๋Œ€๋น„ ์ฃผ์š” ํ–ฅ์ƒ์  / ์ฐจ์ด์ 

๋‹ค์Œ์€ Apple์ด ๊ฐ•์กฐํ•˜๋Š” ๊ฐœ์„ ์  ๋ฐ ๋ณ€๊ฒฝ์‚ฌํ•ญ์ž…๋‹ˆ๋‹ค:

| Feature | Original MTE | EMTE (Appleโ€™s enhanced) / MIE |
|---|---|---|
| **Check mode** | Supports synchronous and asynchronous modes. In async, tag mismatches are reported later (delayed)| Apple insists on **synchronous mode** by defaultโ€”tag mismatches are caught immediately, no delay/race windows allowed.|
| **Coverage of non-tagged memory** | Accesses to non-tagged memory (e.g. globals) may bypass checks in some implementations | EMTE requires that accesses from a tagged region to non-tagged memory also validate tag knowledge, making it harder to bypass by mixing allocations.|
| **Tag confidentiality / secrecy** | Tags might be observable or leaked via side channels | Apple adds **Tag Confidentiality Enforcement**, which attempts to prevent leakage of tag values (via speculative side-channels etc.).|
| **Allocator integration & retagging** | MTE leaves much of allocator logic to software | Appleโ€™s secure typed allocators (kalloc_type, xzone malloc, etc.) integrate with EMTE: when memory is allocated or freed, tags are managed at fine granularity.|
| **Always-on by default** | In many platforms, MTE is optional or off by default | Apple enables EMTE / MIE by default on supported hardware (e.g. iPhone 17 / A19) for kernel and many user processes.|

Apple์€ ํ•˜๋“œ์›จ์–ด์™€ ์†Œํ”„ํŠธ์›จ์–ด ์Šคํƒ์„ ๋ชจ๋‘ ํ†ต์ œํ•˜๊ธฐ ๋•Œ๋ฌธ์— EMTE๋ฅผ ์—„๊ฒฉํ•˜๊ฒŒ ์ ์šฉํ•˜๊ณ  ์„ฑ๋Šฅ ์ €ํ•˜ ์š”์†Œ๋ฅผ ํ”ผํ•˜๋ฉฐ side-channel ์ทจ์•ฝ์ ์„ ๋ด‰์‡„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

---

## EMTE๊ฐ€ ์‹ค์ œ๋กœ ๋™์ž‘ํ•˜๋Š” ๋ฐฉ์‹ (Apple / MIE)

๋‹ค์Œ์€ Apple์˜ MIE ๊ตฌ์„ฑ์—์„œ EMTE๊ฐ€ ๋™์ž‘ํ•˜๋Š” ์ƒ์œ„ ์ˆ˜์ค€ ์„ค๋ช…์ž…๋‹ˆ๋‹ค:

1. **Tag assignment**
- ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ํ• ๋‹น๋  ๋•Œ(์˜ˆ: ์ปค๋„ ๋˜๋Š” secure allocators๋ฅผ ํ†ตํ•œ ์‚ฌ์šฉ์ž ๊ณต๊ฐ„), ํ•ด๋‹น ๋ธ”๋ก์— **secret tag**๊ฐ€ ํ• ๋‹น๋ฉ๋‹ˆ๋‹ค.
- ์‚ฌ์šฉ์ž๋‚˜ ์ปค๋„์— ๋ฐ˜ํ™˜๋˜๋Š” ํฌ์ธํ„ฐ๋Š” TBI / top byte ignore ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์‚ฌ์šฉํ•ด ๋†’์€ ๋น„ํŠธ์— ๊ทธ ํƒœ๊ทธ๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.

2. **Tag checking on access**
- ํฌ์ธํ„ฐ๋ฅผ ์‚ฌ์šฉํ•œ load/store๊ฐ€ ์‹คํ–‰๋  ๋•Œ๋งˆ๋‹ค ํ•˜๋“œ์›จ์–ด๋Š” ํฌ์ธํ„ฐ์˜ ํƒœ๊ทธ๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ ๋ธ”๋ก์˜ ํƒœ๊ทธ(ํ• ๋‹น ํƒœ๊ทธ)์™€ ์ผ์น˜ํ•˜๋Š”์ง€ ๊ฒ€์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๋ถˆ์ผ์น˜ํ•˜๋ฉด ์ฆ‰์‹œ fault๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค(๋™๊ธฐ ๋ฐฉ์‹์ด๋ฏ€๋กœ).
- ๋™๊ธฐ ๋ฐฉ์‹์ด๊ธฐ ๋•Œ๋ฌธ์— โ€œ์ง€์—ฐ๋œ ํƒ์ง€โ€ ์ฐฝ์ด ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

3. **Retagging on free / reuse**
- ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ํ•ด์ œ๋˜๋ฉด ํ• ๋‹น์ž๋Š” ๋ธ”๋ก์˜ ํƒœ๊ทธ๋ฅผ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค(์ด์ „ ํƒœ๊ทธ๋ฅผ ๊ฐ€์ง„ ํฌ์ธํ„ฐ๋Š” ๋” ์ด์ƒ ์ผ์น˜ํ•˜์ง€ ์•Š์Œ).
- ๋”ฐ๋ผ์„œ use-after-free ํฌ์ธํ„ฐ๋Š” ์˜ค๋ž˜๋œ ํƒœ๊ทธ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์–ด ์ ‘๊ทผ ์‹œ mismatch๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

4. **Neighbor-tag differentiation to catch overflows**
- ์ธ์ ‘ํ•œ ํ• ๋‹น ๋ธ”๋ก์—๋Š” ์„œ๋กœ ๋‹ค๋ฅธ ํƒœ๊ทธ๊ฐ€ ๋ถ€์—ฌ๋ฉ๋‹ˆ๋‹ค. ๋ฒ„ํผ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ๊ฐ€ ์ด์›ƒ ๋ฉ”๋ชจ๋ฆฌ๋กœ ํ˜๋Ÿฌ๋“ค์–ด๊ฐ€๋ฉด ํƒœ๊ทธ ๋ถˆ์ผ์น˜๋กœ fault๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.
- ๊ฒฝ๊ณ„๋ฅผ ๋„˜๋Š” ์ž‘์€ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ๋ฅผ ์žก์•„๋‚ด๋Š” ๋ฐ ํŠนํžˆ ๊ฐ•๋ ฅํ•ฉ๋‹ˆ๋‹ค.

5. **Tag confidentiality enforcement**
- ๊ณต๊ฒฉ์ž๊ฐ€ ํƒœ๊ทธ ๊ฐ’์„ ์•Œ๊ฒŒ ๋˜๋ฉด ์˜ฌ๋ฐ”๋ฅธ ํƒœ๊ทธ๋กœ ํฌ์ธํ„ฐ๋ฅผ ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ Apple์€ ํƒœ๊ทธ ๊ฐ’์ด leak ๋˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
- ์ด๋ฅผ ์œ„ํ•ด ํƒœ๊ทธ ๋น„ํŠธ์˜ side-channel leak ๋ฅผ ๋ง‰๊ธฐ ์œ„ํ•œ ๋งˆ์ดํฌ๋กœ์•„ํ‚คํ…์ฒ˜์  / speculative ์ œ์–ด๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.

6. **Kernel and user-space integration**
- Apple์€ EMTE๋ฅผ ์‚ฌ์šฉ์ž ๊ณต๊ฐ„๋ฟ ์•„๋‹ˆ๋ผ ์ปค๋„/OS ํ•ต์‹ฌ ๊ตฌ์„ฑ์š”์†Œ์—์„œ๋„ ์‚ฌ์šฉํ•ด ์ปค๋„์˜ ๋ฉ”๋ชจ๋ฆฌ ์†์ƒ์œผ๋กœ๋ถ€ํ„ฐ ๋ณดํ˜ธํ•ฉ๋‹ˆ๋‹ค.
- ํ•˜๋“œ์›จ์–ด/OS๋Š” ์‚ฌ์šฉ์ž ๊ณต๊ฐ„์„ ๋Œ€์‹ ํ•ด ์ปค๋„์ด ์‹คํ–‰๋  ๋•Œ์—๋„ ํƒœ๊ทธ ๊ทœ์น™์ด ์ ์šฉ๋˜๋„๋ก ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค.

EMTE๋Š” MIE์— ํ†ตํ•ฉ๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— Apple์€ ํ•ต์‹ฌ ๊ณต๊ฒฉ ํ‘œ๋ฉด ์ „๋ฐ˜์—์„œ ๋™๊ธฐ ๋ชจ๋“œ๋กœ EMTE๋ฅผ ์ ์šฉํ•˜๋ฉฐ, ๋‹จ์ˆœํ•œ ์„ ํƒ์  ๋˜๋Š” ๋””๋ฒ„๊น… ์šฉ๋„๊ฐ€ ์•„๋‹ˆ๋ผ ๊ธฐ๋ณธ์ ์œผ๋กœ ํ™œ์„ฑํ™”๋œ ๋ณดํ˜ธ๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

---

## XNU์—์„œ์˜ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ

์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•  ๋•Œ(์˜ˆ: `EXC_BAD_ACCESS`, `EXC_BAD_INSTRUCTION`, `EXC_CRASH`, `EXC_ARM_PAC` ๋“ฑ), XNU ์ปค๋„์˜ **Mach ๋ ˆ์ด์–ด**๋Š” ์ด๋ฅผ UNIX ์Šคํƒ€์ผ์˜ signal(์˜ˆ: `SIGSEGV`, `SIGBUS`, `SIGILL`, ...)๋กœ ๋ณ€ํ™˜ํ•˜๊ธฐ ์ „์— ๊ฐ€๋กœ์ฑ„๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.

์ด ๊ณผ์ •์€ ์‚ฌ์šฉ์ž ๊ณต๊ฐ„์œผ๋กœ ์ „๋‹ฌ๋˜๊ฑฐ๋‚˜ BSD ์‹œ๊ทธ๋„๋กœ ๋ณ€ํ™˜๋˜๊ธฐ ์ „์— ์—ฌ๋Ÿฌ ๊ณ„์ธต์˜ ์˜ˆ์™ธ ์ „ํŒŒ ๋ฐ ์ฒ˜๋ฆฌ๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.

###ย ์˜ˆ์™ธ ํ๋ฆ„ (์ƒ์œ„ ์ˆ˜์ค€)

1.  **CPU๊ฐ€ ๋™๊ธฐ ์˜ˆ์™ธ๋ฅผ ์œ ๋ฐœ**ํ•ฉ๋‹ˆ๋‹ค(์˜ˆ: ์ž˜๋ชป๋œ ํฌ์ธํ„ฐ ์—ญ์ฐธ์กฐ, PAC ์‹คํŒจ, ๋ถˆ๋ฒ• ๋ช…๋ น ๋“ฑ).

2.  **์ €์ˆ˜์ค€ trap handler**๊ฐ€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค(`trap.c`, `exception.c` ์ฐธ๊ณ ).

3.  ํŠธ๋žฉ ํ•ธ๋“ค๋Ÿฌ๋Š” **`exception_triage()`**๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด Mach ์˜ˆ์™ธ ์ฒ˜๋ฆฌ์˜ ํ•ต์‹ฌ์ž…๋‹ˆ๋‹ค.

4.  `exception_triage()`๋Š” ์˜ˆ์™ธ๋ฅผ ์–ด๋–ป๊ฒŒ ๋ผ์šฐํŒ…ํ• ์ง€ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค:

-   ๋จผ์ € **thread์˜ exception port**๋กœ ๋ณด๋ƒ…๋‹ˆ๋‹ค.

-   ๊ทธ ๋‹ค์Œ **task์˜ exception port**๋กœ ๋ณด๋ƒ…๋‹ˆ๋‹ค.

-   ๊ทธ ๋‹ค์Œ **host์˜ exception port**๋กœ ๋ณด๋ƒ…๋‹ˆ๋‹ค(์ข…์ข… `launchd`๋‚˜ `ReportCrash`).

์ด๋Ÿฌํ•œ ํฌํŠธ๋“ค ์ค‘ ์–ด๋А ๊ฒƒ๋„ ์˜ˆ์™ธ๋ฅผ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š์œผ๋ฉด ์ปค๋„์€:

-   **์ด๋ฅผ BSD signal๋กœ ๋ณ€ํ™˜**ํ•ฉ๋‹ˆ๋‹ค(์‚ฌ์šฉ์ž ๊ณต๊ฐ„ ํ”„๋กœ์„ธ์Šค์˜ ๊ฒฝ์šฐ).

-   **panic์„ ์ผ์œผํ‚ต๋‹ˆ๋‹ค**(์ปค๋„ ๊ณต๊ฐ„ ์˜ˆ์™ธ์˜ ๊ฒฝ์šฐ).

### ํ•ต์‹ฌ ํ•จ์ˆ˜: `exception_triage()`

ํ•จ์ˆ˜ `exception_triage()`๋Š” ์˜ˆ์™ธ๋ฅผ ๊ฐ€๋Šฅํ•œ ํ•ธ๋“ค๋Ÿฌ ์ฒด์ธ์œผ๋กœ ์ „๋‹ฌํ•˜์—ฌ ์ฒ˜๋ฆฌ๋  ๋•Œ๊นŒ์ง€ ๋˜๋Š” ์ตœ์ข…์ ์œผ๋กœ ์น˜๋ช…์ ์œผ๋กœ ํŒ์ •๋  ๋•Œ๊นŒ์ง€ ๋ผ์šฐํŒ…ํ•ฉ๋‹ˆ๋‹ค. ์ด ํ•จ์ˆ˜๋Š” `osfmk/kern/exception.c`์— ์ •์˜๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.
```c
void exception_triage(exception_type_t exception, mach_exception_data_t code, mach_msg_type_number_t codeCnt);

์ผ๋ฐ˜์ ์ธ ํ˜ธ์ถœ ํ๋ฆ„:

exception_triage() โ””โ”€โ”€ exception_deliver() โ”œโ”€โ”€ exception_deliver_thread() โ”œโ”€โ”€ exception_deliver_task() โ””โ”€โ”€ exception_deliver_host()

๋ชจ๋‘ ์‹คํŒจํ•˜๋ฉด โ†’ bsd_exception()์—์„œ ์ฒ˜๋ฆฌ โ†’ SIGSEGV ๊ฐ™์€ ์‹œ๊ทธ๋„๋กœ ๋ณ€ํ™˜๋œ๋‹ค.

์˜ˆ์™ธ ํฌํŠธ

๊ฐ Mach ๊ฐ์ฒด(thread, task, host)๋Š” ์˜ˆ์™ธ ๋ฉ”์‹œ์ง€๊ฐ€ ์ „์†ก๋˜๋Š” exception ports๋ฅผ ๋“ฑ๋กํ•  ์ˆ˜ ์žˆ๋‹ค.

๋‹ค์Œ API๋กœ ์ •์˜๋œ๋‹ค:

task_set_exception_ports()
thread_set_exception_ports()
host_set_exception_ports()

๊ฐ ์˜ˆ์™ธ ํฌํŠธ๋Š” ๋‹ค์Œ์„ ๊ฐ–์Šต๋‹ˆ๋‹ค:

  • A mask (์–ด๋–ค ์˜ˆ์™ธ๋ฅผ ์ˆ˜์‹ ํ• ์ง€)
  • A port name (Mach port to receive messages)
  • A behavior (์ปค๋„์ด ๋ฉ”์‹œ์ง€๋ฅผ ์–ด๋–ป๊ฒŒ ์ „์†กํ•˜๋Š”์ง€)
  • A flavor (์–ด๋–ค thread state๋ฅผ ํฌํ•จํ• ์ง€)

Debuggers and Exception Handling

A debugger (์˜ˆ: LLDB)๋Š” ๋Œ€์ƒ task๋‚˜ thread์— exception port๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ๋ณดํ†ต task_set_exception_ports()๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด:

  • Mach ๋ฉ”์‹œ์ง€๊ฐ€ debugger ํ”„๋กœ์„ธ์Šค๋กœ ์ „์†ก๋ฉ๋‹ˆ๋‹ค.
  • debugger๋Š” ์˜ˆ์™ธ๋ฅผ ์ฒ˜๋ฆฌํ• ์ง€(resume, ๋ ˆ์ง€์Šคํ„ฐ ์ˆ˜์ •, ๋ช…๋ น์–ด ๊ฑด๋„ˆ๋›ฐ๊ธฐ) ์•„๋‹ˆ๋ฉด ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š์„์ง€ ๊ฒฐ์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • debugger๊ฐ€ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š์œผ๋ฉด ์˜ˆ์™ธ๋Š” ๋‹ค์Œ ๋ ˆ๋ฒจ๋กœ ์ „ํŒŒ๋ฉ๋‹ˆ๋‹ค (task โ†’ host).

Flow of EXC_BAD_ACCESS

  1. Thread๊ฐ€ ์œ ํšจํ•˜์ง€ ์•Š์€ ํฌ์ธํ„ฐ๋ฅผ ์—ญ์ฐธ์กฐ โ†’ CPU๊ฐ€ Data Abort๋ฅผ ๋ฐœ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค.

  2. Kernel์˜ trap handler๊ฐ€ exception_triage(EXC_BAD_ACCESS, ...)๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

  3. ๋ฉ”์‹œ์ง€๊ฐ€ ์ „์†ก๋ฉ๋‹ˆ๋‹ค:

  • Thread port โ†’ (debugger๊ฐ€ breakpoint๋ฅผ ๊ฐ€๋กœ์ฑŒ ์ˆ˜ ์žˆ์Œ).

  • debugger๊ฐ€ ๋ฌด์‹œํ•˜๋ฉด โ†’ Task port โ†’ (ํ”„๋กœ์„ธ์Šค ์ˆ˜์ค€ handler).

  • ๋ฌด์‹œ๋˜๋ฉด โ†’ Host port (๋ณดํ†ต ReportCrash).

  1. ์•„๋ฌด๋„ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š์œผ๋ฉด โ†’ bsd_exception()์ด ์ด๋ฅผ SIGSEGV๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

PAC Exceptions

Pointer Authentication (PAC)์ด ์‹คํŒจ(์„œ๋ช… ๋ถˆ์ผ์น˜)ํ•˜๋ฉด, ํŠน๋ณ„ํ•œ Mach ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค:

  • EXC_ARM_PAC (ํƒ€์ž…)
  • Codes์—๋Š” ์„ธ๋ถ€ ์ •๋ณด๊ฐ€ ํฌํ•จ๋  ์ˆ˜ ์žˆ์Œ(์˜ˆ: key type, pointer type).

๋ฐ”์ด๋„ˆ๋ฆฌ์— TFRO_PAC_EXC_FATAL ํ”Œ๋ž˜๊ทธ๊ฐ€ ์žˆ์œผ๋ฉด, ์ปค๋„์€ PAC ์‹คํŒจ๋ฅผ fatal๋กœ ์ฒ˜๋ฆฌํ•˜์—ฌ debugger์˜ ๊ฐ€๋กœ์ฑ„๊ธฐ๋ฅผ ์šฐํšŒํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ๊ณต๊ฒฉ์ž๊ฐ€ debugger๋ฅผ ์ด์šฉํ•ด PAC ์ฒดํฌ๋ฅผ ์šฐํšŒํ•˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•œ ๊ฒƒ์œผ๋กœ, platform binaries์— ๋Œ€ํ•ด ํ™œ์„ฑํ™”๋ฉ๋‹ˆ๋‹ค.

Software Breakpoints

์†Œํ”„ํŠธ์›จ์–ด breakpoint(int3 on x86, brk on ARM64)๋Š” ์˜๋„์ ์ธ fault๋ฅผ ์ผ์œผ์ผœ ๊ตฌํ˜„๋ฉ๋‹ˆ๋‹ค.
debugger๋Š” exception port๋ฅผ ํ†ตํ•ด ์ด๋ฅผ ์žก์Šต๋‹ˆ๋‹ค:

  • instruction pointer๋‚˜ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ˆ˜์ •ํ•ฉ๋‹ˆ๋‹ค.
  • ์›๋ž˜์˜ ๋ช…๋ น์–ด๋ฅผ ๋ณต์›ํ•ฉ๋‹ˆ๋‹ค.
  • ์‹คํ–‰์„ ์žฌ๊ฐœํ•ฉ๋‹ˆ๋‹ค.

์ด ๋™์ผํ•œ ๋ฉ”์ปค๋‹ˆ์ฆ˜ ๋•Œ๋ฌธ์— PAC ์˜ˆ์™ธ๋ฅผ โ€œcatchโ€œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค โ€” **๋‹จ, TFRO_PAC_EXC_FATAL**์ด ์„ค์ •๋œ ๊ฒฝ์šฐ์—๋Š” debugger์— ๋„๋‹ฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

Conversion to BSD Signals

์–ด๋–ค handler๋„ ์˜ˆ์™ธ๋ฅผ ์ˆ˜๋ฝํ•˜์ง€ ์•Š์œผ๋ฉด:

  • ์ปค๋„์€ task_exception_notify() โ†’ bsd_exception()์„ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

  • ์ด๋Š” Mach ์˜ˆ์™ธ๋ฅผ ์‹œ๊ทธ๋„๋กœ ๋งคํ•‘ํ•ฉ๋‹ˆ๋‹ค:

Mach ExceptionSignal
EXC_BAD_ACCESSSIGSEGV or SIGBUS
EXC_BAD_INSTRUCTIONSIGILL
EXC_ARITHMETICSIGFPE
EXC_SOFTWARESIGTRAP
EXC_BREAKPOINTSIGTRAP
EXC_CRASHSIGKILL
EXC_ARM_PACSIGILL (on non-fatal)

###ย Key Files in XNU Source

  • osfmk/kern/exception.c โ†’ exception_triage(), exception_deliver_*()์˜ ํ•ต์‹ฌ.

  • bsd/kern/kern_sig.c โ†’ ์‹œ๊ทธ๋„ ์ „๋‹ฌ ๋กœ์ง.

  • osfmk/arm64/trap.c โ†’ ์ €์ˆ˜์ค€ trap handlers.

  • osfmk/mach/exc.h โ†’ ์˜ˆ์™ธ ์ฝ”๋“œ์™€ ๊ตฌ์กฐ์ฒด.

  • osfmk/kern/task.c โ†’ Task exception port ์„ค์ •.


Old Kernel Heap (Pre-iOS 15 / Pre-A12 era)

์ปค๋„์€ zone allocator(kalloc)๋ฅผ ์‚ฌ์šฉํ–ˆ์œผ๋ฉฐ, ๊ณ ์ • ํฌ๊ธฐ์˜ โ€œzonesโ€œ๋กœ ๋‚˜๋‰˜์–ด ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.
๊ฐ zone์€ ๋‹จ์ผ ํฌ๊ธฐ ํด๋ž˜์Šค์˜ ํ• ๋‹น๋งŒ ์ €์žฅํ–ˆ์Šต๋‹ˆ๋‹ค.

์Šคํฌ๋ฆฐ์ƒท์—์„œ:

Zone NameElement SizeExample Use
default.kalloc.1616 bytesVery small kernel structs, pointers.
default.kalloc.3232 bytesSmall structs, object headers.
default.kalloc.6464 bytesIPC messages, tiny kernel buffers.
default.kalloc.128128 bytesMedium objects like parts of OSObject.
โ€ฆโ€ฆโ€ฆ
default.kalloc.12801280 bytesLarge structures, IOSurface/graphics metadata.

๋™์ž‘ ๋ฐฉ์‹:

  • ๊ฐ ํ• ๋‹น ์š”์ฒญ์€ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด zone ํฌ๊ธฐ๋กœ ์˜ฌ๋ฆผ(round up) ๋ฉ๋‹ˆ๋‹ค. (์˜ˆ: 50๋ฐ”์ดํŠธ ์š”์ฒญ์€ kalloc.64 zone์— ํ• ๋‹น๋ฉ๋‹ˆ๋‹ค).
  • ๊ฐ zone์˜ ๋ฉ”๋ชจ๋ฆฌ๋Š” freelist์— ๋ณด๊ด€๋˜์—ˆ์Šต๋‹ˆ๋‹ค โ€” ์ปค๋„์ด ํ•ด์ œํ•œ ์ฒญํฌ๋Š” ํ•ด๋‹น zone์œผ๋กœ ๋˜๋Œ์•„๊ฐ”์Šต๋‹ˆ๋‹ค.
  • 64๋ฐ”์ดํŠธ ๋ฒ„ํผ๋ฅผ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐํ•˜๋ฉด, ๋™์ผ zone์˜ ๋‹ค์Œ ๊ฐ์ฒด๋ฅผ ๋ฎ์–ด์“ฐ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์ด ๋•Œ๋ฌธ์— heap spraying / feng shui๊ฐ€ ๋งค์šฐ ํšจ๊ณผ์ ์ด์—ˆ์Šต๋‹ˆ๋‹ค: ๊ฐ™์€ ํฌ๊ธฐ ํด๋ž˜์Šค๋กœ ํ• ๋‹น์„ ๋ฟŒ๋ฆฌ๋ฉด ๊ฐ์ฒด ์ด์›ƒ์„ ์˜ˆ์ธกํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

The freelist

๊ฐ kalloc zone ๋‚ด๋ถ€์—์„œ, ํ•ด์ œ๋œ ๊ฐ์ฒด๋“ค์€ ์‹œ์Šคํ…œ์— ์ง์ ‘ ๋ฐ˜ํ™˜๋˜์ง€ ์•Š๊ณ  freelist์— ๋“ค์–ด๊ฐ”์Šต๋‹ˆ๋‹ค. freelist๋Š” ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์ฒญํฌ๋“ค์˜ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์ž…๋‹ˆ๋‹ค.

  • ์ฒญํฌ๊ฐ€ ํ•ด์ œ๋˜๋ฉด, ์ปค๋„์€ ๊ทธ ์ฒญํฌ์˜ ์‹œ์ž‘ ๋ถ€๋ถ„์— ํฌ์ธํ„ฐ๋ฅผ ์”๋‹ˆ๋‹ค โ†’ ๊ฐ™์€ zone์˜ ๋‹ค์Œ free ์ฒญํฌ ์ฃผ์†Œ.

  • zone์€ ์ฒซ ๋ฒˆ์งธ free ์ฒญํฌ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” HEAD ํฌ์ธํ„ฐ๋ฅผ ์œ ์ง€ํ–ˆ์Šต๋‹ˆ๋‹ค.

  • ํ• ๋‹น์€ ํ•ญ์ƒ ํ˜„์žฌ HEAD๋ฅผ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค:

  1. HEAD๋ฅผ ํŒ(pop) (๊ทธ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ˜ธ์ถœ์ž์— ๋ฐ˜ํ™˜).

  2. HEAD = HEAD->next๋กœ ์—…๋ฐ์ดํŠธ (ํ•ด์ œ๋œ ์ฒญํฌ์˜ ํ—ค๋”์— ์ €์žฅ๋œ ๊ฐ’).

  • ํ•ด์ œ๋Š” ์ฒญํฌ๋ฅผ ๋‹ค์‹œ ํ‘ธ์‹œ(push)ํ–ˆ์Šต๋‹ˆ๋‹ค:

  • freed_chunk->next = HEAD

  • HEAD = freed_chunk

๋”ฐ๋ผ์„œ freelist๋Š” ํ•ด์ œ๋œ ๋ฉ”๋ชจ๋ฆฌ ์ž์ฒด ์•ˆ์— ๊ตฌ์ถ•๋œ ๋‹จ์ˆœํ•œ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์˜€์Šต๋‹ˆ๋‹ค.

Normal state:

Zone page (64-byte chunks for example):
[ A ] [ F ] [ F ] [ A ] [ F ] [ A ] [ F ]

Freelist view:
HEAD โ”€โ”€โ–บ [ F ] โ”€โ”€โ–บ [ F ] โ”€โ”€โ–บ [ F ] โ”€โ”€โ–บ [ F ] โ”€โ”€โ–บ NULL
(next ptrs stored at start of freed chunks)

freelist ์•…์šฉ

free chunk์˜ ์ฒซ 8 bytes๊ฐ€ freelist pointer์™€ ๊ฐ™๊ธฐ ๋•Œ๋ฌธ์—, ๊ณต๊ฒฉ์ž๋Š” ์ด๋ฅผ ์†์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค:

  1. Heap overflow๋กœ ์ธ์ ‘ํ•œ freed chunk์— ์นจ๋ฒ” โ†’ ๊ทธ โ€œnextโ€ pointer๋ฅผ ๋ฎ์–ด์“ฐ๊ธฐ.

  2. Use-after-free๋กœ freed object์— ์“ฐ๊ธฐ โ†’ ๊ทธ โ€œnextโ€ pointer๋ฅผ ๋ฎ์–ด์“ฐ๊ธฐ.

๊ทธ ๋‹ค์Œ, ํ•ด๋‹น ํฌ๊ธฐ์˜ ๋‹ค์Œ ํ• ๋‹น ์‹œ:

  • allocator๊ฐ€ ์†์ƒ๋œ chunk๋ฅผ ๊บผ๋‚ธ๋‹ค.
  • ๊ณต๊ฒฉ์ž๊ฐ€ ์ œ๊ณตํ•œ โ€œnextโ€ pointer๋ฅผ ๋”ฐ๋ฅธ๋‹ค.
  • ์ž„์˜ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ํฌ์ธํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•˜์—ฌ fake object primitives๋‚˜ targeted overwrite๋ฅผ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•œ๋‹ค.

Visual example of freelist poisoning:

Before corruption:
HEAD โ”€โ”€โ–บ [ F1 ] โ”€โ”€โ–บ [ F2 ] โ”€โ”€โ–บ [ F3 ] โ”€โ”€โ–บ NULL

After attacker overwrite of F1->next:
HEAD โ”€โ”€โ–บ [ F1 ]
(next) โ”€โ”€โ–บ 0xDEAD_BEEF_CAFE_BABE  (attacker-chosen)

Next alloc of this zone โ†’ kernel hands out memory at attacker-controlled address.

์ด freelist ์„ค๊ณ„๋Š” ํ•˜๋“œ๋‹ ์ด์ „์— ์ต์Šคํ”Œ๋กœ์ž‡์„ ๋งค์šฐ ํšจ๊ณผ์ ์œผ๋กœ ๋งŒ๋“ค์—ˆ๋‹ค: heap sprays๋กœ ์ธํ•œ ์˜ˆ์ธก ๊ฐ€๋Šฅํ•œ ์ด์›ƒ, ์›์‹œ ํฌ์ธํ„ฐ freelist ๋งํฌ, ๊ทธ๋ฆฌ๊ณ  ํƒ€์ž… ๋ถ„๋ฆฌ๊ฐ€ ์—†์–ด ๊ณต๊ฒฉ์ž๊ฐ€ UAF/overflow ๋ฒ„๊ทธ๋ฅผ ์ž„์˜์˜ ์ปค๋„ ๋ฉ”๋ชจ๋ฆฌ ์ œ์–ด๋กœ ํ™•์žฅํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

Heap Grooming / Feng Shui

The goal of heap grooming is to ํž™ ๋ ˆ์ด์•„์›ƒ์„ ์กฐ์„ฑํ•˜๋Š” ๊ฒƒ so that when an attacker triggers an overflow or use-after-free, the target (victim) object sits right next to an attacker-controlled object.
๊ทธ๋ ‡๊ฒŒ ํ•˜๋ฉด ๋ฉ”๋ชจ๋ฆฌ ์†์ƒ์ด ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ๊ณต๊ฒฉ์ž๋Š” victim ๊ฐ์ฒด๋ฅผ ์ œ์–ด๋œ ๋ฐ์ดํ„ฐ๋กœ ์‹ ๋ขฐ์„ฑ ์žˆ๊ฒŒ ๋ฎ์–ด์“ธ ์ˆ˜ ์žˆ๋‹ค.

Steps:

  1. Spray allocations (fill the holes)
  • ์‹œ๊ฐ„์ด ์ง€๋‚˜๋ฉด ์ปค๋„ ํž™์€ ๋‹จํŽธํ™”๋œ๋‹ค: ์˜ค๋ž˜๋œ ๊ฐ์ฒด๋“ค์ด free๋˜๋ฉด์„œ ๊ตฌ๋ฉ(hole)์ด ์ƒ๊ธด๋‹ค.
  • ๊ณต๊ฒฉ์ž๋Š” ๋จผ์ € ๋งŽ์€ ๋”๋ฏธ ํ• ๋‹น์„ ๋งŒ๋“ค์–ด ์ด๋Ÿฌํ•œ ๋นˆํ‹ˆ์„ ์ฑ„์›Œ ํž™์„ โ€œ๋นฝ๋นฝํ•˜๊ฒŒโ€ ๋งŒ๋“ค์–ด ์˜ˆ์ธก ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋งŒ๋“ ๋‹ค.
  1. Force new pages
  • ๊ตฌ๋ฉ์ด ์ฑ„์›Œ์ง€๋ฉด ๋‹ค์Œ ํ• ๋‹น์€ zone์— ์ƒˆ๋กœ ์ถ”๊ฐ€๋œ ํŽ˜์ด์ง€์—์„œ ํ• ๋‹น๋˜์–ด์•ผ ํ•œ๋‹ค.
  • ์ƒˆ ํŽ˜์ด์ง€๋Š” ๊ฐ์ฒด๋“ค์ด ํฉ์–ด์ง€์ง€ ์•Š๊ณ  ํด๋Ÿฌ์Šคํ„ฐ๋ง๋˜๊ฒŒ ํ•œ๋‹ค.
  • ์ด๋Š” ๊ณต๊ฒฉ์ž๊ฐ€ ์ด์›ƒ ์ œ์–ด๋ฅผ ํ›จ์”ฌ ์ž˜ ํ•˜๊ฒŒ ํ•ด์ค€๋‹ค.
  1. Place attacker objects
  • ๊ณต๊ฒฉ์ž๋Š” ๋‹ค์‹œ ์Šคํ”„๋ ˆ์ดํ•˜์—ฌ ๊ทธ ์ƒˆ ํŽ˜์ด์ง€๋“ค์— ๋งŽ์€ ๊ณต๊ฒฉ์ž ์ œ์–ด ๊ฐ์ฒด๋“ค์„ ๋งŒ๋“ ๋‹ค.
  • ์ด ๊ฐ์ฒด๋“ค์€ ๋ชจ๋‘ ๊ฐ™์€ zone์— ์†ํ•˜๋ฏ€๋กœ ํฌ๊ธฐ์™€ ๋ฐฐ์น˜๊ฐ€ ์˜ˆ์ธก ๊ฐ€๋Šฅํ•˜๋‹ค.
  1. Free a controlled object (make a gap)
  • ๊ณต๊ฒฉ์ž๋Š” ์˜๋„์ ์œผ๋กœ ์ž์‹ ์˜ ๊ฐ์ฒด ์ค‘ ํ•˜๋‚˜๋ฅผ freeํ•œ๋‹ค.
  • ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ํ• ๋‹น์ž๊ฐ€ ์ดํ›„ ๊ฐ™์€ ํฌ๊ธฐ์˜ ๋‹ค์Œ ํ• ๋‹น์„ ์œ„ํ•ด ์žฌ์‚ฌ์šฉํ•  โ€œ๊ตฌ๋ฉโ€์ด ์ƒ๊ธด๋‹ค.
  1. Victim object lands in the hole
  • ๊ณต๊ฒฉ์ž๋Š” ์ปค๋„์ด victim ๊ฐ์ฒด(์†์ƒํ•˜๋ ค๋Š” ๊ฐ์ฒด)๋ฅผ ํ• ๋‹นํ•˜๋„๋ก ํŠธ๋ฆฌ๊ฑฐํ•œ๋‹ค.
  • ๊ตฌ๋ฉ์ด freelist์—์„œ ๊ฐ€์žฅ ๋จผ์ € ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์Šฌ๋กฏ์ด๋ฏ€๋กœ, victim์€ ๊ณต๊ฒฉ์ž๊ฐ€ freeํ•œ ๋ฐ”๋กœ ๊ทธ ์œ„์น˜์— ๋†“์ธ๋‹ค.
  1. Overflow / UAF into victim
  • ์ด์ œ ๊ณต๊ฒฉ์ž๋Š” victim ์ฃผ์œ„์— ๊ณต๊ฒฉ์ž ์ œ์–ด ๊ฐ์ฒด๋“ค์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.
  • ์ž์‹ ์˜ ๊ฐ์ฒด์—์„œ overflowํ•˜๊ฑฐ๋‚˜ freed ๊ฐ์ฒด๋ฅผ ์žฌ์‚ฌ์šฉํ•จ์œผ๋กœ์จ, ๊ณต๊ฒฉ์ž๋Š” victim์˜ ๋ฉ”๋ชจ๋ฆฌ ํ•„๋“œ๋ฅผ ์„ ํƒํ•œ ๊ฐ’์œผ๋กœ ์‹ ๋ขฐ์„ฑ ์žˆ๊ฒŒ ๋ฎ์–ด์“ธ ์ˆ˜ ์žˆ๋‹ค.

Why it works:

  • Zone allocator์˜ ์˜ˆ์ธก์„ฑ: ๊ฐ™์€ ํฌ๊ธฐ์˜ ํ• ๋‹น์€ ํ•ญ์ƒ ๊ฐ™์€ zone์—์„œ ์˜จ๋‹ค.
  • Freelist ๋™์ž‘: ์ƒˆ๋กœ์šด ํ• ๋‹น์€ ๊ฐ€์žฅ ์ตœ๊ทผ์— free๋œ ์ฒญํฌ๋ฅผ ์šฐ์„  ์žฌ์‚ฌ์šฉํ•œ๋‹ค.
  • Heap sprays: ๊ณต๊ฒฉ์ž๊ฐ€ ์˜ˆ์ธก ๊ฐ€๋Šฅํ•œ ๋‚ด์šฉ์œผ๋กœ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ฑ„์šฐ๊ณ  ๋ ˆ์ด์•„์›ƒ์„ ์ œ์–ดํ•œ๋‹ค.
  • ๊ฒฐ๊ณผ: ๊ณต๊ฒฉ์ž๋Š” victim ๊ฐ์ฒด๊ฐ€ ์–ด๋””์— ๋†“์ผ์ง€์™€ ๊ทธ ์˜†์— ์–ด๋–ค ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ์„์ง€๋ฅผ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋‹ค.

Modern Kernel Heap (iOS 15+/A12+ SoCs)

Apple์€ allocator๋ฅผ ํ•˜๋“œ๋‹ํ•˜์—ฌ heap grooming์„ ํ›จ์”ฌ ๋” ์–ด๋ ต๊ฒŒ ๋งŒ๋“ค์—ˆ๋‹ค:

1. From Classic kalloc to kalloc_type

  • Before: ๊ฐ ์‚ฌ์ด์ฆˆ ํด๋ž˜์Šค(16, 32, 64, โ€ฆ 1280 ๋“ฑ)์— ๋Œ€ํ•ด ๋‹จ์ผ kalloc.<size> zone์ด ์กด์žฌํ–ˆ๋‹ค. ๊ทธ ํฌ๊ธฐ์˜ ์–ด๋–ค ๊ฐ์ฒด๋“  ๊ฑฐ๊ธฐ์— ๋ฐฐ์น˜๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— โ†’ ๊ณต๊ฒฉ์ž ๊ฐ์ฒด๊ฐ€ ํŠน๊ถŒ ์ปค๋„ ๊ฐ์ฒด ์˜†์— ๋†“์ผ ์ˆ˜ ์žˆ์—ˆ๋‹ค.
  • Now:
  • ์ปค๋„ ๊ฐ์ฒด๋Š” typed zones(kalloc_type)์—์„œ ํ• ๋‹น๋œ๋‹ค.
  • ๊ฐ ๊ฐ์ฒด ํƒ€์ž…(e.g., ipc_port_t, task_t, OSString, OSData)์€ ํฌ๊ธฐ๊ฐ€ ๊ฐ™๋”๋ผ๋„ ์ „์šฉ zone์„ ๊ฐ€์ง„๋‹ค.
  • ๊ฐ์ฒด ํƒ€์ž… โ†” zone ๊ฐ„์˜ ๋งคํ•‘์€ ์ปดํŒŒ์ผ ์‹œ kalloc_type system์—์„œ ์ƒ์„ฑ๋œ๋‹ค.

๊ณต๊ฒฉ์ž๋Š” ๋” ์ด์ƒ ์ œ์–ด ๋ฐ์ดํ„ฐ(OSData)๊ฐ€ ๊ฐ™์€ ํฌ๊ธฐ์˜ ๋ฏผ๊ฐํ•œ ์ปค๋„ ๊ฐ์ฒด(task_t) ์˜†์— ๋ฐ˜๋“œ์‹œ ๋†“์ผ ๊ฒƒ์ด๋ผ๊ณ  ๋ณด์žฅํ•  ์ˆ˜ ์—†๋‹ค.

2. Slabs and Per-CPU Caches

  • ํž™์€ ๊ฐ zone์„ ์œ„ํ•œ ๊ณ ์ • ํฌ๊ธฐ ์ฒญํฌ๋กœ ๋‚˜๋‰œ slabs(๋ฉ”๋ชจ๋ฆฌ ํŽ˜์ด์ง€๋“ค)๋กœ ๋ถ„ํ• ๋œ๋‹ค.
  • ๊ฐ zone์€ ๊ฒฝ์Ÿ์„ ์ค„์ด๊ธฐ ์œ„ํ•ด per-CPU cache๋ฅผ ๊ฐ€์ง„๋‹ค.
  • ํ• ๋‹น ๊ฒฝ๋กœ:
  1. per-CPU cache๋ฅผ ์‹œ๋„.
  2. ๋น„์–ด ์žˆ์œผ๋ฉด global freelist์—์„œ ๊ฐ€์ ธ์˜ด.
  3. freelist๊ฐ€ ๋น„์–ด ์žˆ์œผ๋ฉด ์ƒˆ๋กœ์šด slab(ํ•˜๋‚˜ ์ด์ƒ์˜ ํŽ˜์ด์ง€)๋ฅผ ํ• ๋‹น.
  • ์ด์ : ์ด ๋ถ„์‚ฐํ™”๋Š” ํ• ๋‹น์ด ๋‹ค๋ฅธ CPU๋“ค์˜ ์บ์‹œ์—์„œ ์ถฉ์กฑ๋  ์ˆ˜ ์žˆ์–ด heap sprays๋ฅผ ๋œ ๊ฒฐ์ •๋ก ์ ์œผ๋กœ ๋งŒ๋“ ๋‹ค.

3. Randomization inside zones

  • zone ๋‚ด์—์„œ freed ์š”์†Œ๋“ค์ด ๋‹จ์ˆœํ•œ FIFO/LIFO ์ˆœ์„œ๋กœ ๋ฐ˜ํ™˜๋˜์ง€ ์•Š๋Š”๋‹ค.
  • ์ตœ์‹  XNU๋Š” encoded freelist pointers(Linux์˜ safe-linking๊ณผ ์œ ์‚ฌ, ์•ฝ iOS 14๋ถ€ํ„ฐ ๋„์ž…)๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
  • ๊ฐ freelist ํฌ์ธํ„ฐ๋Š” per-zone secret cookie๋กœ XOR ์ธ์ฝ”๋”ฉ๋œ๋‹ค.
  • ์ด๋Š” ๊ณต๊ฒฉ์ž๊ฐ€ write primitive๋ฅผ ์–ป๋”๋ผ๋„ ๊ฐ€์งœ freelist ํฌ์ธํ„ฐ๋ฅผ ์œ„์กฐํ•˜์ง€ ๋ชปํ•˜๊ฒŒ ํ•œ๋‹ค.
  • ์ผ๋ถ€ ํ• ๋‹น์€ slab ๋‚ด ๋ฐฐ์น˜๊ฐ€ ๋ฌด์ž‘์œ„ํ™”๋˜์–ด ์Šคํ”„๋ ˆ์ด๊ฐ€ ์ธ์ ‘์„ฑ์„ ๋ณด์žฅํ•˜์ง€ ๋ชปํ•œ๋‹ค.

4. Guarded Allocations

  • ํŠน์ • ์ค‘์š”ํ•œ ์ปค๋„ ๊ฐ์ฒด(e.g., credentials, task structures)๋Š” guarded zones์— ํ• ๋‹น๋œ๋‹ค.
  • ์ด๋Ÿฌํ•œ zone์€ slab ์‚ฌ์ด์— guard pages(์–ธ๋งคํ•‘๋œ ๋ฉ”๋ชจ๋ฆฌ)๋ฅผ ์‚ฝ์ž…ํ•˜๊ฑฐ๋‚˜ ๊ฐ์ฒด ์ฃผ๋ณ€์— redzones๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
  • guard page๋กœ์˜ ์–ด๋–ค overflow๋„ ์ฆ‰์‹œ fault๋ฅผ ์ผ์œผ์ผœ โ†’ ๋ฌด์Œ์˜ ์†์ƒ ๋Œ€์‹  ์ฆ‰์‹œ panic์„ ์œ ๋ฐœํ•œ๋‹ค.

5. Page Protection Layer (PPL) and SPTM

  • ์„ค๋ น freed ๊ฐ์ฒด๋ฅผ ์ œ์–ดํ•˜๋”๋ผ๋„ ๋ชจ๋“  ์ปค๋„ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค:
  • **PPL (Page Protection Layer)**๋Š” ํŠน์ • ์˜์—ญ(e.g., code signing ๋ฐ์ดํ„ฐ, entitlements)์ด ์ปค๋„ ์ž์ฒด์—๋„ read-only๋กœ ๊ฐ•์ œ๋˜๋„๋ก ํ•œ๋‹ค.
  • A15/M2+ ์žฅ์น˜์—์„œ๋Š” ์ด ์—ญํ• ์ด SPTM (Secure Page Table Monitor) + **TXM (Trusted Execution Monitor)**๋กœ ๋Œ€์ฒด/๊ฐ•ํ™”๋œ๋‹ค.
  • ์ด๋Ÿฌํ•œ ํ•˜๋“œ์›จ์–ด ๊ฐ•์ œ ๊ณ„์ธต์€ ๊ณต๊ฒฉ์ž๊ฐ€ ๋‹จ์ผ ํž™ ์†์ƒ์—์„œ ์ค‘์š”ํ•œ ๋ณด์•ˆ ๊ตฌ์กฐ๋ฅผ ์ž„์˜๋กœ ํŒจ์น˜ํ•  ์ˆ˜ ์—†๊ฒŒ ๋งŒ๋“ ๋‹ค.
  • (Added / Enhanced): ๋˜ํ•œ ์ปค๋„์—์„œ๋Š” ํฌ์ธํ„ฐ(ํŠนํžˆ ํ•จ์ˆ˜ ํฌ์ธํ„ฐ, vtables)๋ฅผ ๋ณดํ˜ธํ•˜๊ธฐ ์œ„ํ•ด **PAC (Pointer Authentication Codes)**๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์œ„์กฐ๋‚˜ ์†์ƒ์ด ๋” ์–ด๋ ค์›Œ์กŒ๋‹ค.
  • (Added / Enhanced): zones๋Š” zone_require / zone enforcement๋ฅผ ์‹œํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ฆ‰, free๋œ ๊ฐ์ฒด๋Š” ์˜ฌ๋ฐ”๋ฅธ typed zone์„ ํ†ตํ•ด์„œ๋งŒ ๋ฐ˜ํ™˜๋˜์–ด์•ผ ํ•˜๋ฉฐ, ์ž˜๋ชป๋œ cross-zone free๋Š” panic๋˜๊ฑฐ๋‚˜ ๊ฑฐ๋ถ€๋  ์ˆ˜ ์žˆ๋‹ค. (Apple์€ ๋ฉ”๋ชจ๋ฆฌ ์•ˆ์ „ ๊ด€๋ จ ํฌ์ŠคํŠธ์—์„œ ์ด๋ฅผ ์–ธ๊ธ‰ํ•œ๋‹ค)

6. Large Allocations

  • ๋ชจ๋“  ํ• ๋‹น์ด kalloc_type์„ ํ†ตํ•˜์ง€๋Š” ์•Š๋Š”๋‹ค.
  • ๋งค์šฐ ํฐ ์š”์ฒญ(๋Œ€๋žต ~16 KB ์ด์ƒ)์€ typed zones๋ฅผ ์šฐํšŒํ•˜๊ณ  ํŽ˜์ด์ง€ ํ• ๋‹น์„ ํ†ตํ•ด **kernel VM (kmem)**์—์„œ ์ง์ ‘ ์„œ๋น„์Šค๋œ๋‹ค.
  • ์ด๋Ÿฌํ•œ ํ• ๋‹น์€ ๋œ ์˜ˆ์ธก ๊ฐ€๋Šฅํ•˜์ง€๋งŒ, ๋‹ค๋ฅธ ๊ฐ์ฒด๋“ค๊ณผ slab๋ฅผ ๊ณต์œ ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— exploitable ๊ฐ€๋Šฅ์„ฑ๋„ ๋‚ฎ๋‹ค.

7. Allocation Patterns Attackers Target

์ด๋Ÿฌํ•œ ๋ณดํ˜ธ๊ฐ€ ์žˆ์–ด๋„ ๊ณต๊ฒฉ์ž๋“ค์ด ์—ฌ์ „ํžˆ ๋…ธ๋ฆฌ๋Š” ๊ฒƒ๋“ค:

  • Reference count objects: retain/release ์นด์šดํ„ฐ๋ฅผ ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด use-after-free๋ฅผ ์œ ๋ฐœํ•  ์ˆ˜ ์žˆ๋‹ค.
  • Objects with function pointers (vtables): ์ด๋ฅผ ์†์ƒ์‹œํ‚ค๋ฉด ์—ฌ์ „ํžˆ ์ œ์–ด ํ๋ฆ„์„ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค.
  • Shared memory objects (IOSurface, Mach ports): ์ด๋“ค์€ user โ†” kernel์„ ์—ฐ๊ฒฐํ•˜๋ฏ€๋กœ ์—ฌ์ „ํžˆ ๊ณต๊ฒฉ ๋Œ€์ƒ์ด๋‹ค.

ํ•˜์ง€๋งŒ โ€” ๊ณผ๊ฑฐ์™€ ๋‹ฌ๋ฆฌ โ€” ๋‹จ์ˆœํžˆ OSData๋ฅผ ์Šคํ”„๋ ˆ์ดํ•ด์„œ task_t ์˜†์— ๋†“์ด๊ธธ ๊ธฐ๋Œ€ํ•  ์ˆ˜๋Š” ์—†๋‹ค. ์„ฑ๊ณตํ•˜๋ ค๋ฉด type-specific bugs๋‚˜ **์ •๋ณด ๋ˆ„์ถœ(info leaks)**์ด ํ•„์š”ํ•˜๋‹ค.

Example: Allocation Flow in Modern Heap

Suppose userspace calls into IOKit to allocate an OSData object:

  1. Type lookup โ†’ OSData maps to kalloc_type_osdata zone (size 64 bytes).
  2. Check per-CPU cache for free elements.
  • If found โ†’ return one.
  • If empty โ†’ go to global freelist.
  • If freelist empty โ†’ allocate a new slab (page of 4KB โ†’ 64 chunks of 64 bytes).
  1. Return chunk to caller.

Freelist pointer protection:

  • Each freed chunk stores the address of the next free chunk, but encoded with a secret key.
  • Overwriting that field with attacker data wonโ€™t work unless you know the key.

Comparison Table

FeatureOld Heap (Pre-iOS 15)Modern Heap (iOS 15+ / A12+)
Allocation granularityFixed size buckets (kalloc.16, kalloc.32, etc.)Size + type-based buckets (kalloc_type)
Placement predictabilityHigh (same-size objects side by side)Low (same-type grouping + randomness)
Freelist managementRaw pointers in freed chunks (easy to corrupt)Encoded pointers (safe-linking style)
Adjacent object controlEasy via sprays/frees (feng shui predictable)Hard โ€” typed zones separate attacker objects
Kernel data/code protectionsFew hardware protectionsPPL / SPTM protect page tables & code pages, and PAC protects pointers
Allocation reuse validationNone (freelist pointers raw)zone_require / zone enforcement
Exploit reliabilityHigh with heap spraysMuch lower, requires logic bugs or info leaks
Large allocations handlingAll small allocations managed equallyLarge ones bypass zones โ†’ handled via VM

Modern Userland Heap (iOS, macOS โ€” type-aware / xzone malloc)

์ตœ๊ทผ Apple OS ๋ฒ„์ „(ํŠนํžˆ iOS 17+)์—์„œ Apple์€ ์‚ฌ์šฉ์ž ๊ณต๊ฐ„ allocator์ธ xzone malloc(XZM)์„ ๋„์ž…ํ–ˆ๋‹ค. ์ด๋Š” ์ปค๋„์˜ kalloc_type์— ๋Œ€์‘ํ•˜๋Š” ์‚ฌ์šฉ์ž ๊ณต๊ฐ„ ์•„๋‚ ๋กœ๊ทธ๋กœ, ํƒ€์ž… ์ธ์‹, ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ๋ถ„๋ฆฌ, ๋ฉ”๋ชจ๋ฆฌ ํƒœ๊น… ์™„ํ™” ๊ธฐ๋Šฅ์„ ์ ์šฉํ•œ๋‹ค.

Goals & Design Principles

  • Type segregation / type awareness: ํƒ€์ž… ๋˜๋Š” ์‚ฌ์šฉ(ํฌ์ธํ„ฐ ๋Œ€ ๋ฐ์ดํ„ฐ)๋ณ„๋กœ ํ• ๋‹น์„ ๊ทธ๋ฃนํ™”ํ•˜์—ฌ ํƒ€์ž… ํ˜ผ๋™๊ณผ ๊ต์ฐจ ํƒ€์ž… ์žฌ์‚ฌ์šฉ์„ ๋ฐฉ์ง€.
  • Metadata isolation: ํž™ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ(e.g. free lists, size/state ๋น„ํŠธ)๋ฅผ ๊ฐ์ฒด ํŽ˜์ด๋กœ๋“œ์™€ ๋ถ„๋ฆฌํ•˜์—ฌ OOB ์“ฐ๊ธฐ๊ฐ€ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ์†์ƒ์‹œํ‚ค๊ธฐ ์–ด๋ ต๊ฒŒ ํ•จ.
  • Guard pages / redzones: ์–ธ๋งคํ•‘๋œ ํŽ˜์ด์ง€๋‚˜ ํŒจ๋”ฉ์„ ์‚ฝ์ž…ํ•˜์—ฌ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ๋ฅผ ํฌ์ฐฉ.
  • Memory tagging (EMTE / MIE): ํ•˜๋“œ์›จ์–ด ํƒœ๊น…๊ณผ ํ•จ๊ป˜ ์ž‘๋™ํ•˜์—ฌ use-after-free, OOB, ์ž˜๋ชป๋œ ์ ‘๊ทผ์„ ํƒ์ง€.
  • Scalable performance: ๋‚ฎ์€ ์˜ค๋ฒ„ํ—ค๋“œ ์œ ์ง€, ๊ณผ๋„ํ•œ ๋‹จํŽธํ™” ํšŒํ”ผ, ์ดˆ๋‹น ๋งŽ์€ ํ• ๋‹น์„ ๋‚ฎ์€ ์ง€์—ฐ์œผ๋กœ ์ง€์›.

Architecture & Components

์•„๋ž˜๋Š” xzone allocator์˜ ์ฃผ์š” ์š”์†Œ๋“ค์ด๋‹ค:

Segment Groups & Zones

  • Segment groups๋Š” ์ฃผ์†Œ ๊ณต๊ฐ„์„ ์‚ฌ์šฉ ์นดํ…Œ๊ณ ๋ฆฌ๋ณ„๋กœ ๋ถ„ํ• : ์˜ˆ) data, pointer_xzones, data_large, pointer_large.
  • ๊ฐ segment group์€ ํ•ด๋‹น ์นดํ…Œ๊ณ ๋ฆฌ์˜ ํ• ๋‹น์„ ํ˜ธ์ŠคํŒ…ํ•˜๋Š” segments(VM ๋ฒ”์œ„)๋ฅผ ํฌํ•จํ•œ๋‹ค.
  • ๊ฐ segment์™€ ์—ฐ๊ด€๋œ metadata slab(๋ณ„๋„์˜ VM ์˜์—ญ)๊ฐ€ ์žˆ์–ด ํ•ด๋‹น segment์˜ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ(e.g. free/used ๋น„ํŠธ, size classes)๋ฅผ ์ €์žฅํ•œ๋‹ค. ์ด out-of-line (OOL) metadata๋Š” ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๊ฐ€ ๊ฐ์ฒด ํŽ˜์ด๋กœ๋“œ์™€ ์„ž์ด์ง€ ์•Š๋„๋ก ํ•˜์—ฌ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ๋กœ ์ธํ•œ ์†์ƒ์„ ์™„ํ™”ํ•œ๋‹ค.
  • Segments๋Š” chunks(์Šฌ๋ผ์ด์Šค)๋กœ ์ชผ๊ฐœ์ง€๊ณ , ๊ฐ chunk๋Š” ๋‹ค์‹œ blocks(ํ• ๋‹น ๋‹จ์œ„)๋กœ ์„ธ๋ถ„ํ™”๋œ๋‹ค. ํ•˜๋‚˜์˜ chunk๋Š” ํŠน์ • ์‚ฌ์ด์ฆˆ ํด๋ž˜์Šค์™€ segment group์— ๋ฌถ์—ฌ ์žˆ๋‹ค(์ฆ‰, chunk ๋‚ด๋ถ€์˜ ๋ชจ๋“  block์€ ๊ฐ™์€ ํฌ๊ธฐ & ์นดํ…Œ๊ณ ๋ฆฌ).
  • ์ž‘์€/์ค‘๊ฐ„ ํฌ๊ธฐ ํ• ๋‹น์—๋Š” ๊ณ ์ • ํฌ๊ธฐ chunks๋ฅผ ์‚ฌ์šฉํ•˜๊ณ , ํฐ/๋งค์šฐ ํฐ ํ• ๋‹น์€ ๋ณ„๋„๋กœ ๋งคํ•‘ํ•  ์ˆ˜ ์žˆ๋‹ค.

Chunks & Blocks

  • chunk๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ์—ฌ๋Ÿฌ ํŽ˜์ด์ง€๋กœ ๊ตฌ์„ฑ๋œ, ํ•ด๋‹น ๊ทธ๋ฃน ๋‚ด ํ•œ ์‚ฌ์ด์ฆˆ ํด๋ž˜์Šค๋ฅผ ์œ„ํ•œ ์˜์—ญ์ด๋‹ค.
  • chunk ๋‚ด๋ถ€์—์„œ blocks๋Š” ํ• ๋‹น ๊ฐ€๋Šฅํ•œ ์Šฌ๋กฏ์ด๋‹ค. ํ•ด์ œ๋œ ๋ธ”๋ก๋“ค์€ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ slab๋ฅผ ํ†ตํ•ด ์ถ”์ ๋œ๋‹ค โ€” ์˜ˆ: ๋น„ํŠธ๋งต์ด๋‚˜ out-of-line์— ์ €์žฅ๋œ free lists๋ฅผ ํ†ตํ•ด.
  • chunk๋“ค ์‚ฌ์ด(๋˜๋Š” ๋‚ด๋ถ€)์—๋Š” guard slices / guard pages๊ฐ€ ์‚ฝ์ž…๋  ์ˆ˜ ์žˆ์–ด OOB ์“ฐ๊ธฐ๋ฅผ ํฌ์ฐฉํ•œ๋‹ค.

Type / Type ID

  • ๋ชจ๋“  ํ• ๋‹น ์ง€์ (๋˜๋Š” malloc, calloc ๋“ฑ ํ˜ธ์ถœ)์€ ์–ด๋–ค ์ข…๋ฅ˜์˜ ๊ฐ์ฒด๊ฐ€ ํ• ๋‹น๋˜๋Š”์ง€ ์ธ์ฝ”๋”ฉํ•˜๋Š” type identifier(malloc_type_id_t)์™€ ์—ฐ๊ด€๋œ๋‹ค. ์ด type ID๋Š” allocator์— ์ „๋‹ฌ๋˜์–ด ์–ด๋–ค zone/segment๊ฐ€ ํ• ๋‹น์„ ์ œ๊ณตํ• ์ง€ ์„ ํƒํ•œ๋‹ค.
  • ๋”ฐ๋ผ์„œ ๊ฐ™์€ ํฌ๊ธฐ์˜ ๋‘ ํ• ๋‹น์ด๋ผ๋„ ํƒ€์ž…์ด ๋‹ค๋ฅด๋ฉด ์™„์ „ํžˆ ๋‹ค๋ฅธ zone์— ๋“ค์–ด๊ฐˆ ์ˆ˜ ์žˆ๋‹ค.
  • ์ดˆ๊ธฐ iOS 17 ๋ฒ„์ „์—์„œ๋Š” ๋ชจ๋“  API(e.g. CFAllocator)๊ฐ€ ์™„์ „ํžˆ ํƒ€์ž… ์ธ์‹์ ์ด์ง€ ์•Š์•˜๊ณ , Apple์€ iOS 18์—์„œ ์ผ๋ถ€ ์•ฝ์ ์„ ํ•ด๊ฒฐํ–ˆ๋‹ค.

Allocation & Freeing Workflow

๋‹ค์Œ์€ xzone์—์„œ ํ• ๋‹น ๋ฐ ํ•ด์ œ์˜ ์ƒ์œ„ ์ˆ˜์ค€ ํ๋ฆ„์ด๋‹ค:

  1. malloc / calloc / realloc / typed alloc์ด ํฌ๊ธฐ์™€ type ID์™€ ํ•จ๊ป˜ ํ˜ธ์ถœ๋œ๋‹ค.
  2. allocator๋Š” type ID๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์˜ฌ๋ฐ”๋ฅธ segment group / zone์„ ์„ ํƒํ•œ๋‹ค.
  3. ํ•ด๋‹น zone/segment ๋‚ด์—์„œ ์š”์ฒญ๋œ ํฌ๊ธฐ์˜ ์—ฌ์œ  ๋ธ”๋ก์„ ๊ฐ€์ง„ chunk๋ฅผ ์ฐพ๋Š”๋‹ค.
  • ๋กœ์ปฌ ์บ์‹œ / per-thread pools ๋˜๋Š” ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ์˜ free block lists๋ฅผ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋ธ”๋ก์ด ์—†์œผ๋ฉด ํ•ด๋‹น zone์— ์ƒˆ chunk๋ฅผ ํ• ๋‹นํ•  ์ˆ˜ ์žˆ๋‹ค.
  1. ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ slab๋ฅผ ์—…๋ฐ์ดํŠธ(ํ”„๋ฆฌ ๋น„ํŠธ ํด๋ฆฌ์–ด, ๋ถํ‚คํ•‘).
  2. ๋ฉ”๋ชจ๋ฆฌ ํƒœ๊น…(EMTE)์ด ์ ์šฉ๋˜๋Š” ๊ฒฝ์šฐ ๋ฐ˜ํ™˜๋œ ๋ธ”๋ก์— tag๊ฐ€ ํ• ๋‹น๋˜๊ณ  ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋Š” ๊ทธ ๋ธ”๋ก์ด โ€œliveโ€ ์ƒํƒœ์ž„์„ ๋ฐ˜์˜ํ•˜๋„๋ก ์—…๋ฐ์ดํŠธ๋œ๋‹ค.
  3. free() ํ˜ธ์ถœ ์‹œ:
  • ๋ธ”๋ก์€ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ์—์„œ ํ•ด์ œ๋œ ๊ฒƒ์œผ๋กœ ํ‘œ์‹œ๋œ๋‹ค(OOL slab ํ†ตํ•ด).
  • ๋ธ”๋ก์€ free list์— ๋“ค์–ด๊ฐ€๊ฑฐ๋‚˜ ์žฌ์‚ฌ์šฉ์„ ์œ„ํ•ด ํ’€๋ง๋  ์ˆ˜ ์žˆ๋‹ค.
  • ์„ ํƒ์ ์œผ๋กœ ๋ธ”๋ก ๋‚ด์šฉ์„ ์ง€์šฐ๊ฑฐ๋‚˜ poisoningํ•˜์—ฌ ๋ฐ์ดํ„ฐ ๋ˆ„์ถœ์ด๋‚˜ use-after-free ์•…์šฉ์„ ์ค„์ธ๋‹ค.
  • ๋ธ”๋ก๊ณผ ์—ฐ๊ด€๋œ ํ•˜๋“œ์›จ์–ด ํƒœ๊ทธ๋Š” ๋ฌดํšจํ™”๋˜๊ฑฐ๋‚˜ ์žฌํƒœ๊ทธ๋  ์ˆ˜ ์žˆ๋‹ค.
  • ์ „์ฒด chunk๊ฐ€ ๋น„๊ฒŒ ๋˜๋ฉด(๋ชจ๋“  ๋ธ”๋ก์ด ํ•ด์ œ๋˜๋ฉด) allocator๋Š” ๋ฉ”๋ชจ๋ฆฌ ์••๋ ฅ์ด ์žˆ์„ ๋•Œ ๊ทธ chunk๋ฅผ ํšŒ์ˆ˜(์–ธ๋งตํ•˜๊ฑฐ๋‚˜ OS์— ๋ฐ˜ํ™˜)ํ•  ์ˆ˜ ์žˆ๋‹ค.

Security Features & Hardening

์•„๋ž˜๋Š” modern userland xzone์— ๋‚ด์žฅ๋œ ๋ฐฉ์–ด์ฑ…๋“ค์ด๋‹ค:

FeaturePurposeNotes
Metadata decoupling์˜ค๋ฒ„ํ”Œ๋กœ์šฐ๋กœ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๊ฐ€ ์†์ƒ๋˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋Š” ๋ณ„๋„์˜ VM ์˜์—ญ(metadata slab)์— ์œ„์น˜
Guard pages / unmapped slicesOOB ์“ฐ๊ธฐ๋ฅผ ํฌ์ฐฉ์ธ์ ‘ ๋ธ”๋ก์„ ์กฐ์šฉํžˆ ์†์ƒ์‹œํ‚ค๋Š” ๋Œ€์‹  ๋ฒ„ํผ ์˜ค๋ฒ„ํ”Œ๋กœ๋ฅผ ํƒ์ง€
Type-based segregation๊ต์ฐจ ํƒ€์ž… ์žฌ์‚ฌ์šฉ ๋ฐ ํƒ€์ž… ํ˜ผ๋™ ๋ฐฉ์ง€๊ฐ™์€ ํฌ๊ธฐ๋ผ๋„ ํƒ€์ž…์ด ๋‹ค๋ฅด๋ฉด ๋‹ค๋ฅธ zone์œผ๋กœ ๊ฐ„๋‹ค
Memory Tagging (EMTE / MIE)์ž˜๋ชป๋œ ์ ‘๊ทผ, stale references, OOB, UAF ํƒ์ง€xzone์€ ํ•˜๋“œ์›จ์–ด EMTE์™€ ํ˜‘์กฐํ•˜์—ฌ ๋™๊ธฐํ™” ๋ชจ๋“œ๋กœ ์ž‘๋™
Delayed reuse / poisoning / zapuse-after-free ์•…์šฉ ๊ฐ€๋Šฅ์„ฑ ๊ฐ์†Œํ•ด์ œ๋œ ๋ธ”๋ก์€ ์žฌ์‚ฌ์šฉ ์ „์— poisoning, zeroing ๋˜๋Š” ๊ฒ€์—ญ(quarantine)๋  ์ˆ˜ ์žˆ์Œ
Chunk reclamation / dynamic unmapping๋ฉ”๋ชจ๋ฆฌ ๋‚ญ๋น„์™€ ๋‹จํŽธํ™” ๊ฐ์†Œ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ์ „์ฒด chunk๋Š” ์–ธ๋งต๋  ์ˆ˜ ์žˆ์Œ
Randomization / placement variation๊ฒฐ์ •์  ์ธ์ ‘์„ฑ ๋ฐฉ์ง€chunk ๋‚ด ๋ธ”๋ก ๋ฐ chunk ์„ ํƒ์— ๋ฌด์ž‘์œ„ํ™” ์š”์†Œ๊ฐ€ ์žˆ์Œ
Segregation of โ€œdata-onlyโ€ allocationsํฌ์ธํ„ฐ๋ฅผ ์ €์žฅํ•˜์ง€ ์•Š๋Š” ํ• ๋‹น ๋ถ„๋ฆฌ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋‚˜ ์ œ์–ด ํ•„๋“œ์— ๋Œ€ํ•œ ๊ณต๊ฒฉ์ž ์ œ์–ด ๊ฐ€๋Šฅ์„ฑ ๊ฐ์†Œ

Interaction with Memory Integrity Enforcement (MIE / EMTE)

  • Apple์˜ MIE(Memory Integrity Enforcement)๋Š” ํ•˜๋“œ์›จ์–ด + OS ํ”„๋ ˆ์ž„์›Œํฌ๋กœ, **Enhanced Memory Tagging Extension (EMTE)**๋ฅผ ์ฃผ์š” ๊ณต๊ฒฉ ํ‘œ๋ฉด ์ „๋ฐ˜์—์„œ ํ•ญ์ƒ-์˜จ ๋™๊ธฐ์‹ ๋ชจ๋“œ๋กœ ์ œ๊ณตํ•œ๋‹ค.
  • xzone allocator๋Š” ์‚ฌ์šฉ์ž ๊ณต๊ฐ„์—์„œ MIE์˜ ๊ทผ๊ฐ„์ด๋‹ค: xzone์„ ํ†ตํ•ด ์ˆ˜ํ–‰๋œ ํ• ๋‹น์€ ํƒœ๊ทธ๋ฅผ ๋ฐ›๊ณ  ์ ‘๊ทผ์€ ํ•˜๋“œ์›จ์–ด์— ์˜ํ•ด ๊ฒ€์‚ฌ๋œ๋‹ค.
  • MIE์—์„œ๋Š” allocator, ํƒœ๊ทธ ํ• ๋‹น, ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ๊ด€๋ฆฌ, ํƒœ๊ทธ ๊ธฐ๋ฐ€์„ฑ ๊ฐ•์ œ๊ฐ€ ํ†ตํ•ฉ๋˜์–ด ๋ฉ”๋ชจ๋ฆฌ ์˜ค๋ฅ˜(e.g. stale reads, OOB, UAF)๊ฐ€ ์ฆ‰์‹œ ํฌ์ฐฉ๋˜์–ด ์ดํ›„์— ์•…์šฉ๋˜์ง€ ์•Š๋„๋ก ํ•œ๋‹ค.

If you like, I can also generate a cheat-sheet or diagram of xzone internals for your book. Do you want me to do that next?
:contentReference[oai:20]{index=20}

(Old) Physical Use-After-Free via IOSurface

ios Physical UAF - IOSurface


Ghidra Install BinDiff

Download BinDiff DMG from https://www.zynamics.com/bindiff/manual and install it.

Open Ghidra with ghidraRun and go to File โ€“> Install Extensions, press the add button and select the path /Applications/BinDiff/Extra/Ghidra/BinExport and click OK and isntall it even if there is a version mismatch.

Using BinDiff with Kernel versions

  1. Go to the page https://ipsw.me/ and download the iOS versions you want to diff. These will be .ipsw files.
  2. Decompress until you get the bin format of the kernelcache of both .ipsw files. You have information on how to do this on:

macOS Kernel Extensions & Kernelcache

  1. Open Ghidra with ghidraRun, create a new project and load the kernelcaches.
  2. Open each kernelcache so they are automatically analyzed by Ghidra.
  3. Then, on the project Window of Ghidra, right click each kernelcache, select Export, select format Binary BinExport (v2) for BinDiff and export them.
  4. Open BinDiff, create a new workspace and add a new diff indicating as primary file the kernelcache that contains the vulnerability and as secondary file the patched kernelcache.

Finding the right XNU version

If you want to check for vulnerabilities in a specific version of iOS, you can check which XNU release version the iOS version uses at [https://www.theiphonewiki.com/wiki/kernel]https://www.theiphonewiki.com/wiki/kernel).

For example, the versions 15.1 RC, 15.1 and 15.1.1 use the version Darwin Kernel Version 21.1.0: Wed Oct 13 19:14:48 PDT 2021; root:xnu-8019.43.1~1/RELEASE_ARM64_T8006.

JSKit-Based Safari Chains and PREYHUNTER Stagers

Renderer RCE abstraction with JSKit

  • Reusable entry: Recent in-the-wild chains abused a WebKit JIT bug (patched as CVE-2023-41993) purely to gain JavaScript-level arbitrary read/write. The exploit immediately pivots into a purchased framework called JSKit, so any future Safari bug only needs to deliver the same primitive.
  • Version abstraction & PAC bypasses: JSKit bundles support for a wide range of iOS releases together with multiple, selectable Pointer Authentication Code bypass modules. The framework fingerprints the target build, selects the appropriate PAC bypass logic, and verifies every step (primitive validation, shellcode launch) before progressing.
  • Manual Mach-O mapping: JSKit parses Mach-O headers directly from memory, resolves the symbols it needs inside dyld-cached images, and can manually map additional Mach-O payloads without writing them to disk. This keeps the renderer process in-memory only and evades code-signature checks tied to filesystem artifacts.
  • Portfolio model: Debug strings such as โ€œexploit number 7โ€ show that the suppliers maintain multiple interchangeable WebKit exploits. Once the JS primitive matches JSKitโ€™s interface, the rest of the chain is unchanged across campaigns.

Kernel bridge: IPC UAF -> code-sign bypass pattern

  • Kernel IPC UAF (CVE-2023-41992): The second stage, still running inside the Safari context, triggers a kernel use-after-free in IPC code, re-allocates the freed object from userland, and abuses the dangling pointers to pivot into arbitrary kernel read/write. The stage also reuses PAC bypass material previously computed by JSKit instead of re-deriving it.
  • Code-signing bypass (CVE-2023-41991): With kernel R/W available, the exploit patches the trust cache / code-signing structures so unsigned payloads execute as system. The stage then exposes a lightweight kernel R/W service to later payloads.
  • Composed pattern: This chain demonstrates a reusable recipe that defenders should expect going forward:
WebKit renderer RCE -> kernel IPC UAF -> kernel arbitrary R/W -> code-sign bypass -> unsigned system stager

PREYHUNTER helper & watcher modules

  • Watcher anti-analysis: ์ „์šฉ watcher ๋ฐ”์ด๋„ˆ๋ฆฌ๋Š” ์žฅ์น˜๋ฅผ ์ง€์†์ ์œผ๋กœ ํ”„๋กœํŒŒ์ผ๋งํ•˜๋ฉฐ ์—ฐ๊ตฌ ํ™˜๊ฒฝ์ด ๊ฐ์ง€๋˜๋ฉด kill-chain์„ ์ค‘๋‹จํ•ฉ๋‹ˆ๋‹ค. security.mac.amfi.developer_mode_status, diagnosticd ์ฝ˜์†”์˜ ์กด์žฌ, ๋กœ์ผ€์ผ US ๋˜๋Š” IL, Cydia ๊ฐ™์€ jailbreak ํ”์ , bash, tcpdump, frida, sshd, checkrain ๊ฐ™์€ ํ”„๋กœ์„ธ์Šค, ๋ชจ๋ฐ”์ผ AV ์•ฑ(McAfee, AvastMobileSecurity, NortonMobileSecurity), ์ปค์Šคํ…€ HTTP ํ”„๋ก์‹œ ์„ค์ • ๋ฐ ์ปค์Šคํ…€ ๋ฃจํŠธ CA๋ฅผ ๊ฒ€์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์–ด๋–ค ๊ฒ€์‚ฌ๋ผ๋„ ์‹คํŒจํ•˜๋ฉด ์ถ”๊ฐ€ payload ์ „๋‹ฌ์ด ์ฐจ๋‹จ๋ฉ๋‹ˆ๋‹ค.
  • Helper surveillance hooks: helper ์ปดํฌ๋„ŒํŠธ๋Š” /tmp/helper.sock์„ ํ†ตํ•ด ๋‹ค๋ฅธ ์Šคํ…Œ์ด์ง€์™€ ํ†ต์‹ ํ•œ ๋’ค DMHooker์™€ UMHooker๋ผ๋Š” ํ›… ์„ธํŠธ๋ฅผ ๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค. ์ด ํ›…์€ VOIP ์˜ค๋””์˜ค ๊ฒฝ๋กœ๋ฅผ ๊ฐ€๋กœ์ฑ„๋ฉฐ(๋…น์Œ์€ /private/var/tmp/l/voip_%lu_%u_PART.m4a์— ์ €์žฅ๋จ), ์‹œ์Šคํ…œ ์ „์—ญ keylogger๋ฅผ ๊ตฌํ˜„ํ•˜๊ณ , UI ์—†์ด ์‚ฌ์ง„์„ ์ดฌ์˜ํ•˜๋ฉฐ, SpringBoard๋ฅผ ํ›…ํ•˜์—ฌ ํ•ด๋‹น ๋™์ž‘๋“ค์ด ์ผ๋ฐ˜์ ์œผ๋กœ ๋ฐœ์ƒ์‹œํ‚ค๋Š” ์•Œ๋ฆผ์„ ์ˆจ๊น๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ helper๋Š” Predator ๊ฐ™์€ ๋ฌด๊ฑฐ์šด ์ž„ํ”Œ๋ž€ํŠธ๋ฅผ ๋–จ์–ด๋œจ๋ฆฌ๊ธฐ ์ „์— ์€๋ฐ€ํ•œ ๊ฒ€์ฆ ๋ฐ ๊ฒฝ๋Ÿ‰ ๊ฐ์‹œ ๋ ˆ์ด์–ด๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.

WebKit DFG Store-Barrier UAF + ANGLE PBO OOB (iOS 26.1)

Webkit Dfg Store Barrier Uaf Angle Oob

iMessage/Media Parser Zero-Click Chains

Imessage Media Parser Zero Click Coreaudio Pac 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 ์ง€์›ํ•˜๊ธฐ