Translated ['', 'src/binary-exploitation/ios-exploiting/ios-physical-uaf

This commit is contained in:
Translator 2025-09-29 09:00:20 +00:00
parent efa111760f
commit 12175d56e6

View File

@ -1,95 +1,99 @@
# iOS Physical Use-After-Free via IOSurface
# iOS Physical Use After Free via IOSurface
{{#include ../../banners/hacktricks-training.md}}
## Physical use-after-free
Hii ni muhtasari kutoka kwenye post ya [https://alfiecg.uk/2024/09/24/Kernel-exploit.html](https://alfiecg.uk/2024/09/24/Kernel-exploit.html). Taarifa zaidi kuhusu exploit inayotumia teknik hii inaweza kupatikana kwenye [https://github.com/felix-pb/kfd](https://github.com/felix-pb/kfd)
Hii ni muhtasari wa chapisho kutoka [https://alfiecg.uk/2024/09/24/Kernel-exploit.html](https://alfiecg.uk/2024/09/24/Kernel-exploit.html); zaidi ya hayo, taarifa za ziada kuhusu exploit inayotumia tekniki hii zinapatikana katika [https://github.com/felix-pb/kfd](https://github.com/felix-pb/kfd)
### Memory management in XNU <a href="#memory-management-in-xnu" id="memory-management-in-xnu"></a>
### Usimamizi wa kumbukumbu katika XNU <a href="#memory-management-in-xnu" id="memory-management-in-xnu"></a>
The **virtual memory address space** kwa michakato ya user kwenye iOS inajulikana kuanzia **0x0 hadi 0x8000000000**. Hata hivyo, anwani hizi hazitafsiri moja kwa moja kuwa physical memory. Badala yake, the **kernel** inatumia **page tables** kutafsiri anwani za virtual kuwa **physical addresses** halisi.
**virtual memory address space** kwa michakato ya mtumiaji kwenye iOS inashughulikia anuwai kutoka **0x0 hadi 0x8000000000**. Hata hivyo, anwani hizi hazitafsiri moja kwa moja kuwa kumbukumbu ya kimwili. Badala yake, **kernel** hutumia **page tables** kutafsiri anwani za virtual kuwa **physical addresses** halisi.
#### Levels of Page Tables in iOS
#### Ngazi za Page Tables katika iOS
Page tables zimepangwa kwa hatua tatu:
Page tables zimepangwa kwa muundo wa mlolongo katika ngazi tatu:
1. **L1 Page Table (Level 1)**:
* Kila entry hapa inawakilisha eneo kubwa la virtual memory.
* Kila entry hapa inawakilisha anuwai kubwa ya virtual memory.
* Inafunika **0x1000000000 bytes** (au **256 GB**) ya virtual memory.
2. **L2 Page Table (Level 2)**:
* Entry hapa inawakilisha eneo ndogo zaidi la virtual memory, hasa **0x2000000 bytes** (32 MB).
* Entry ya L1 inaweza kuelekeza kwenye L2 table ikiwa haiwezi kuoanisha eneo lote yenyewe.
* Entry hapa inawakilisha eneo ndogo ya virtual memory, haswa **0x2000000 bytes** (32 MB).
* Kuingia kwa L1 kunaweza kuonyesha kwenye L2 table ikiwa haifanyi mapping ya eneo zima yenyewe.
3. **L3 Page Table (Level 3)**:
* Hii ni level ya kina zaidi, ambapo kila entry inaoanisha ukurasa mmoja wa **4 KB**.
* Entry ya L2 inaweza kuelekeza kwenye L3 table ikiwa inahitaji udhibiti wa kina zaidi.
* Hii ni ngazi ya mwisho, ambapo kila entry inamezea ukurasa mmoja wa kumbukumbu wa **4 KB**.
* Entry ya L2 inaweza kuonyesha kwenye L3 table ikiwa inahitajika udhibiti wa undani zaidi.
#### Mapping Virtual to Physical Memory
#### Kuweka Mapping ya Virtual kwa Physical Memory
* **Direct Mapping (Block Mapping)**:
* Baadhi ya entry kwenye page table zinaoanisha moja kwa moja **msururu wa anwani za virtual** kwa msururu wa contiguous wa anwani za physical (kama njia mkato).
* Baadhi ya entry katika page table zinamap moja kwa moja anuwai za anwani za virtual kwa anuwai inayoendelea ya anwani za physical (kama njia fupi).
* **Pointer to Child Page Table**:
* Ikiwa inahitajika udhibiti wa kina, entry katika level moja (mfano L1) inaweza kuelekeza kwenye **child page table** kwenye level inayofuata (mfano L2).
* Ikiwa inahitajika udhibiti wa kina, entry katika ngazi moja (mfano, L1) inaweza kuelekeza kwenye **child page table** kwenye ngazi inayofuata (mfano, L2).
#### Example: Mapping a Virtual Address
#### Mfano: Kuweka Mapping ya Anwani ya Virtual
Tuseme unajaribu kufikia anwani ya virtual **0x1000000000**:
Tuseme unajaribu kupata anwani ya virtual **0x1000000000**:
1. **L1 Table**:
* Kernel inakagua entry ya L1 inayohusiana na anwani hii ya virtual. Ikiwa ina **pointer to an L2 page table**, inahamia L2 table hiyo.
* Kernel inakagua entry ya L1 inayohusiana na anwani hii ya virtual. Ikiwa ina **pointer to an L2 page table**, inaendelea kwa L2 table hiyo.
2. **L2 Table**:
* Kernel inakagua L2 page table kwa mapping ya kina zaidi. Ikiwa entry hii inaelekeza kwenye **L3 page table**, inaendelea huko.
* Kernel inakagua L2 page table kwa mapping ya undani zaidi. Ikiwa entry hii inaonyesha kwenye **L3 page table**, inaendelea huko.
3. **L3 Table**:
* Kernel inatafuta entry ya mwisho ya L3, ambayo inaelekeza kwenye **physical address** ya ukurasa wa kumbukumbu.
* Kernel inatafuta entry ya mwisho ya L3, ambayo inaonyesha kwenye **physical address** ya ukurasa wa kumbukumbu halisi.
#### Example of Address Mapping
#### Mfano wa Mapping ya Anwani
Ikiwa unaandika physical address **0x800004000** kwenye index ya kwanza ya L2 table, basi:
Ikiwa unaandika anwani ya physical **0x800004000** kwenye index ya kwanza ya L2 table, basi:
* Anwani za virtual kutoka **0x1000000000** hadi **0x1002000000** zinaoanisha kwa anwani za physical kutoka **0x800004000** hadi **0x802004000**.
* Hii ni **block mapping** kwenye level ya L2.
* Anwani za virtual kutoka **0x1000000000** hadi **0x1002000000** zinamap kuwa anwani za physical kutoka **0x800004000** hadi **0x802004000**.
* Hii ni **block mapping** kwenye ngazi ya L2.
Akiba, ikiwa entry ya L2 inaelekeza kwenye L3 table:
Vinginevyo, ikiwa entry ya L2 inaonyesha kwenye L3 table:
* Kila ukurasa wa 4 KB kwenye anwani ya virtual **0x1000000000 -> 0x1002000000** utatafsiriwa na entry za kibinafsi katika L3 table.
* Kila ukurasa wa 4 KB katika anuwai ya virtual **0x1000000000 -> 0x1002000000** utapangwa na entry za kibinafsi katika L3 table.
### Physical use-after-free
Physical **use-after-free** (UAF) hutokea wakati:
A **physical use-after-free** (UAF) hutokea wakati:
1. Mchakato unafanya **allocate** memory fulani kama **readable na writable**.
2. **page tables** zinasasishwa ili kuoanisha memory hii na physical address maalum ambayo mchakato unaweza kufikia.
3. Mchakato una **deallocate** (free) memory hiyo.
4. Hata hivyo, kutokana na **bug**, kernel **inasahau kuondoa mapping** kutoka kwenye page tables, ingawa inaweka physical memory husika kama free.
5. Kernel inaweza kisha **kureallocate memory hii "freed"** kwa matumizi mengine, kama data ya kernel.
6. Kwa kuwa mapping haikuondolewa, mchakato bado anaweza **kusoma na kuandika** kwenye memory hiyo ya physical.
1. Mchakato unafanya **allocate** kumbukumbu fulani kama inayoweza kusomwa na kuandikwa (readable and writable).
2. **page tables** zinasasishwa ili kumap kumbukumbu hii kwa anwani mahususi za physical ambazo mchakato anaweza kufikia.
3. Mchakato **huondoa** (hutoa/free) kumbukumbu hiyo.
4. Hata hivyo, kutokana na **bug**, kernel **inasahau kuondoa mapping** kutoka page tables, ingawa inatambua kumbukumbu ya physical kama huru.
5. Kernel inaweza kisha **kureallocate kumbukumbu ya physical iliyotolewa** kwa matumizi mengine, kama data za kernel.
6. Kwa sababu mapping haikuondolewa, mchakato bado anaweza **kusoma na kuandika** kwenye kumbukumbu hiyo ya physical.
Hii inamaanisha mchakato unaweza kufikia **pages za kernel memory**, ambazo zinaweza kubeba data nyeti au miundo, na hivyo kumruhusu mwizi **kuathiri kernel memory**.
Hii ina maana mchakato unaweza kufikia **kurasa za kumbukumbu za kernel**, ambazo zinaweza kuwa na data nyeti au miundo, na hivyo kumuwezesha mshambuliaji **kuingilia kumbukumbu ya kernel**.
### IOSurface Heap Spray
Kwa kuwa mshambuliaji hana udhibiti wa kurudia ni kurasa gani za kernel zitapatiwa memory iliyofutwa, wanatumia tekniki inayoitwa **heap spray**:
Kwa kuwa mshambuliaji hawezi kudhibiti ni kurasa gani za kernel zitapewa kumbukumbu iliyotolewa, wanatumia mbinu inayoitwa **heap spray**:
1. Mshambuliaji **anaunda idadi kubwa ya IOSurface objects** katika kernel memory.
2. Kila IOSurface object ina **magic value** katika moja ya fields zake, kufanya iwe rahisi kuibua.
3. Wanapitia **pages zilizofutwa** kuona kama IOSurface objects yoyote imeangukia kwenye ukurasa uliotolewa.
4. Wao wanapogundua IOSurface object kwenye ukurasa uliofutwa, wanaweza kutumia ili **kusoma na kuandika kernel memory**.
1. Mshambuliaji **huunda idadi kubwa ya vitu vya IOSurface** kwenye kumbukumbu ya kernel.
2. Kila objektu la IOSurface lina thamani ya **magic** katika moja ya fields zake, kufanya iwe rahisi kutambua.
3. Wanapiga **skana kurasa zilizotolewa** ili kuona kama baadhi ya vitu vya IOSurface vimeangukia kwenye ukurasa uliotolewa.
4. Wakitambua objektu la IOSurface kwenye ukurasa uliotolewa, wanaweza kulitumia **kusoma na kuandika kumbukumbu ya kernel**.
Taarifa zaidi kuhusu hili ziko kwenye [https://github.com/felix-pb/kfd/tree/main/writeups](https://github.com/felix-pb/kfd/tree/main/writeups)
Taarifa za ziada kuhusu hili ziko katika [https://github.com/felix-pb/kfd/tree/main/writeups](https://github.com/felix-pb/kfd/tree/main/writeups)
> [!TIP]
> Tambua kwamba vifaa vya iOS 16+ (A12+) vinamitigation za hardware (kama PPL au SPTM) zinazofanya physical UAF techniques kuwa ngumu zaidi. PPL inatekeleza ulinzi mgumu wa MMU kwenye kurasa zinazohusiana na code signing, entitlements, na data nyeti ya kernel, hivyo, hata ikiwa ukurasa utatumika tena, maandishi kutoka userland au code ya kernel iliyomilikiwa yanazuia kuandika kwenye kurasa zilizolindwa na PPL. Secure Page Table Monitor (SPTM) inaongeza PPL kwa kuimarisha sasisho za page table wenyewe. Inahakikisha kwamba hata code yenye mamlaka ya kernel haiwezi kubadilisha silently mappings au kupindua freed pages bila kupitia ukaguzi salama. KTRR (Kernel Text Read-Only Region), ambayo inalaza eneo la code ya kernel kama read-only baada ya boot. Hii inazuia mabadiliko ya runtime kwa code ya kernel, ikifunga njia kubwa ya shambulio ambayo physical UAF exploits mara nyingi hutegemea. Zaidi ya hayo, allocations za `IOSurface` zimekuwa zisizotarajiwa na ngumu zaidi kupangwa ndani ya maeneo yanayoweza kufikiwa na user, jambo linalofanya mbinu ya “magic value scanning” kuwa isiyokuwa na uhakika. Na `IOSurface` sasa inalindwa na entitlements na vizuizi vya sandbox.
> Fahamu kuwa vifaa vya iOS 16+ (A12+) vina utatuzi wa kiapparatus (kama PPL au SPTM) unaofanya mbinu za physical UAF zisifae kwa urahisi.
> PPL inatekeleza ulinzi mkali wa MMU kwa kurasa zinazohusiana na code signing, entitlements, na data nyeti za kernel, hivyo, hata ukireuse ukurasa, uandishi kutoka userland au kernel iliyovamiwa kwenda kwenye kurasa zilizo chini ya ulinzi wa PPL unatokwama.
> Secure Page Table Monitor (SPTM) inaongeza PPL kwa kuimarisha sasisho za page table yenyewe. Inahakikisha kwamba hata code yenye vibali vya juu ya kernel haiwezi kuremap kwa kimya kurasa zilizotolewa au kuharibu mappings bila kupitia ukaguzi wa usalama.
> KTRR (Kernel Text Read-Only Region), ambayo inafunga sehemu ya code ya kernel kama read-only baada ya boot. Hii inazuia mabadiliko yoyote ya runtime kwa code ya kernel, ikifunga njia kubwa ya shambulio ambayo exploit za physical UAF mara nyingi hutegemea.
> Zaidi ya hayo, allocations za `IOSurface` ziko ngumu kutabirika na vigumu kuzifanikiwa kuzipanga katika maeneo yanayoweza kufikiwa na user, ambayo inafanya mbinu ya “magic value scanning” isitegemeeke sana. Na `IOSurface` sasa inatwaliwa na entitlements na vizuizi vya sandbox.
### Step-by-Step Heap Spray Process
1. **Spray IOSurface Objects**: mshambuliaji anaunda IOSurface objects nyingi zilizo na kitambulisho maalum ("magic value").
2. **Scan Freed Pages**: wanakagua ikiwa yoyote ya objects imewekwa kwenye ukurasa uliotolewa.
3. **Read/Write Kernel Memory**: kwa kuathiri fields ndani ya IOSurface object, wanapata uwezo wa kufanya **arbitrary reads and writes** katika kernel memory. Hii inawawezesha:
* Kutumia field moja kusoma **kiasi chochote cha 32-bit** katika kernel memory.
* Kutumia field nyingine kuandika **64-bit values**, wakifikia primitive imara ya **kernel read/write**.
1. **Spray IOSurface Objects**: Mshambuliaji huunda vitu vingi vya IOSurface zikiwa na kitambulisho maalum ("magic value").
2. **Scan Freed Pages**: Wanakagua kama yoyote ya vitu imepangwa kwenye ukurasa uliotolewa.
3. **Read/Write Kernel Memory**: Kwa kuibadilisha fields katika objektu la IOSurface, wanapata uwezo wa kufanya **arbitrary reads and writes** katika kumbukumbu ya kernel. Hii inawawezesha:
* Kutumia field moja kusoma **kima chochote cha 32-bit** katika kumbukumbu ya kernel.
* Kutumia field nyingine kuandika thamani za **64-bit**, wakipata primitive thabiti ya **kernel read/write**.
Generate IOSurface objects with the magic value IOSURFACE_MAGIC to later search for:
Generate IOSurface objects with the magic value IOSURFACE\_MAGIC to later search for:
```c
void spray_iosurface(io_connect_t client, int nSurfaces, io_connect_t **clients, int *nClients) {
if (*nClients >= 0x4000) return;
@ -110,7 +114,7 @@ io_connect_t id = result.surface_id;
}
}
```
Tafuta vitu vya **`IOSurface`** katika ukurasa mmoja wa kimwili uliotolewa:
Tafuta vitu vya **`IOSurface`** katika ukurasa wa kimwili mmoja ulioachiliwa:
```c
int iosurface_krw(io_connect_t client, uint64_t *puafPages, int nPages, uint64_t *self_task, uint64_t *puafPage) {
io_connect_t *surfaceIDs = malloc(sizeof(io_connect_t) * 0x4000);
@ -144,25 +148,25 @@ free(surfaceIDs);
return 0;
}
```
### Kupata kusoma/kuandika kwa kernel kwa kutumia IOSurface
### Kupata Kernel Read/Write kwa kutumia IOSurface
Baada ya kupata udhibiti wa objekti ya IOSurface katika kernel memory (imepangwa kwenye ukurasa wa kimwili uliotolewa unaopatikana kutoka userspace), tunaweza kuitumia kwa **operesheni zozote za kusoma na kuandika katika kernel**.
Baada ya kupata udhibiti wa object ya IOSurface katika kernel memory (mapped to a freed physical page accessible from userspace), tunaweza kuvitumia kwa ajili ya **arbitrary kernel read and write operations**.
**Minda Muhimu katika IOSurface**
**Sehemu Muhimu katika IOSurface**
Objekti ya IOSurface ina vipengele viwili muhimu:
The IOSurface object has two crucial fields:
1. **Use Count Pointer**: Inaruhusu **kusoma kwa 32-bit**.
2. **Indexed Timestamp Pointer**: Inaruhusu **kuandika kwa 64-bit**.
1. **Use Count Pointer**: Inaruhusu **32-bit read**.
2. **Indexed Timestamp Pointer**: Inaruhusu **64-bit write**.
Kwa kuandika upya pointers hizi, tunaziweka kuonyesha anwani zozote katika kernel memory, hivyo kuwezesha uwezo wa kusoma/kuandika.
Kwa kuandika upya pointers hizi, tunazituma kwa anwani zozote katika kernel memory, hivyo kuwezesha operesheni za read/write.
#### Kusoma kwa 32-bit kwa kernel
#### 32-Bit Kernel Read
Ili kufanya kusoma:
1. Bandika upya **use count pointer** ili ianze kuonyesha anwani lengwa ukiokoa offset ya 0x14-byte.
2. Tumia method `get_use_count` kusoma thamani kwenye anwani hiyo.
1. Andika upya **use count pointer** ili iashirie anwani lengwa ikipunguzwa kwa offset ya 0x14-byte.
2. Tumia method ya `get_use_count` kusoma thamani kwenye anwani hiyo.
```c
uint32_t get_use_count(io_connect_t client, uint32_t surfaceID) {
uint64_t args[1] = {surfaceID};
@ -184,8 +188,8 @@ return value;
Ili kufanya uandishi:
1. Andika tena **indexed timestamp pointer** kwa anwani lengwa.
2. Tumia method ya `set_indexed_timestamp` kuandika thamani ya 64-bit.
1. Overwrite the **indexed timestamp pointer** kwa anwani lengwa.
2. Tumia method `set_indexed_timestamp` kuandika thamani ya 64-bit.
```c
void set_indexed_timestamp(io_connect_t client, uint32_t surfaceID, uint64_t value) {
uint64_t args[3] = {surfaceID, 0, value};
@ -201,11 +205,11 @@ iosurface_set_indexed_timestamp_pointer(info.object, orig);
```
#### Exploit Flow Recap
1. **Sababisha Physical Use-After-Free**: Kurasa zilizotolewa zinaweza kutumika tena.
1. **Trigger Physical Use-After-Free**: Kurasa zilizofutwa zinaweza kutumika tena.
2. **Spray IOSurface Objects**: Tenga vitu vingi vya IOSurface na "magic value" ya kipekee katika kernel memory.
3. **Identify Accessible IOSurface**: Tafuta IOSurface kwenye ukurasa uliotolewa unaodhibiti.
4. **Abuse Use-After-Free**: Badilisha pointers katika object ya IOSurface ili kuwezesha arbitrary **kernel read/write** kupitia IOSurface methods.
3. **Identify Accessible IOSurface**: Tafuta IOSurface kwenye freed page unayodhibiti.
4. **Abuse Use-After-Free**: Badilisha pointers katika IOSurface object ili kuwezesha arbitrary **kernel read/write** kupitia IOSurface methods.
Kwa kutumia primitives hizi, the exploit hutoa controlled **32-bit reads** na **64-bit writes** kwa kernel memory. Hatua za ziada za jailbreak zinaweza kuhusisha primitives za read/write zenye utulivu zaidi, ambazo zinaweza kuhitaji kupitisha ulinzi wa ziada (mfano, PPL kwenye vifaa vipya vya arm64e).
Kwa primitives hizi, exploit inatoa controlled **32-bit reads** na **64-bit writes** kwa kernel memory. Hatua za ziada za jailbreak zinaweza kuhusisha read/write primitives imara zaidi, ambazo zinaweza kuhitaji kupitisha kinga za ziada (kwa mfano, PPL kwenye vifaa vipya vya arm64e).
{{#include ../../banners/hacktricks-training.md}}