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 ์ง์ํ๊ธฐ
- ๊ตฌ๋ ๊ณํ ํ์ธํ๊ธฐ!
- **๐ฌ ๋์ค์ฝ๋ ๊ทธ๋ฃน ๋๋ ํ ๋ ๊ทธ๋จ ๊ทธ๋ฃน์ ์ฐธ์ฌํ๊ฑฐ๋ ํธ์ํฐ ๐ฆ @hacktricks_live๋ฅผ ํ๋ก์ฐํ์ธ์.
- HackTricks ๋ฐ HackTricks Cloud ๊นํ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ์ PR์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.
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๋ฅผ ์ ์)๋ก ๊ณ์ฐ๋๋ฉฐ ์ ๋ ฅ์:
- ํฌ์ธํฐ ๊ฐ(์ ๊ทํ๋ ๋ถ๋ถ)
- modifier(์ปจํ ์คํธ ๊ฐ, ์: salt)
- ๋น๋ฐ ํค
- ๋ด๋ถ ํธ์ ๋ก์ง ๊ฒฐ๊ณผ PAC๊ฐ ํฌ์ธํฐ ์์ ๋นํธ์ ์ ์ฅ๋ ๊ฐ๊ณผ ์ผ์นํ๋ฉด ์ธ์ฆ ์ฑ๊ณต์ ๋๋ค.
Instruction Families
๋ช ๋ช ๊ท์น์: PAC / AUT / XPAC, ๊ทธ ๋ค์ ๋๋ฉ์ธ ๋ฌธ์์ ๋๋ค.
PACxx๋ช ๋ น์ด๋ ํฌ์ธํฐ์ ์๋ช ํ์ฌ PAC๋ฅผ ์ฝ์ ํฉ๋๋ค.AUTxx๋ช ๋ น์ด๋ ์ธ์ฆ + ์ ๊ฑฐ(PAC ๊ฒ์ฆ ๋ฐ ์ ๊ฑฐ)๋ฅผ ์ํํฉ๋๋ค.XPACxx๋ช ๋ น์ด๋ ๊ฒ์ฆ ์์ด PAC๋ฅผ ์ ๊ฑฐํฉ๋๋ค.
๋๋ฉ์ธ / ์ ๋ฏธ์ฌ:
| Mnemonic | Meaning / Domain | Key / Domain | Example Usage in Assembly |
|---|---|---|---|
| PACIA | Sign instruction pointer with APIAKey | โI, Aโ | PACIA X0, X1 โ sign pointer in X0 using APIAKey with modifier X1 |
| PACIB | Sign instruction pointer with APIBKey | โI, Bโ | PACIB X2, X3 |
| PACDA | Sign data pointer with APDAKey | โD, Aโ | PACDA X4, X5 |
| PACDB | Sign data pointer with APDBKey | โD, Bโ | PACDB X6, X7 |
| PACG / PACGA | Generic (non-pointer) signing with APGAKey | โGโ | PACGA X8, X9, X10 (sign X9 with modifier X10 into X8) |
| AUTIA | Authenticate APIA-signed instruction pointer & strip PAC | โI, Aโ | AUTIA X0, X1 โ check PAC on X0 using modifier X1, then strip |
| AUTIB | Authenticate APIB domain | โI, Bโ | AUTIB X2, X3 |
| AUTDA | Authenticate APDA-signed data pointer | โD, Aโ | AUTDA X4, X5 |
| AUTDB | Authenticate APDB-signed data pointer | โD, Bโ | AUTDB X6, X7 |
| AUTGA | Authenticate generic / blob (APGA) | โGโ | AUTGA X8, X9, X10 (validate generic) |
| XPACI | Strip PAC (instruction pointer, no validation) | โIโ | XPACI X0 โ remove PAC from X0 (instruction domain) |
| XPACD | Strip 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
- 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๋ ๋งค์ฐ ๊ฒฌ๊ณ ํ ๋ณดํธ๋ก ๊ฐ์ฃผ๋์ง๋ง ์๋ฒฝํ์ง๋ ์์ต๋๋ค.
- 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:
- 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).
- 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.
- 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.
- 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.
- 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.
- 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
-
Thread๊ฐ ์ ํจํ์ง ์์ ํฌ์ธํฐ๋ฅผ ์ญ์ฐธ์กฐ โ CPU๊ฐ Data Abort๋ฅผ ๋ฐ์์ํต๋๋ค.
-
Kernel์ trap handler๊ฐ
exception_triage(EXC_BAD_ACCESS, ...)๋ฅผ ํธ์ถํฉ๋๋ค. -
๋ฉ์์ง๊ฐ ์ ์ก๋ฉ๋๋ค:
-
Thread port โ (debugger๊ฐ breakpoint๋ฅผ ๊ฐ๋ก์ฑ ์ ์์).
-
debugger๊ฐ ๋ฌด์ํ๋ฉด โ Task port โ (ํ๋ก์ธ์ค ์์ค handler).
-
๋ฌด์๋๋ฉด โ Host port (๋ณดํต ReportCrash).
- ์๋ฌด๋ ์ฒ๋ฆฌํ์ง ์์ผ๋ฉด โ
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 Exception | Signal |
|---|---|
| EXC_BAD_ACCESS | SIGSEGV or SIGBUS |
| EXC_BAD_INSTRUCTION | SIGILL |
| EXC_ARITHMETIC | SIGFPE |
| EXC_SOFTWARE | SIGTRAP |
| EXC_BREAKPOINT | SIGTRAP |
| EXC_CRASH | SIGKILL |
| EXC_ARM_PAC | SIGILL (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 Name | Element Size | Example Use |
|---|---|---|
default.kalloc.16 | 16 bytes | Very small kernel structs, pointers. |
default.kalloc.32 | 32 bytes | Small structs, object headers. |
default.kalloc.64 | 64 bytes | IPC messages, tiny kernel buffers. |
default.kalloc.128 | 128 bytes | Medium objects like parts of OSObject. |
| โฆ | โฆ | โฆ |
default.kalloc.1280 | 1280 bytes | Large structures, IOSurface/graphics metadata. |
๋์ ๋ฐฉ์:
- ๊ฐ ํ ๋น ์์ฒญ์ ๊ฐ์ฅ ๊ฐ๊น์ด zone ํฌ๊ธฐ๋ก ์ฌ๋ฆผ(round up) ๋ฉ๋๋ค.
(์: 50๋ฐ์ดํธ ์์ฒญ์
kalloc.64zone์ ํ ๋น๋ฉ๋๋ค). - ๊ฐ zone์ ๋ฉ๋ชจ๋ฆฌ๋ freelist์ ๋ณด๊ด๋์์ต๋๋ค โ ์ปค๋์ด ํด์ ํ ์ฒญํฌ๋ ํด๋น zone์ผ๋ก ๋๋์๊ฐ์ต๋๋ค.
- 64๋ฐ์ดํธ ๋ฒํผ๋ฅผ ์ค๋ฒํ๋ก์ฐํ๋ฉด, ๋์ผ zone์ ๋ค์ ๊ฐ์ฒด๋ฅผ ๋ฎ์ด์ฐ๊ฒ ๋ฉ๋๋ค.
์ด ๋๋ฌธ์ heap spraying / feng shui๊ฐ ๋งค์ฐ ํจ๊ณผ์ ์ด์์ต๋๋ค: ๊ฐ์ ํฌ๊ธฐ ํด๋์ค๋ก ํ ๋น์ ๋ฟ๋ฆฌ๋ฉด ๊ฐ์ฒด ์ด์์ ์์ธกํ ์ ์์์ต๋๋ค.
The freelist
๊ฐ kalloc zone ๋ด๋ถ์์, ํด์ ๋ ๊ฐ์ฒด๋ค์ ์์คํ ์ ์ง์ ๋ฐํ๋์ง ์๊ณ freelist์ ๋ค์ด๊ฐ์ต๋๋ค. freelist๋ ์ฌ์ฉ ๊ฐ๋ฅํ ์ฒญํฌ๋ค์ ์ฐ๊ฒฐ ๋ฆฌ์คํธ์ ๋๋ค.
-
์ฒญํฌ๊ฐ ํด์ ๋๋ฉด, ์ปค๋์ ๊ทธ ์ฒญํฌ์ ์์ ๋ถ๋ถ์ ํฌ์ธํฐ๋ฅผ ์๋๋ค โ ๊ฐ์ zone์ ๋ค์ free ์ฒญํฌ ์ฃผ์.
-
zone์ ์ฒซ ๋ฒ์งธ free ์ฒญํฌ๋ฅผ ๊ฐ๋ฆฌํค๋ HEAD ํฌ์ธํฐ๋ฅผ ์ ์งํ์ต๋๋ค.
-
ํ ๋น์ ํญ์ ํ์ฌ HEAD๋ฅผ ์ฌ์ฉํ์ต๋๋ค:
-
HEAD๋ฅผ ํ(pop) (๊ทธ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํธ์ถ์์ ๋ฐํ).
-
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์ ๊ฐ๊ธฐ ๋๋ฌธ์, ๊ณต๊ฒฉ์๋ ์ด๋ฅผ ์์์ํฌ ์ ์๋ค:
-
Heap overflow๋ก ์ธ์ ํ freed chunk์ ์นจ๋ฒ โ ๊ทธ โnextโ pointer๋ฅผ ๋ฎ์ด์ฐ๊ธฐ.
-
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:
- Spray allocations (fill the holes)
- ์๊ฐ์ด ์ง๋๋ฉด ์ปค๋ ํ์ ๋จํธํ๋๋ค: ์ค๋๋ ๊ฐ์ฒด๋ค์ด free๋๋ฉด์ ๊ตฌ๋ฉ(hole)์ด ์๊ธด๋ค.
- ๊ณต๊ฒฉ์๋ ๋จผ์ ๋ง์ ๋๋ฏธ ํ ๋น์ ๋ง๋ค์ด ์ด๋ฌํ ๋นํ์ ์ฑ์ ํ์ โ๋นฝ๋นฝํ๊ฒโ ๋ง๋ค์ด ์์ธก ๊ฐ๋ฅํ๊ฒ ๋ง๋ ๋ค.
- Force new pages
- ๊ตฌ๋ฉ์ด ์ฑ์์ง๋ฉด ๋ค์ ํ ๋น์ zone์ ์๋ก ์ถ๊ฐ๋ ํ์ด์ง์์ ํ ๋น๋์ด์ผ ํ๋ค.
- ์ ํ์ด์ง๋ ๊ฐ์ฒด๋ค์ด ํฉ์ด์ง์ง ์๊ณ ํด๋ฌ์คํฐ๋ง๋๊ฒ ํ๋ค.
- ์ด๋ ๊ณต๊ฒฉ์๊ฐ ์ด์ ์ ์ด๋ฅผ ํจ์ฌ ์ ํ๊ฒ ํด์ค๋ค.
- Place attacker objects
- ๊ณต๊ฒฉ์๋ ๋ค์ ์คํ๋ ์ดํ์ฌ ๊ทธ ์ ํ์ด์ง๋ค์ ๋ง์ ๊ณต๊ฒฉ์ ์ ์ด ๊ฐ์ฒด๋ค์ ๋ง๋ ๋ค.
- ์ด ๊ฐ์ฒด๋ค์ ๋ชจ๋ ๊ฐ์ zone์ ์ํ๋ฏ๋ก ํฌ๊ธฐ์ ๋ฐฐ์น๊ฐ ์์ธก ๊ฐ๋ฅํ๋ค.
- Free a controlled object (make a gap)
- ๊ณต๊ฒฉ์๋ ์๋์ ์ผ๋ก ์์ ์ ๊ฐ์ฒด ์ค ํ๋๋ฅผ freeํ๋ค.
- ์ด๋ ๊ฒ ํ๋ฉด ํ ๋น์๊ฐ ์ดํ ๊ฐ์ ํฌ๊ธฐ์ ๋ค์ ํ ๋น์ ์ํด ์ฌ์ฌ์ฉํ โ๊ตฌ๋ฉโ์ด ์๊ธด๋ค.
- Victim object lands in the hole
- ๊ณต๊ฒฉ์๋ ์ปค๋์ด victim ๊ฐ์ฒด(์์ํ๋ ค๋ ๊ฐ์ฒด)๋ฅผ ํ ๋นํ๋๋ก ํธ๋ฆฌ๊ฑฐํ๋ค.
- ๊ตฌ๋ฉ์ด freelist์์ ๊ฐ์ฅ ๋จผ์ ์ฌ์ฉ ๊ฐ๋ฅํ ์ฌ๋กฏ์ด๋ฏ๋ก, victim์ ๊ณต๊ฒฉ์๊ฐ freeํ ๋ฐ๋ก ๊ทธ ์์น์ ๋์ธ๋ค.
- 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๋ฅผ ๊ฐ์ง๋ค.
- ํ ๋น ๊ฒฝ๋ก:
- per-CPU cache๋ฅผ ์๋.
- ๋น์ด ์์ผ๋ฉด global freelist์์ ๊ฐ์ ธ์ด.
- 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:
- Type lookup โ
OSDatamaps tokalloc_type_osdatazone (size 64 bytes). - 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).
- 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
| Feature | Old Heap (Pre-iOS 15) | Modern Heap (iOS 15+ / A12+) |
|---|---|---|
| Allocation granularity | Fixed size buckets (kalloc.16, kalloc.32, etc.) | Size + type-based buckets (kalloc_type) |
| Placement predictability | High (same-size objects side by side) | Low (same-type grouping + randomness) |
| Freelist management | Raw pointers in freed chunks (easy to corrupt) | Encoded pointers (safe-linking style) |
| Adjacent object control | Easy via sprays/frees (feng shui predictable) | Hard โ typed zones separate attacker objects |
| Kernel data/code protections | Few hardware protections | PPL / SPTM protect page tables & code pages, and PAC protects pointers |
| Allocation reuse validation | None (freelist pointers raw) | zone_require / zone enforcement |
| Exploit reliability | High with heap sprays | Much lower, requires logic bugs or info leaks |
| Large allocations handling | All small allocations managed equally | Large 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์์ ํ ๋น ๋ฐ ํด์ ์ ์์ ์์ค ํ๋ฆ์ด๋ค:
- malloc / calloc / realloc / typed alloc์ด ํฌ๊ธฐ์ type ID์ ํจ๊ป ํธ์ถ๋๋ค.
- allocator๋ type ID๋ฅผ ์ฌ์ฉํ์ฌ ์ฌ๋ฐ๋ฅธ segment group / zone์ ์ ํํ๋ค.
- ํด๋น zone/segment ๋ด์์ ์์ฒญ๋ ํฌ๊ธฐ์ ์ฌ์ ๋ธ๋ก์ ๊ฐ์ง chunk๋ฅผ ์ฐพ๋๋ค.
- ๋ก์ปฌ ์บ์ / per-thread pools ๋๋ ๋ฉํ๋ฐ์ดํฐ์ free block lists๋ฅผ ์ฐธ์กฐํ ์ ์๋ค.
- ์ฌ์ฉ ๊ฐ๋ฅํ ๋ธ๋ก์ด ์์ผ๋ฉด ํด๋น zone์ ์ chunk๋ฅผ ํ ๋นํ ์ ์๋ค.
- ๋ฉํ๋ฐ์ดํฐ slab๋ฅผ ์ ๋ฐ์ดํธ(ํ๋ฆฌ ๋นํธ ํด๋ฆฌ์ด, ๋ถํคํ).
- ๋ฉ๋ชจ๋ฆฌ ํ๊น (EMTE)์ด ์ ์ฉ๋๋ ๊ฒฝ์ฐ ๋ฐํ๋ ๋ธ๋ก์ tag๊ฐ ํ ๋น๋๊ณ ๋ฉํ๋ฐ์ดํฐ๋ ๊ทธ ๋ธ๋ก์ด โliveโ ์ํ์์ ๋ฐ์ํ๋๋ก ์ ๋ฐ์ดํธ๋๋ค.
free()ํธ์ถ ์:
- ๋ธ๋ก์ ๋ฉํ๋ฐ์ดํฐ์์ ํด์ ๋ ๊ฒ์ผ๋ก ํ์๋๋ค(OOL slab ํตํด).
- ๋ธ๋ก์ free list์ ๋ค์ด๊ฐ๊ฑฐ๋ ์ฌ์ฌ์ฉ์ ์ํด ํ๋ง๋ ์ ์๋ค.
- ์ ํ์ ์ผ๋ก ๋ธ๋ก ๋ด์ฉ์ ์ง์ฐ๊ฑฐ๋ poisoningํ์ฌ ๋ฐ์ดํฐ ๋์ถ์ด๋ use-after-free ์ ์ฉ์ ์ค์ธ๋ค.
- ๋ธ๋ก๊ณผ ์ฐ๊ด๋ ํ๋์จ์ด ํ๊ทธ๋ ๋ฌดํจํ๋๊ฑฐ๋ ์ฌํ๊ทธ๋ ์ ์๋ค.
- ์ ์ฒด chunk๊ฐ ๋น๊ฒ ๋๋ฉด(๋ชจ๋ ๋ธ๋ก์ด ํด์ ๋๋ฉด) allocator๋ ๋ฉ๋ชจ๋ฆฌ ์๋ ฅ์ด ์์ ๋ ๊ทธ chunk๋ฅผ ํ์(์ธ๋งตํ๊ฑฐ๋ OS์ ๋ฐํ)ํ ์ ์๋ค.
Security Features & Hardening
์๋๋ modern userland xzone์ ๋ด์ฅ๋ ๋ฐฉ์ด์ฑ ๋ค์ด๋ค:
| Feature | Purpose | Notes |
|---|---|---|
| Metadata decoupling | ์ค๋ฒํ๋ก์ฐ๋ก ๋ฉํ๋ฐ์ดํฐ๊ฐ ์์๋๋ ๊ฒ์ ๋ฐฉ์ง | ๋ฉํ๋ฐ์ดํฐ๋ ๋ณ๋์ VM ์์ญ(metadata slab)์ ์์น |
| Guard pages / unmapped slices | OOB ์ฐ๊ธฐ๋ฅผ ํฌ์ฐฉ | ์ธ์ ๋ธ๋ก์ ์กฐ์ฉํ ์์์ํค๋ ๋์ ๋ฒํผ ์ค๋ฒํ๋ก๋ฅผ ํ์ง |
| Type-based segregation | ๊ต์ฐจ ํ์ ์ฌ์ฌ์ฉ ๋ฐ ํ์ ํผ๋ ๋ฐฉ์ง | ๊ฐ์ ํฌ๊ธฐ๋ผ๋ ํ์ ์ด ๋ค๋ฅด๋ฉด ๋ค๋ฅธ zone์ผ๋ก ๊ฐ๋ค |
| Memory Tagging (EMTE / MIE) | ์๋ชป๋ ์ ๊ทผ, stale references, OOB, UAF ํ์ง | xzone์ ํ๋์จ์ด EMTE์ ํ์กฐํ์ฌ ๋๊ธฐํ ๋ชจ๋๋ก ์๋ |
| Delayed reuse / poisoning / zap | use-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
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
- Go to the page https://ipsw.me/ and download the iOS versions you want to diff. These will be
.ipswfiles. - Decompress until you get the bin format of the kernelcache of both
.ipswfiles. You have information on how to do this on:
macOS Kernel Extensions & Kernelcache
- Open Ghidra with
ghidraRun, create a new project and load the kernelcaches. - Open each kernelcache so they are automatically analyzed by Ghidra.
- Then, on the project Window of Ghidra, right click each kernelcache, select
Export, select formatBinary BinExport (v2) for BinDiffand export them. - 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 ์ง์ํ๊ธฐ
- ๊ตฌ๋ ๊ณํ ํ์ธํ๊ธฐ!
- **๐ฌ ๋์ค์ฝ๋ ๊ทธ๋ฃน ๋๋ ํ ๋ ๊ทธ๋จ ๊ทธ๋ฃน์ ์ฐธ์ฌํ๊ฑฐ๋ ํธ์ํฐ ๐ฆ @hacktricks_live๋ฅผ ํ๋ก์ฐํ์ธ์.
- HackTricks ๋ฐ HackTricks Cloud ๊นํ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ์ PR์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.


