Translated ['binary-exploitation/heap/README.md', 'binary-exploitation/h

This commit is contained in:
Translator 2024-05-10 17:44:54 +00:00
parent 7aecaf5b41
commit 053669b326
8 changed files with 625 additions and 77 deletions

View file

@ -721,7 +721,11 @@
* [Format Strings - Arbitrary Read Example](binary-exploitation/format-strings/format-strings-arbitrary-read-example.md)
* [Format Strings Template](binary-exploitation/format-strings/format-strings-template.md)
* [Heap](binary-exploitation/heap/README.md)
* [Use After Free](binary-exploitation/heap/use-after-free.md)
* [Bins & Memory Allocations](binary-exploitation/heap/bins-and-memory-allocations.md)
* [Heap Functions Security Checks](binary-exploitation/heap/heap-functions-security-checks.md)
* [Use After Free](binary-exploitation/heap/use-after-free/README.md)
* [First Fit](binary-exploitation/heap/use-after-free/first-fit.md)
* [Double Free](binary-exploitation/heap/double-free.md)
* [Heap Overflow](binary-exploitation/heap/heap-overflow.md)
* [Common Binary Exploitation Protections & Bypasses](binary-exploitation/common-binary-protections-and-bypasses/README.md)
* [ASLR](binary-exploitation/common-binary-protections-and-bypasses/aslr/README.md)

View file

@ -2,34 +2,34 @@
## Βασικά για τον Σωρό
Ο σωρός είναι βασικά το μέρος όπου ένα πρόγραμμα θα μπορεί να αποθηκεύει δεδομένα όταν ζητά δεδομένα καλώντας συναρτήσεις όπως **`malloc`**, `calloc`... Επιπλέον, όταν αυτή η μνήμη δεν χρειάζεται πλέον, γίνεται διαθέσιμη καλώντας τη συνάρτηση **`free`**.
Ο σωρός είναι βασικά το μέρος όπου ένα πρόγραμμα μπορεί να αποθηκεύσει δεδομένα όταν ζητά δεδομένα καλώντας συναρτήσεις όπως **`malloc`**, `calloc`... Επιπλέον, όταν αυτή η μνήμη δεν χρειάζεται πλέον, γίνεται διαθέσιμη καλώντας τη συνάρτηση **`free`**.
Όπως φαίνεται, βρίσκεται αμέσως μετά από το σημείο όπου φορτώνεται το δυαδικό στη μνήμη (ελέγξτε την ενότητα `[heap]`):
<figure><img src="../../.gitbook/assets/image (1241).png" alt=""><figcaption></figcaption></figure>
### Βασική Δέσμη Εκχώρησης
### Βασική Δέσμη Χονδρικής Εκχώρησης
Όταν ζητείται να αποθηκευτεί κάποιο δεδομένο στο σωρό, κάποιος χώρος του σωρού του εκχωρείται. Αυτός ο χώρος θα ανήκει σε μια δέσμη και μόνο τα ζητηθέντα δεδομένα + ο χώρος των κεφαλίδων της δέσμης + η ελάχιστη μετατόπιση μεγέθους δέσμης θα είναι κρατημένα για το κομμάτι. Ο στόχος είναι να κρατηθεί όσο το δυνατόν λιγότερη μνήμη χωρίς να γίνει περίπλοκο να βρεθεί πού βρίσκεται κάθε κομμάτι. Γι' αυτό, χρησιμοποιείται η πληροφορία μεταδεδομένων κομματιών για να γνωρίζουμε πού βρίσκεται κάθε χρησιμοποιούμενο/ελεύθερο κομμάτι.
Όταν ζητείται να αποθηκευτούν κάποια δεδομένα στο σωρό, κατανέμεται κάποιος χώρος του σωρού γι' αυτά. Αυτός ο χώρος θα ανήκει σε έναν κάδο και μόνο τα ζητηθέντα δεδομένα + ο χώρος των κεφαλίδων των κάδων + η ελάχιστη μετατόπιση μεγέθους κάδου θα είναι κρατημένα για το κομμάτι. Ο στόχος είναι να κρατηθεί όση μνήμη χρειάζεται χωρίς να γίνει περίπλοκο να βρεθεί πού βρίσκεται κάθε κομμάτι. Γι' αυτό, χρησιμοποιούνται πληροφορίες μεταδεδομένων κομματιών για να γνωρίζουν πού βρίσκεται κάθε χρησιμοποιούμενο/ελεύθερο κομμάτι.
Υπάρχουν διαφορετικοί τρόποι για την εκχώρηση χώρου κυρίως ανάλογα με τη χρησιμοποιούμενη δέσμη, αλλά μια γενική μεθοδολογία είναι η ακόλουθη:
Υπάρχουν διαφορετικοί τρόποι για την εκχώρηση χώρου κυρίως ανάλογα με τον χρησιμοποιούμενο κάδο, αλλά μια γενική μεθοδολογία είναι η ακόλουθη:
* Το πρόγραμμα ξεκινάει ζητώντας συγκεκριμένη ποσότητα μνήμης.
* Αν στη λίστα των κομματιών υπάρχει κάποιο διαθέσιμο αρκετά μεγάλο για να καλύψει το αίτημα, θα χρησιμοποιηθεί.
* Αυτό μπορεί ακόμη να σημαίνει ότι μέρος του διαθέσιμου κομματιού θα χρησιμοποιηθεί για αυτό το αίτημα και το υπόλοιπο θα προστεθεί στη λίστα των κομματιών
* Αν δεν υπάρχει διαθέσιμο κομμάτι στη λίστα αλλά υπάρχει ακόμη χώρος στην εκχωρημένη μνήμη του σωρού, ο διαχειριστής του σωρού δημιουργεί ένα νέο κομμάτι
* Αν δεν υπάρχει αρκετός χώρος στο σωρό για να εκχωρηθεί το νέο κομμάτι, ο διαχειριστής του σωρού ζητά από τον πυρήνα να επεκτείνει τη μνήμη που εκχωρείται στο σωρό και στη συνέχεια να χρησιμοποιήσει αυτή τη μνήμη για τη δημιουργία του νέου κομματιού
* Αν αποτύχει τα παραπάνω, το `malloc` επιστρέφει null.
* Αν στη λίστα των κομματιών υπάρχει κάποιο αρκετά μεγάλο για να καλύψει το αίτημα, θα χρησιμοποιηθεί.
* Αυτό μπορεί ακόμη να σημαίνει ότι ένα μέρος του διαθέσιμου κομματιού θα χρησιμοποιηθεί για αυτό το αίτημα και το υπόλοιπο θα προστεθεί στη λίστα των κομματιών
* Αν δεν υπάρχει κανένα διαθέσιμο κομμάτι στη λίστα αλλά υπάρχει ακόμη χώρος στην εκχωρημένη μνήμη του σωρού, ο διαχειριστής του σωρού δημιουργεί ένα νέο κομμάτι
* Αν δεν υπάρχει αρκετός χώρος στο σωρό για να εκχωρηθεί το νέο κομμάτι, ο διαχειριστής του σωρού ζητά από τον πυρήνα να επεκτείνει τη μνήμη που έχει εκχωρηθεί στο σωρό και στη συνέχεια να χρησιμοποιήσει αυτή τη μνήμη για να δημιουργήσει το νέο κομμάτι
* Αν αποτύχει τα πάντα, το `malloc` επιστρέφει null.
Σημειώστε ότι αν η ζητούμενη **μνήμη ξεπεράσει ένα κατώτατο όριο**, θα χρησιμοποιηθεί το **`mmap`** για να χαρτογραφήσει τη ζητούμενη μνήμη.
### Αρένες
Σε **πολυνηματικές** εφαρμογές, ο διαχειριστής του σωρού πρέπει να αποτρέψει τις **συνθήκες ανταγωνισμού** που θα μπορούσαν να οδηγήσουν σε κολάπτες. Αρχικά, αυτό επιτυγχάνονταν χρησιμοποιώντας ένα **καθολικό κλειδαριά** για να εξασφαλίσει ότι μόνο ένα νήμα θα μπορούσε να έχει πρόσβαση στο σωρό ταυτόχρονα, αλλά αυτό προκαλούσε **προβλήματα απόδοσης** λόγω του φραγμού που προκαλούσε η κλειδαριά.
Σε **πολυνηματικές** εφαρμογές, ο διαχειριστής του σωρού πρέπει να αποτρέψει τις **συνθήκες ανταγωνισμού** που θα μπορούσαν να οδηγήσουν σε κολάπτες. Αρχικά, αυτό επιτελούνταν χρησιμοποιώντας ένα **καθολικό κλειδαριά** για να διασφαλιστεί ότι μόνο ένα νήμα μπορούσε να έχει πρόσβαση στο σωρό ταυτόχρονα, αλλά αυτό προκαλούσε **προβλήματα απόδοσης** λόγω του φραγμού που προκαλούσε η κλειδαριά.
Για να αντιμετωπίσει αυτό, ο αναθέτης σωρού ptmalloc2 εισήγαγε "αρένες", όπου **κάθε αρένα** λειτουργεί ως ένας **ξεχωριστός σωρός** με τις **δικές της** δομές **δεδομένων** και **κλειδαριά**, επιτρέποντας σε πολλά νήματα να εκτελούν λειτουργίες σωρού χωρίς να επηρεάζουν ο ένας τον άλλο, όσον αφορά τις αρένες.
Η προεπιλεγμένη "κύρια" αρένα χειρίζεται τις λειτουργίες σωρού για μονονηματικές εφαρμογές. Όταν προστίθενται **νέα νήματα**, ο διαχειριστής του σωρού αναθέτει σε αυτά **δευτερεύουσες αρένες** για να μειώσει τον ανταγωνισμό. Πρώτα προσπαθεί να συνδέσει κάθε νέο νήμα σε μια αχρησιμοποίητη αρένα, δημιουργώντας νέες αν χρειαστεί, μέχρι ένα όριο 2 φορές του αριθμού των πυρήνων CPU για συστήματα 32-bit και 8 φορές για συστήματα 64-bit. Αφού επιτευχθεί το όριο, τα νήματα πρέπει να μοιράζονται αρένες, οδηγώντας σε πιθανό ανταγωνισμό.
Η προεπιλεγμένη "κύρια" αρένα χειρίζεται τις λειτουργίες σωρού για μονονηματικές εφαρμογές. Όταν προστίθενται **νέα νήματα**, ο διαχειριστής του σωρού αναθέτει σε αυτά **δευτερεύουσες αρένες** για να μειώσει τον ανταγωνισμό. Πρώτα προσπαθεί να συνδέσει κάθε νέο νήμα σε μια αχρησιμοποίητη αρένα, δημιουργώντας νέες αν χρειαστεί, μέχρι ένα όριο 2 φορές του αριθμού των πυρήνων CPU για συστήματα 32-bit και 8 φορές για συστήματα 64-bit. Μόλις φτάσει το όριο, τα νήματα πρέπει να μοιράζονται αρένες, οδηγώντας σε πιθανό ανταγωνισμό.
Αντίθετα με την κύρια αρένα, η οποία επεκτείνεται χρησιμοποιώντας την κλήση συστήματος `brk`, οι δευτερεύουσες αρένες δημιουργούν "υποσωρούς" χρησιμοποιώντας `mmap` και `mprotect` για να προσομοιώσουν τη συμπεριφορά του σωρού, επιτρέποντας ευελιξία στη διαχείριση μνήμης για πολυνηματικές λειτουργίες.
@ -39,87 +39,95 @@
1. **Αρχικός Σωρός έναντι Υποσωρών**:
* Ο αρχικός σωρός βρίσκεται αμέσως μετά το δυαδικό του προγράμματος στη μνήμη και επεκτείνεται χρησιμοποιώντας την κλήση συστήματος `sbrk`.
* Οι υποσωροί, που χρησιμοποιούνται από τις δευτερεύουσες αρένες, δημιουργούνται μέσω `mmap`, μιας κλήσης συστήματος που χαρτογραφεί μια συγκεκριμένη περιοχή μνήμης.
2. **Εκχώρηση Μνήμης με το `mmap`**:
* Όταν ο διαχειριστής του σωρού δημιουργεί έναν υποσωρό, εκχωρεί ένα μεγάλο τμήμα μνήμης μέσω `mmap`. Αυτή η εκχώρηση δεν κατανέμει μνήμη αμέσως· απλώς καθορίζει μια περιοχή που άλλες διεργασίες του συστήματος ή εκχωρήσεις δεν πρέπει να χρησιμοποιούν.
* Από προεπιλογή, το μέγεθος της εκχωρημένης μνήμης για έναν υποσωρό είναι 1 MB για διεργασίες 32-bit και 64 MB για διεργασίες 64-bit.
3. **Σταδιακή Επέκταση με το `mprotect`**:
* Η εκχωρημέ
## Bins
* Οι υποσωροί, χρησιμοποιούμενοι από δευτερεύουσες αρένες, δημιουργούνται μέσω `mmap`, μιας κλήσης συστήματος που χαρτογραφεί μια συγκεκριμένη περιοχή μνήμης.
2. **Επιφύλαξη Μνήμης με `mmap`**:
* Όταν ο διαχειριστής του σωρού δημιουργεί έναν υποσωρό, επιφυλάσσει ένα μεγάλο τμήμα μνήμης μέσω του `mmap`. Αυτή η επιφύλαξη δεν εκχωρεί μνήμη αμέσως· απλώς καθορίζει μια περιοχή που άλλες διεργασίες του συστήματος ή εκχωρήσεις δεν πρέπει να χρησιμοποιούν.
* Από προεπιλογή, το μέγεθος της επιφύλαξης για έναν υποσωρό είναι 1 MB για διεργασίες 32-bit και 64 MB για διεργασίες 64-bit.
3. **Σταδιακή Επέκταση με `mprotect`**:
* Η επιφυλαγμέ
```c
// From https://heap-exploitation.dhavalkapil.com/diving_into_glibc_heap/malloc_state
struct malloc_state
{
/* Serialize access. */
__libc_lock_define (, mutex);
/* Flags (formerly in max_fast). */
int flags;
Για να βελτιωθεί η αποδοτικότητα στον τρόπο αποθήκευσης των τμημάτων, κάθε τμήμα δεν βρίσκεται μόνο σε μια συνδεδεμένη λίστα, αλλά υπάρχουν διάφοροι τύποι. Αυτοί είναι οι κάδοι και υπάρχουν 5 τύποι κάδων: [62](https://sourceware.org/git/gitweb.cgi?p=glibc.git;a=blob;f=malloc/malloc.c;h=6e766d11bc85b6480fa5c9f2a76559f8acf9deb5;hb=HEAD#l1407) μικροί κάδοι, 63 μεγάλοι κάδοι, 1 μη ταξινομημένος κάδος, 10 γρήγοροι κάδοι και 64 κάδοι tcache ανά νήμα.
/* Fastbins */
mfastbinptr fastbinsY[NFASTBINS];
/* Base of the topmost chunk -- not otherwise kept in a bin */
mchunkptr top;
/* The remainder from the most recent split of a small request */
mchunkptr last_remainder;
/* Normal bins packed as described above */
mchunkptr bins[NBINS * 2 - 2];
Η αρχική διεύθυνση για κάθε μη ταξινομημένο, μικρό και μεγάλο κάδο βρίσκεται μέσα στον ίδιο πίνακα. Το δείκτης 0 δεν χρησιμοποιείται, ο 1 είναι ο μη ταξινομημένος κάδος, οι κάδοι 2-64 είναι μικροί κάδοι και οι κάδοι 65-127 είναι μεγάλοι κάδοι.
/* Bitmap of bins */
unsigned int binmap[BINMAPSIZE];
### Μικροί Κάδοι
/* Linked list */
struct malloc_state *next;
/* Linked list for free arenas. Access to this field is serialized
by free_list_lock in arena.c. */
struct malloc_state *next_free;
/* Number of threads attached to this arena. 0 if the arena is on
the free list. Access to this field is serialized by
free_list_lock in arena.c. */
Οι μικροί κάδοι είναι ταχύτεροι από τους μεγάλους κάδους αλλά πιο αργοί από τους γρήγορους κάδους.
INTERNAL_SIZE_T attached_threads;
/* Memory allocated from the system in this arena. */
INTERNAL_SIZE_T system_mem;
INTERNAL_SIZE_T max_system_mem;
};
Κάθε κάδος από τους 62 θα έχει **τμήματα με τον ίδιο μέγεθος**: 16, 24, ... (με μέγιστο μέγεθος 504 bytes σε 32bit και 1024 σε 64bit). Αυτό βοηθάει στην ταχύτητα εύρεσης του κάδου όπου θα πρέπει να γίνει μια εκχώρηση χώρου και στην εισαγωγή και αφαίρεση καταχωρήσεων σε αυτές τις λίστες.
typedef struct malloc_state *mstate;
```
### malloc\_chunk
### Μεγάλοι Κάδοι
Αυτή η δομή αντιπροσωπεύει ένα συγκεκριμένο κομμάτι μνήμης. Τα διάφορα πεδία έχουν διαφορετική σημασία για τα κομμάτια μνήμης που έχουν εκχωρηθεί και για αυτά που δεν έχουν εκχωρηθεί.
```c
// From https://heap-exploitation.dhavalkapil.com/diving_into_glibc_heap/malloc_chunk
struct malloc_chunk {
INTERNAL_SIZE_T mchunk_prev_size; /* Size of previous chunk, if it is free. */
INTERNAL_SIZE_T mchunk_size; /* Size in bytes, including overhead. */
struct malloc_chunk* fd; /* double links -- used only if this chunk is free. */
struct malloc_chunk* bk;
/* Only used for large blocks: pointer to next larger size. */
struct malloc_chunk* fd_nextsize; /* double links -- used only if this chunk is free. */
struct malloc_chunk* bk_nextsize;
};
Αντίθετα με τους μικρούς κάδους, οι οποίοι διαχειρίζονται τμήματα με σταθερά μεγέθη, κάθε **μεγάλος κάδος διαχειρίζεται ένα εύρος μεγεθών τμημάτων**. Αυτό είναι πιο ευέλικτο, επιτρέποντας στο σύστημα να φιλοξενεί **διάφορα μεγέθη** χωρίς την ανάγκη για έναν ξεχωριστό κάδο για κάθε μέγεθος.
typedef struct malloc_chunk* mchunkptr;
```
Όπως σχολιάστηκε προηγουμένως, αυτά τα κομμάτια έχουν επίσης μερικά μεταδεδομένα, πολύ καλά αναπαριστώμενα σε αυτήν την εικόνα:
Σε έναν διαχειριστή μνήμης, οι μεγάλοι κάδοι ξεκινούν από εκεί που τελειώνουν οι μικροί κάδοι. Τα εύρη για τους μεγάλους κάδους μεγαλώνουν σταδιακά, που σημαίνει ότι ο πρώτος κάδος μπορεί να καλύπτει τμήματα από 512 έως 576 bytes, ενώ ο επόμενος καλύπτει από 576 έως 640 bytes. Αυτό το πρότυπο συνεχίζεται, με τον μεγαλύτερο κάδο να περιέχει όλα τα τμήματα άνω των 1MB.
<figure><img src="../../.gitbook/assets/image (1242).png" alt=""><figcaption><p><a href="https://azeria-labs.com/wp-content/uploads/2019/03/chunk-allocated-CS.png">https://azeria-labs.com/wp-content/uploads/2019/03/chunk-allocated-CS.png</a></p></figcaption></figure>
Οι μεγάλοι κάδοι είναι πιο αργοί στη λειτουργία σε σύγκριση με τους μικρούς κάδους επειδή πρέπει **να ταξινομήσουν και να αναζητήσουν μέσω μιας λίστας με διαφορετικά μεγέθη τμημάτων για να βρουν την καλύτερη ταιριάστηκα για μια εκχώρηση**. Όταν ένα τμήμα εισάγεται σε έναν μεγάλο κάδο, πρέπει να ταξινομηθεί, και όταν γίνεται εκχώρηση μνήμης, το σύστημα πρέπει να βρει το σωστό τμήμα. Αυτή η επιπλέον εργασία τους καθιστά **πιο αργούς**, αλλά επειδή οι μεγάλες εκχωρήσεις είναι λιγότερο συνηθισμένες από τις μικρές, είναι μια αποδεκτή ανταλλαγή.
Τα μεταδεδομένα είναι συνήθως 0x08B, υποδεικνύοντας το μέγεθος του τρέχοντος κομματιού χρησιμοποιώντας τα τελευταία 3 bits για να υποδείξει:
Υπάρχουν:
* `A`: Αν είναι 1 προέρχεται από έναν υπο-σωρό, αν είναι 0 βρίσκεται στην κύρια αρένα
* `M`: Αν είναι 1, αυτό το κομμάτι είναι μέρος ενός χώρου που έχει εκχωρηθεί με το mmap και όχι μέρος ενός σωρού
* `P`: Αν είναι 1, το προηγούμενο κομμάτι είναι σε χρήση
* 32 κάδοι εύρους 64B
* 16 κάδοι εύρους 512B
* 8 κάδοι εύρους 4096B
* 4 κάδοι εύρους 32768B
* 2 κάδοι εύρους 262144B
* 1 κάδος για υπενθυμίσεις μεγεθών
Στη συνέχεια, ο χώρος για τα δεδομένα του χρήστη, και τέλος 0x08B για να υποδείξει το μέγεθος του προηγούμενου κομματιού όταν το κομμάτι είναι διαθέσιμο (ή για να αποθηκεύσει τα δεδομένα του χρήστη όταν είναι εκχωρημένο).
### Μη Ταξινομημένος Κάδος
Επιπλέον, όταν είναι διαθέσιμα, τα δεδομένα του χρήστη χρησιμοποιούνται επίσης για να περιέχουν κάποια δεδομένα:
Ο μη ταξινομημένος κάδος είναι ένας **γρήγορος προσωρινός χώρος** που χρησιμοποιείται από τον διαχειριστή στοίβας για να κάνει την εκχώρηση μνήμης πιο γρήγορη. Έτσι λειτουργεί: Όταν ένα πρόγραμμα απελευθερώνει μνήμη, ο διαχειριστής στοίβας δεν το τοποθετεί αμέσως σε ένα συγκεκριμένο κάδο. Αντ' αυτού, πρώτα προσπαθεί να **συγχωνεύσει το με οποιαδήποτε γειτονικά ελεύθερα τμήματα** για να δημιουργήσει ένα μεγαλύτερο τμήμα ελεύθερης μνήμης. Στη συνέχεια, το τοποθετεί αυτό το νέο τμήμα σε ένα γενικό κάδο που ονομάζεται "μη ταξινομημένος κάδος".
* Δείκτη προς το επόμενο κομμάτι
* Δείκτη προς το προηγούμενο κομμάτι
* Μέγεθος του επόμενου κομματιού στη λίστα
* Μέγεθος του προηγούμενου κομματιού στη λίστα
Όταν ένα πρόγραμμα ζητά **μνήμη**, ο διαχειριστής στοίβας **ελέγχει πρώτα τον μη ταξινομημένο κάδο** για να δει αν υπάρχει ένα τμήμα του σωστού μεγέθους. Αν βρει ένα, το χρησιμοποιεί αμέσως, που είναι ταχύτερο από την αναζήτηση σε άλλους κάδους. Αν δε βρει ένα κατάλληλο τμήμα, μεταφέρει τα ελεύθερα τμήματα στους σωστούς κάδους τους, είτε μικρούς είτε μεγάλους, με βάση το μέγεθός τους.
<figure><img src="../../.gitbook/assets/image (1243).png" alt=""><figcaption><p><a href="https://azeria-labs.com/wp-content/uploads/2019/03/chunk-allocated-CS.png">https://azeria-labs.com/wp-content/uploads/2019/03/chunk-allocated-CS.png</a></p></figcaption></figure>
Έτσι, ο μη ταξινομημένος κάδος είναι ένας τρόπος για να επιταχυνθεί η εκχώρηση μνήμης με την ταχεία επαναχρησιμοποίηση πρόσφατα απελευθερωμένης μνήμης και τη μείωση της ανάγκης για χρονοβόρες αναζητήσεις και συγχωνεύσεις.
{% hint style="danger" %}
Σημειώστε ότι ακόμα και αν τα τμήματα είναι διαφορετικών κατηγοριών, από καιρό σε καιρό, αν ένα διαθέσιμο τμήμα συγκρούεται με ένα άλλο διαθέσιμο τμήμα (ακόμα κι αν είναι διαφορετικών κατηγοριών), θα συγχωνευτούν.
{% hint style="info" %}
Σημειώστε πώς η ταξινόμηση της λίστας με αυτόν τον τρόπο αποτρέπει την ανάγκη να υπάρχει ένας πίνακας όπου κάθε μεμονωμένο κομμάτι καταγράφεται.
{% endhint %}
### Γρήγοροι Κάδοι
### Γρήγορο Παράδειγμα Σωρού
Οι γρήγοροι κάδοι σχεδιάστηκαν για να **επιταχύνουν την εκχώρηση μνήμης για μικρά τμήματα** κρατώντας πρόσφατα απελευθερωμένα τμήματα σε μια δομή γρήγορης πρόσβασης. Αυτοί οι κάδοι χρησιμοποιούν μια προσέγγιση Τελευταίο Εισερχόμενο, Πρώτο Εξερχόμενο (LIFO), που σημαίνει ότι το **πιο πρόσφατα απελευθερωμένο τμήμα είναι το πρώτο** που θα επαναχρησιμοποιηθεί όταν υπάρχει αίτηση για νέα εκχώρηση. Αυτή η συμπεριφορά είναι επωφελής για την ταχύτητα, καθώς είναι πιο γρήγορο να εισαχθεί και να αφαιρεθεί από την κορυφή ενός σωρού (LIFO) σε σύγκριση με μια ουρά (FIFO).
Επιπλέον, **οι γρήγοροι κάδοι χρησιμοποιούν μονόδεσμες λίστες**, όχι διπλά δεσμευμένες, που βελτιώνει περαιτέρω την ταχύτητα. Δεδομένου ότι τα τμήματα στους γρήγορους κάδους δε συγχωνεύονται με γειτονικά, δεν χρειάζεται μια πολύπλοκη δομή που επιτρέπει την αφαίρεση από τη μέση. Μια μονόδεσμη λίστα είναι απλούστερη και ταχύτερη για αυτές τις λειτουργίες.
Βασικά, αυτό που σ
### Τακτική των κάδων
#### Για την εκχώρηση:
1. Αν υπάρχει διαθέσιμο τμήμα στο Tcache αυτού του μεγέθους, χρησιμοποιήστε το Tcache
2. Αν είναι πολύ μεγάλο, χρησιμοποιήστε το mmap
3. Αποκτήστε το κλείδωμα σωρού της αρένας και:
1. Αν υπάρχει αρκετό μικρό μέγεθος, τμήμα fast bin διαθέσιμο του ζητούμενου μεγέθους, χρησιμοποιήστε το και προ-γεμίστε το Tcache από το fast bin
2. Ελέγξτε κάθε καταχώρηση στη λίστα μη ταξινομημένων αναζητώντας ένα τμήμα αρκετά μεγάλο, και προ-γεμίστε το Tcache αν είναι δυνατόν
3. Ελέγξτε τους μικρούς κάδους ή τους μεγάλους κάδους (σύμφωνα με το ζητούμενο μέγεθος) και προ-γεμίστε το Tcache αν είναι δυνατόν
4. Δημιουργήστε ένα νέο τμήμα από διαθέσιμη μνήμη
1. Αν δεν υπάρχει διαθέσιμη μνήμη, αποκτήστε περισσότερη χρησιμοποιώντας `sbrk`
2. Αν η κύρια μνήμη του σωρού δεν μπορεί να αυξηθεί περισσότερο, δημιουργήστε ένα νέο χώρο χρησιμοποιώντας το mmap
5. Αν τίποτα δεν λειτούργησε, επιστρέψτε null
**Για την απελευθέρωση:**
1. Αν ο δείκτης είναι Null, ολοκληρώστε
2. Εκτελέστε ελέγχους ακεραιότητας `free` στο τμήμα για να επιχειρήσετε να επιβεβαιώσετε ότι είναι έγκυρο τμήμα
1. Αν είναι αρκετά μικρό και το Tcache δεν είναι γεμάτο, τοποθετήστε το εκεί
2. Αν το bit M είναι ενεργοποιημένο (όχι σωρός), χρησιμοποιήστε το `munmap`
3. Λάβετε το κλείδωμα σωρού της αρένας:
1. Αν χωράει σε ένα fastbin, τοποθετήστε το εκεί
2. Αν το τμήμα είναι > 64KB, συγχωνεύστε αμέσως τα fastbins και τοποθετήστε τα αποτελέσματα συγχωνευμένων τμημάτων στον μη ταξινομημένο κάδο.
3. Συγχωνεύστε το τμήμα προς τα πίσω και προς τα εμπρός με τα γειτονικά ελεύθερα τμήματα στους μικρούς, μεγάλους και μη ταξινομημένους κάδους αν υπάρχουν.
4. Αν είναι στην κορυφή της κεφαλής, συγχωνεύστε το στην αχρησιμοποίητη μνήμη
5. Αν δεν είναι στα προηγούμενα, αποθηκεύστε το στη λίστα μη ταξινομημένων
Γρήγορο παράδειγμα σωρού από [https://guyinatuxedo.github.io/25-heap/index.html](https://guyinatuxedo.github.io/25-heap/index.html) αλλά σε arm64:
```c
#include <stdio.h>
#include <stdlib.h>
@ -138,13 +146,27 @@ strcpy(ptr, "panda");
Είναι δυνατόν να δούμε ότι η συμβολοσειρά "panda" αποθηκεύτηκε στη διεύθυνση `0xaaaaaaac12a0` (η οποία ήταν η διεύθυνση που δόθηκε ως απάντηση από την malloc μέσα στο `x0`). Ελέγχοντας 0x10 bytes πριν από αυτήν, είναι δυνατόν να δούμε ότι το `0x0` αντιπροσωπεύει ότι το **προηγούμενο τμήμα δεν χρησιμοποιείται** (μήκος 0) και ότι το μήκος αυτού του τμήματος είναι `0x21`.
Τα επιπλέον κενά που διατηρούνται (0x21-0x10=0x11) προέρχονται από τα **προστιθέμενα κεφαλίδες** (0x10) και το 0x1 δεν σημαίνει ότι κρατήθηκαν 0x21B αλλά τα τελευταία 3 bits του μήκους της τρέχουσας κεφαλίδας έχουν κάποιες ειδικές σημασίες. Δεδομένου ότι το μήκος είναι πάντα σε ευθυγραμμισμένα 16-byte (σε μηχανές 64bit), αυτά τα bits προφανώς δεν θα χρησιμοποιηθούν ποτέ από τον αριθμό μήκους.
Τα επιπλέον κενά που κρατήθηκαν (0x21-0x10=0x11) προέρχονται από τα **προστιθέμενα κεφαλίδες** (0x10) και το 0x1 δεν σημαίνει ότι κρατήθηκαν 0x21B αλλά τα τελευταία 3 bits του μήκους της τρέχουσας κεφαλίδας έχουν κάποιες ειδικές σημασίες. Δεδομένου ότι το μήκος είναι πάντα σε ευθυγραμμισμένα 16-byte (σε μηχανές 64 bits), αυτά τα bits προφανώς δεν θα χρησιμοποιηθούν ποτέ από τον αριθμό του μήκους.
```
0x1: Previous in Use - Specifies that the chunk before it in memory is in use
0x2: Is MMAPPED - Specifies that the chunk was obtained with mmap()
0x4: Non Main Arena - Specifies that the chunk was obtained from outside of the main arena
```
##
## Bins & Εκχωρήσεις/Απελευθερώσεις Μνήμης
Ελέγξτε ποια είναι τα bins και πώς οργανώνονται και πώς γίνεται η εκχώρηση και απελευθέρωση μνήμης σε:
{% content-ref url="bins-and-memory-allocations.md" %}
[bins-and-memory-allocations.md](bins-and-memory-allocations.md)
{% endcontent-ref %}
## Έλεγχοι Ασφαλείας Συναρτήσεων Heap
Οι συναρτήσεις που σχετίζονται με το heap θα πραγματοποιήσουν ορισμένους ελέγχους πριν εκτελέσουν τις ενέργειές τους προκειμένου να βεβαιωθούν ότι το heap δεν έχει διαφθαρεί:
{% content-ref url="heap-functions-security-checks.md" %}
[heap-functions-security-checks.md](heap-functions-security-checks.md)
{% endcontent-ref %}
## Αναφορές

View file

@ -0,0 +1,158 @@
# Bins & Εκχωρήσεις Μνήμης
<details>
<summary><strong>Μάθετε το χάκινγκ του AWS από το μηδέν μέχρι τον ήρωα με το</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
Άλλοι τρόποι υποστήριξης του HackTricks:
* Αν θέλετε να δείτε την **εταιρεία σας διαφημισμένη στο HackTricks** ή να **κατεβάσετε το HackTricks σε μορφή PDF** ελέγξτε τα [**ΣΧΕΔΙΑ ΣΥΝΔΡΟΜΗΣ**](https://github.com/sponsors/carlospolop)!
* Αποκτήστε το [**επίσημο PEASS & HackTricks swag**](https://peass.creator-spring.com)
* Ανακαλύψτε την [**Οικογένεια PEASS**](https://opensea.io/collection/the-peass-family), τη συλλογή μας από αποκλειστικά [**NFTs**](https://opensea.io/collection/the-peass-family)
* **Εγγραφείτε στη** 💬 [**ομάδα Discord**](https://discord.gg/hRep4RUj7f) ή στη [**ομάδα τηλεγραφήματος**](https://t.me/peass) ή **ακολουθήστε** μας στο **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Μοιραστείτε τα χάκινγκ κόλπα σας υποβάλλοντας PRs στα** [**HackTricks**](https://github.com/carlospolop/hacktricks) και [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) αποθετήρια του github.
</details>
## Βασικές Πληροφορίες
Για να βελτιώσετε την αποδοτικότητα στον τρόπο αποθήκευσης των τμημάτων, κάθε τμήμα δεν βρίσκεται μόνο σε μια συνδεδεμένη λίστα, αλλά υπάρχουν διάφοροι τύποι. Αυτοί είναι οι bins και υπάρχουν 5 τύποι bins: [62](https://sourceware.org/git/gitweb.cgi?p=glibc.git;a=blob;f=malloc/malloc.c;h=6e766d11bc85b6480fa5c9f2a76559f8acf9deb5;hb=HEAD#l1407) μικροί bins, 63 μεγάλοι bins, 1 unsorted bin, 10 fast bins και 64 tcache bins ανά νήμα.
Η αρχική διεύθυνση για κάθε unsorted, small και large bin βρίσκεται μέσα στον ίδιο πίνακα. Το δείκτης 0 δεν χρησιμοποιείται, το 1 είναι το unsorted bin, τα bins 2-64 είναι μικροί bins και τα bins 65-127 είναι μεγάλοι bins.
### Μικροί Bins
Οι μικροί bins είναι ταχύτεροι από τους μεγάλους bins αλλά πιο αργοί από τους fast bins.
Κάθε bin από τα 62 θα έχει **chunks του ίδιου μεγέθους**: 16, 24, ... (με μέγιστο μέγεθος 504 bytes σε 32bits και 1024 σε 64bits). Αυτό βοηθάει στην ταχύτητα εύρεσης του bin όπου θα πρέπει να γίνει εκχώρηση χώρου και στην εισαγωγή και αφαίρεση καταχωρήσεων σε αυτές τις λίστες.
### Μεγάλοι Bins
Αντίθετα με τους μικρούς bins, οι οποίοι διαχειρίζονται τμήματα με σταθερά μεγέθη, κάθε **μεγάλος bin διαχειρίζεται ένα εύρος μεγεθών τμημάτων**. Αυτό είναι πιο ευέλικτο, επιτρέποντας στο σύστημα να φιλοξενεί **διάφορα μεγέθη** χωρίς την ανάγκη για έναν ξεχωριστό bin για κάθε μέγεθος.
Σε έναν διαχειριστή μνήμης, οι μεγάλοι bins ξεκινούν από εκεί που τελειώνουν οι μικροί bins. Τα εύρη των μεγάλων bins μεγαλώνουν σταδιακά, που σημαίνει ότι το πρώτο bin μπορεί να καλύπτει τμήματα από 512 έως 576 bytes, ενώ το επόμενο καλύπτει από 576 έως 640 bytes. Αυτό το πρότυπο συνεχίζεται, με τον μεγαλύτερο bin να περιέχει όλα τα τμήματα άνω των 1MB.
Οι μεγάλοι bins είναι πιο αργοί στη λειτουργία σε σύγκριση με τους μικρούς bins επειδή πρέπει **να ταξινομήσουν και να αναζητήσουν μέσω μιας λίστας με διαφορετικά μεγέθη τμημάτων για να βρουν την καλύτερη ταιριάστηκη** για μια εκχώρηση. Όταν ένα τμήμα εισάγεται σε έναν μεγάλο bin, πρέπει να ταξινομηθεί, και όταν γίνεται εκχώρηση μνήμης, το σύστημα πρέπει να βρει το σωστό τμήμα. Αυτή η επιπλέον εργασία τους καθιστά **πιο αργούς**, αλλά επειδή οι μεγάλες εκχωρήσεις είναι λιγότερο συνηθισμένες από τις μικρές, είναι μια αποδεκτή ανταλλαγή.
Υπάρχουν:
* 32 bins εύρους 64B
* 16 bins εύρους 512B
* 8 bins εύρους 4096B
* 4 bins εύρους 32768B
* 2 bins εύρους 262144B
* 1 bin για υπενθύμιση μεγεθών
### Unsorted bin
Το unsorted bin είναι ένα **γρήγορο cache** που χρησιμοποιεί ο διαχειριστής του σωρού για να κάνει την εκχώρηση μνήμης πιο γρήγορη. Έτσι λειτουργεί: Όταν ένα πρόγραμμα απελευθερώνει μνήμη, ο διαχειριστής του σωρού δεν την τοποθετεί αμέσως σε ένα συγκεκριμένο bin. Αντ' αυτού, πρώτα προσπαθεί να **συγχωνεύσει με οποιαδήποτε γειτονικά ελεύθερα τμήματα** για να δημιουργήσει ένα μεγαλύτερο τμήμα ελεύθερης μνήμης. Στη συνέχεια, το τοποθετεί αυτό το νέο τμήμα σε ένα γενικό bin που ονομάζεται "unsorted bin".
Όταν ένα πρόγραμμα ζητά μνήμη, ο διαχειριστής του σωρού **ελέγχει το unsorted bin** για να δει αν υπάρχει ένα τμήμα αρκετά μεγάλο. Αν βρει ένα, το χρησιμοποιεί αμέσως. Αν δεν βρει ένα κατάλληλο τμήμα, μεταφέρει τα ελεύθερα τμήματα στα αντίστοιχα bins τους, είτε μικρά είτε μεγάλα, με βάση το μέγεθός τους.
Έτσι, το unsorted bin είναι ένας τρόπος για να επιταχυνθεί η εκχώρηση μνήμης με την γρήγορη επαναχρησιμοποίηση πρόσφατα απελευθερωμένης μνήμης και τη μείωση της ανάγκης για χρονοβόρες αναζητήσεις και συγχωνεύσεις.
{% hint style="danger" %}
Σημειώστε ότι ακόμα και αν τα τμήματα είναι διαφορετικών κατηγοριών, αν ένα διαθέσιμο τμήμα συγκρούεται με ένα άλλο διαθέσιμο τμήμα (ακόμα κι αν είναι διαφορετικών κατηγοριών), θα συγχωνευτούν.
{% endhint %}
### Fast bins
Οι fast bins σχεδιάστηκαν για να **επιταχύνουν την εκχώρηση μνήμης για μικρά τμήματα** κρατώντας πρόσφατα απελευθερωμένα τμήματα σε μια δομή γρήγορης πρόσβασης. Αυτά τα bins χρησιμοποιούν μια προσέγγιση Last-In, First-Out (LIFO), που σημαίνει ότι το **πιο πρόσφατα απελευθερωμένο τμήμα είναι το πρώτο** που θα χρησιμοποιηθεί όταν υπάρχει αίτηση για νέα εκχώρηση. Αυτή η συμπεριφορά είναι επωφελής για την ταχύτητα, καθώς είναι πιο γρήγορο να εισάγετε και να αφαιρέσετε από την κορυφή μιας στοίβας (LIFO) σε σύγκριση με μια ουρά (FIFO).
Επιπλέον, **οι fast bins χρησιμοποιούν μονόδεσμες λίστες**, όχι διπλές, που βελτιώνει περαιτέρω την ταχύτητα. Δεδομένου ότι τα τμήματα στους fast bins δεν συγ
## Ροή Κατανομής
{% hint style="success" %}
(Η τρέχουσα εξήγηση προέρχεται από [https://heap-exploitation.dhavalkapil.com/diving\_into\_glibc\_heap/core\_functions](https://heap-exploitation.dhavalkapil.com/diving\_into\_glibc\_heap/core\_functions). TODO: Ελέγξτε την τελευταία έκδοση και ενημερώστε την)
{% endhint %}
Οι κατανομές πραγματοποιούνται τελικά με τη λειτουργία: `void * _int_malloc (mstate av, size_t bytes)` και ακολουθούν αυτήν τη σειρά:
1. Ενημερώνει το `bytes` για να αντιμετωπίσει τις **ευθυγραμμίσεις**, κ.λπ.
2. Ελέγχει αν το `av` είναι **NULL** ή όχι.
3. Στην περίπτωση απουσίας **χρήσιμης αρένας** (όταν το `av` είναι NULL), καλεί το `sysmalloc` για να λάβει κομμάτι χρησιμοποιώντας το mmap. Εάν είναι επιτυχές, καλεί το `alloc_perturb`. Επιστρέφει το δείκτη.
4. Ανάλογα με το μέγεθος:
* \[Προσθήκη στον αρχικό κώδικα] Χρησιμοποιήστε το tcache πριν ελέγξετε τον επόμενο fastbin.
* \[Προσθήκη στον αρχικό κώδικα] Αν δεν υπάρχει tcache αλλά χρησιμοποιείται διαφορετικός bin (δείτε το επόμενο βήμα), προσπαθήστε να γεμίσετε το tcache από αυτόν τον bin
* Αν το μέγεθος ανήκει στο εύρος του **fastbin**:
1. Πάρτε δείκτη στον πίνακα fastbin για να έχετε πρόσβαση σε ένα κατάλληλο bin σύμφωνα με το μέγεθος του αιτήματος.
2. Αφαιρεί το πρώτο κομμάτι σε αυτόν τον bin και κάνει το `victim` να δείχνει σε αυτό.
3. Αν το `victim` είναι NULL, προχωρήστε στην επόμενη περίπτωση (smallbin).
4. Αν το `victim` δεν είναι NULL, ελέγξτε το μέγεθος του κομματιού για να βεβαιωθείτε ότι ανήκει σε αυτόν τον συγκεκριμένο bin. Διαφορετικά εκτοξεύεται ένα σφάλμα ("malloc(): μνήμη που διαφθείρεται (fast)").
5. Καλεί το `alloc_perturb` και στη συνέχεια επιστρέφει το δείκτη.
* Αν το μέγεθος ανήκει στο εύρος του **smallbin**:
1. Πάρτε δείκτη στον πίνακα smallbin για να έχετε πρόσβαση σε ένα κατάλληλο bin σύμφωνα με το μέγεθος του αιτήματος.
2. Αν δεν υπάρχουν κομμάτια σε αυτόν τον bin, προχωρήστε στην επόμενη περίπτωση. Αυτό ελέγχεται συγκρίνοντας τους δείκτες `bin` και `bin->bk`.
3. Το `victim` γίνεται ίσο με το `bin->bk` (το τελευταίο κομμάτι στο bin). Αν είναι NULL (συμβαίνει κατά την `αρχικοποίηση`), καλέστε το `malloc_consolidate` και παραλείψτε αυτό το πλήρες βήμα ελέγχου σε διαφορετικούς bins.
4. Διαφορετικά, όταν το `victim` δεν είναι NULL, ελέγξτε αν `victim->bk->fd` και `victim` είναι ίσα ή όχι. Αν δεν είναι ίσα, εκτοξεύεται ένα σφάλμα (`malloc(): διπλή διαφθορά μικρού bin`).
5. Ορίζει το bit PREV\_INSUSE για το επόμενο κομμάτι (στη μνήμη, όχι στη διπλά συνδεδεμένη λίστα) για το `victim`.
6. Αφαιρεί αυτό το κομμάτι από τη λίστα του bin.
7. Ορίζει το κατάλληλο bit αρένας για αυτό το κομμάτι ανάλογα με το `av`.
8. Καλεί το `alloc_perturb` και στη συνέχεια επιστρέφει το δείκτη.
* Αν το μέγεθος δεν ανήκει στο εύρος του smallbin:
1. Πάρτε δείκτη στον πίνακα largebin για να έχετε πρόσβαση σε ένα κατάλληλο bin σύμφωνα με το μέγεθος του αιτήματος.
2. Δείτε αν το `av` έχει fastchunks ή όχι. Αυτό γίνεται ελέγχοντας το `FASTCHUNKS_BIT` στα `av->flags`. Αν ναι, καλέστε το `malloc_consolidate` στο `av`.
5. Αν δεν έχει επιστραφεί ακόμα δείκτης, αυτό υποδηλώνει ένα ή περισσότερα από τα ακόλουθα περιστατικά:
1. Το μέγεθος ανήκει στο εύρος 'fastbin' αλλά δεν υπάρχει fastchunk διαθέσιμο.
2. Το μέγεθος ανήκει στο εύρος 'smallbin' αλλά δεν υπάρχει smallchunk διαθέσιμο (καλεί το `malloc_consolidate` κατά την αρχικοποίηση).
3. Το μέγεθος ανήκει στο εύρος 'largebin'.
6. Στη συνέχεια, ελέγχονται **αταξινόμητα κομμάτια** και τα κομμάτια που διατρέχονται τοποθετούνται σε bins. Αυτό είναι το μόνο σημείο όπου τα κομμάτια τοποθετούνται σε bins. Διατρέξτε τον αταξινόμητο bin από το 'TAIL'.
1. Το `victim` δείχνει στο τρέχον κομμάτι που εξετάζεται.
2. Ελέγξτε αν το μέγεθος του κομματιού `victim` βρίσκεται εντός του ελάχιστου (`2*SIZE_SZ`) και μέγιστου (`av->system_mem`) εύρους. Διαφορετικά εκτοξεύεται ένα σφάλμα (`malloc(): διαφθορά μνήμης`).
3. Αν (το μέγεθος του αιτούμενου κομματιού ανήκει στο εύρος του smallbin) και (`victim` είναι το τελευταίο κομμάτι υπολοίπου) και (είναι το μοναδικό κομμάτι στον αταξινόμητο bin) και (το μέγεθος των κομματιών >= αυτού που ζητήθηκε): **Διαίρεσε το κομμάτι σε 2 κομμάτια**:
* Το πρώτο κομμάτι ταιριάζει με το ζητούμενο μέγεθος και επιστρέφεται.
* Το υπόλοιπο κομμάτι γίνεται το νέο τελευταίο κομμάτι υπολοίπου. Εισάγεται πίσω στον αταξινόμητο bin.
1. Ορίστε τα πεδία `chunk_size` και `chunk_prev_size` κατάλληλα για τα δύο κομμάτια.
2. Το πρώτο κομμάτι επιστρέφεται μετά την κλήση του `alloc_perturb`.
3. Αν η παραπάνω συνθήκη είναι ψευδής, η έλεγχος φτάνει εδώ. Αφαιρέστε το `victim` από τον αταξινόμητο bin. Αν το μέγεθος του `victim` ταιριάζει ακριβώς με το ζητούμενο μέγεθος, επιστρέψτε αυτό το κομμάτι μετά την κλήση του `alloc_perturb`.
4. Αν το μέγεθος του `victim` ανήκει στο εύρος του smallbin, προσθέστε το κομμάτι στον κατάλληλο smallbin στο `HEAD`.
5. Διαφορετικά εισάγετε στον κατάλληλο largebin διατηρώντας την ταξινομημένη σειρά:
6. Ελέγξτε πρώτα το τελευταίο κομμάτι (το μικρότερο). Αν το `victim` είναι μικρότερο από το τελευταίο κομμάτι, εισάγετέ το στο τέλος.
7. Διαφορετικά, επαναλάβετε για να βρείτε ένα κομμάτι με μέγεθος >= του `victim`. Αν το μέγεθος είναι ακριβώς το ίδιο, εισάγετε πάντα στη δεύτερη θέση.
8. Επαναλάβετε αυτό το βήμα μέγιστο `MAX_ITERS` (10000) φορές ή μέχρι να εξαντληθούν όλα τα κομμάτια στον αταξινόμητο bin.
7. Μετά τον έλεγχο των αταξινόμητων κομματιών, ελέγξτε αν το ζητούμενο μέγεθος δεν ανήκει στο εύρος του smallbin, αν ναι τότε ελέγξτε τα **largebins**.
1. Πάρτε δείκτη στον πίνακα largebin για να έχετε πρόσβαση σε ένα κατάλληλο
## Ελεύθερη Ροή
{% hint style="success" %}
(Η τρέχουσα εξήγηση προέρχεται από [https://heap-exploitation.dhavalkapil.com/diving\_into\_glibc\_heap/core\_functions](https://heap-exploitation.dhavalkapil.com/diving\_into\_glibc\_heap/core\_functions). TODO: Ελέγξτε την τελευταία έκδοση και ενημερώστε την)
{% endhint %}
Η τελική συνάρτηση που ελευθερώνει κομμάτια μνήμης είναι η `_int_free (mstate av, mchunkptr p, int have_lock)`:
1. Ελέγξτε εάν το `p` βρίσκεται πριν από το `p + chunksize(p)` στη μνήμη (για να αποφευχθεί η τυλιγμένη μνήμη). Διαφορετικά εκτοξεύεται ένα σφάλμα (`free(): μη έγκυρος δείκτης`).
2. Ελέγξτε εάν το μέγεθος του κομματιού είναι τουλάχιστον `MINSIZE` ή πολλαπλάσιο του `MALLOC_ALIGNMENT`. Διαφορετικά εκτοξεύεται ένα σφάλμα (`free(): μη έγκυρο μέγεθος`).
3. Εάν το μέγεθος του κομματιού ανήκει στη λίστα fastbin:
1. Ελέγξτε εάν το μέγεθος του επόμενου κομματιού βρίσκεται μεταξύ ελάχιστου και μέγιστου μεγέθους (`av->system_mem`), διαφορετικά εκτοξεύεται ένα σφάλμα (`free(): μη έγκυρο μέγεθος επόμενου (fast)`) αλλιώς.
2. Καλεί το `free_perturb` στο κομμάτι.
3. Ορίζει το `FASTCHUNKS_BIT` για το `av`.
4. Παίρνει δείκτη στον πίνακα fastbin ανάλογα με το μέγεθος του κομματιού.
5. Ελέγχει εάν η κορυφή του κάδου δεν είναι το κομμάτι που πρόκειται να προστεθεί. Διαφορετικά, εκτοξεύεται ένα σφάλμα (`διπλή ελευθέρωση ή διαφθορά (fasttop)`).
6. Ελέγχει εάν το μέγεθος του κομματιού fastbin στην κορυφή είναι το ίδιο με το κομμάτι που προσθέτουμε. Διαφορετικά, εκτοξεύεται ένα σφάλμα (`μη έγκυρη είσοδος fastbin (ελεύθερη)`).
7. Εισάγει το κομμάτι στην κορυφή της λίστας fastbin και επιστρέφει.
4. Εάν το κομμάτι δεν είναι mmapped:
1. Ελέγξτε εάν το κομμάτι είναι το κορυφαίο κομμάτι ή όχι. Εάν ναι, εκτοξεύεται ένα σφάλμα (`διπλή ελευθέρωση ή διαφθορά (κορυφή) `).
2. Ελέγξτε εάν το επόμενο κομμάτι (με βάση τη μνήμη) βρίσκεται εντός των ορίων της αρένας. Αν όχι, εκτοξεύεται ένα σφάλμα (`διπλή ελευθέρωση ή διαφθορά (έξω) `).
3. Ελέγξτε εάν το προηγούμενο bit χρήσης του επόμενου κομματιού (με βάση τη μνήμη) είναι σημασμένο ή όχι. Αν όχι, εκτοξεύεται ένα σφάλμα (`διπλή ελευθέρωση ή διαφθορά (!prev) `).
4. Ελέγξτε εάν το μέγεθος του επόμενου κομματιού βρίσκεται μεταξύ του ελάχιστου και μέγιστου μεγέθους (`av->system_mem`). Αν όχι, εκτοξεύεται ένα σφάλμα (`free(): μη έγκυρο μέγεθος επόμενου (κανονικό) `).
5. Καλεί το `free_perturb` στο κομμάτι.
6. Εάν το προηγούμενο κομμάτι (με βάση τη μνήμη) δεν είναι σε χρήση, καλέστε το `unlink` στο προηγούμενο κομμάτι.
7. Εάν το επόμενο κομμάτι (με βάση τη μνήμη) δεν είναι κορυφαίο κομμάτι:
1. Αν το επόμενο κομμάτι δεν είναι σε χρήση, καλέστε το `unlink` στο επόμενο κομμάτι.
2. Συγχωνεύστε το κομμάτι με το προηγούμενο, το επόμενο (με βάση τη μνήμη), αν υπάρχει ελεύθερο, και προσθέστε το στην αρχή του unsorted bin. Πριν την εισαγωγή, ελέγξτε εάν `unsorted_chunks(av)->fd->bk == unsorted_chunks(av)` ή όχι. Αν όχι, εκτοξεύεται ένα σφάλμα ("free(): διαφθορά στα unsorted chunks").
8. Εάν το επόμενο κομμάτι (με βάση τη μνήμη) ήταν κορυφαίο κομμάτι, συγχωνεύστε τα κομμάτια κατάλληλα σε ένα μοναδικό κορυφαίο κομμάτι.
5. Αν το κομμάτι ήταν mmapped, καλέστε το `munmap_chunk`.
## Έλεγχοι Ασφαλείας Συναρτήσεων Κάδου
Ελέγξτε τους έλεγχους ασφαλείας που πραγματοποιούνται από συχνά χρησιμοποιούμενες συναρτήσεις στον κάδο σε:
{% content-ref url="heap-functions-security-checks.md" %}
[heap-functions-security-checks.md](heap-functions-security-checks.md)
{% endcontent-ref %}
## Αναφορές
* [https://azeria-labs.com/heap-exploitation-part-1-understanding-the-glibc-heap-implementation/](https://azeria-labs.com/heap-exploitation-part-1-understanding-the-glibc-heap-implementation/)
* [https://azeria-labs.com/heap-exploitation-part-2-glibc-heap-free-bins/](https://azeria-labs.com/heap-exploitation-part-2-glibc-heap-free-bins/)
* [https://heap-exploitation.dhavalkapil.com/diving\_into\_glibc\_heap/core\_functions](https://heap-exploitation.dhavalkapil.com/diving\_into\_glibc\_heap/core\_functions)

View file

@ -0,0 +1,124 @@
# Διπλός Ελεύθερος
<details>
<summary><strong>Μάθετε το χάκινγκ στο AWS από το μηδέν μέχρι τον ήρωα με το</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (Ειδικός Ερυθρός Συνεργάτης AWS του HackTricks)</strong></a><strong>!</strong></summary>
Άλλοι τρόποι υποστήριξης του HackTricks:
* Αν θέλετε να δείτε την **εταιρεία σας διαφημισμένη στο HackTricks** ή να **κατεβάσετε το HackTricks σε μορφή PDF** ελέγξτε τα [**ΣΧΕΔΙΑ ΣΥΝΔΡΟΜΗΣ**](https://github.com/sponsors/carlospolop)!
* Αποκτήστε το [**επίσημο PEASS & HackTricks swag**](https://peass.creator-spring.com)
* Ανακαλύψτε την [**Οικογένεια PEASS**](https://opensea.io/collection/the-peass-family), τη συλλογή μας από αποκλειστικά [**NFTs**](https://opensea.io/collection/the-peass-family)
* **Εγγραφείτε στη** 💬 [**ομάδα Discord**](https://discord.gg/hRep4RUj7f) ή στη [**ομάδα τηλεγραφής**](https://t.me/peass) ή **ακολουθήστε** μας στο **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Μοιραστείτε τα χάκινγκ κόλπα σας υποβάλλοντας PRs στα** [**HackTricks**](https://github.com/carlospolop/hacktricks) και [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) αποθετήρια του github.
</details>
## Βασικές Πληροφορίες
Αν ελευθερώσετε ένα τμήμα μνήμης περισσότερες από μία φορές, μπορεί να δημιουργήσετε προβλήματα στα δεδομένα του διαχειριστή μνήμης και να ανοίξετε την πόρτα σε επιθέσεις. Εδώ είναι πώς συμβαίνει: όταν ελευθερώνετε ένα τμήμα μνήμης, επιστρέφει σε μια λίστα ελεύθερων τμημάτων (π.χ. το "fastbin"). Αν ελευθερώσετε το ίδιο τμήμα δύο φορές συνεχόμενα, ο διαχειριστής ανιχνεύει αυτό και εκτοξεύει ένα σφάλμα. Αλλά αν **ελευθερώσετε ένα άλλο τμήμα μεταξύ τους, ο έλεγχος διπλής ελευθέρωσης παρακάμπτεται**, προκαλώντας διαφθορά.
Τώρα, όταν ζητάτε νέα μνήμη (χρησιμοποιώντας `malloc`), ο διαχειριστής μπορεί να σας δώσει ένα **τμήμα που έχει ελευθερωθεί δύο φορές**. Αυτό μπορεί να οδηγήσει σε δύο διαφορετικούς δείκτες που δείχνουν στην ίδια τοποθεσία μνήμης. Αν ένας επιτιθέμενος ελέγχει έναν από αυτούς τους δείκτες, μπορεί να αλλάξει το περιεχόμενο αυτής της μνήμης, το οποίο μπορεί να προκαλέσει θέματα ασφαλείας ή ακόμα και να τους επιτρέψει να εκτελέσουν κώδικα.
Παράδειγμα:
```c
#include <stdio.h>
#include <stdlib.h>
int main() {
// Allocate memory for three chunks
char *a = (char *)malloc(10);
char *b = (char *)malloc(10);
char *c = (char *)malloc(10);
char *d = (char *)malloc(10);
char *e = (char *)malloc(10);
char *f = (char *)malloc(10);
char *g = (char *)malloc(10);
char *h = (char *)malloc(10);
char *i = (char *)malloc(10);
// Print initial memory addresses
printf("Initial allocations:\n");
printf("a: %p\n", (void *)a);
printf("b: %p\n", (void *)b);
printf("c: %p\n", (void *)c);
printf("d: %p\n", (void *)d);
printf("e: %p\n", (void *)e);
printf("f: %p\n", (void *)f);
printf("g: %p\n", (void *)g);
printf("h: %p\n", (void *)h);
printf("i: %p\n", (void *)i);
// Fill tcache
free(a);
free(b);
free(c);
free(d);
free(e);
free(f);
free(g);
// Introduce double-free vulnerability in fast bin
free(h);
free(i);
free(h);
// Reallocate memory and print the addresses
char *a1 = (char *)malloc(10);
char *b1 = (char *)malloc(10);
char *c1 = (char *)malloc(10);
char *d1 = (char *)malloc(10);
char *e1 = (char *)malloc(10);
char *f1 = (char *)malloc(10);
char *g1 = (char *)malloc(10);
char *h1 = (char *)malloc(10);
char *i1 = (char *)malloc(10);
char *i2 = (char *)malloc(10);
// Print initial memory addresses
printf("After reallocations:\n");
printf("a1: %p\n", (void *)a1);
printf("b1: %p\n", (void *)b1);
printf("c1: %p\n", (void *)c1);
printf("d1: %p\n", (void *)d1);
printf("e1: %p\n", (void *)e1);
printf("f1: %p\n", (void *)f1);
printf("g1: %p\n", (void *)g1);
printf("h1: %p\n", (void *)h1);
printf("i1: %p\n", (void *)i1);
printf("i2: %p\n", (void *)i1);
return 0;
}
```
Σε αυτό το παράδειγμα, μετά τον γέμισμα του tcache με αρκετά ελεύθερα τμήματα, ο κώδικας **ελευθερώνει το τμήμα `h`, στη συνέχεια το τμήμα `i`, και μετά ξανά το `h`, προκαλώντας ένα σφάλμα διπλής απελευθέρωσης**. Αυτό ανοίγει τη δυνατότητα λήψης επικαλυπτόμενων διευθύνσεων μνήμης κατά την επαναδιάταξη, που σημαίνει ότι δύο ή περισσότεροι δείκτες μπορεί να δείχνουν στην ίδια τοποθεσία μνήμης. Η διαμόρφωση δεδομένων μέσω ενός δείκτη μπορεί να επηρεάσει τον άλλο, δημιουργώντας ένα κρίσιμο κίνδυνο ασφάλειας και δυνατότητα εκμετάλλευσης.
Εκτελώντας το, παρατηρήστε πώς **`i1` και `i2` πήραν την ίδια διεύθυνση**:
<pre><code>Αρχικές εκχωρήσεις:
a: 0xaaab0f0c22a0
b: 0xaaab0f0c22c0
c: 0xaaab0f0c22e0
d: 0xaaab0f0c2300
e: 0xaaab0f0c2320
f: 0xaaab0f0c2340
g: 0xaaab0f0c2360
h: 0xaaab0f0c2380
i: 0xaaab0f0c23a0
Μετά τις επαναδιατάξεις:
a1: 0xaaab0f0c2360
b1: 0xaaab0f0c2340
c1: 0xaaab0f0c2320
d1: 0xaaab0f0c2300
e1: 0xaaab0f0c22e0
f1: 0xaaab0f0c22c0
g1: 0xaaab0f0c22a0
h1: 0xaaab0f0c2380
<strong>i1: 0xaaab0f0c23a0
</strong><strong>i2: 0xaaab0f0c23a0
</strong></code></pre>
## Αναφορές
* [https://heap-exploitation.dhavalkapil.com/attacks/double\_free](https://heap-exploitation.dhavalkapil.com/attacks/double\_free)

View file

@ -0,0 +1,92 @@
# Έλεγχοι Ασφαλείας Συναρτήσεων Σωρού
<details>
<summary><strong>Μάθετε το χάκινγκ στο AWS από το μηδέν μέχρι τον ήρωα με το</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (Ειδικός Ερυθρού Συνεργείου AWS του HackTricks)</strong></a><strong>!</strong></summary>
Άλλοι τρόποι υποστήριξης του HackTricks:
* Αν θέλετε να δείτε την **εταιρεία σας διαφημισμένη στο HackTricks** ή να **κατεβάσετε το HackTricks σε μορφή PDF** ελέγξτε τα [**ΣΧΕΔΙΑ ΣΥΝΔΡΟΜΗΣ**](https://github.com/sponsors/carlospolop)!
* Αποκτήστε το [**επίσημο PEASS & HackTricks swag**](https://peass.creator-spring.com)
* Ανακαλύψτε [**την Οικογένεια PEASS**](https://opensea.io/collection/the-peass-family), τη συλλογή μας από αποκλειστικά [**NFTs**](https://opensea.io/collection/the-peass-family)
* **Εγγραφείτε** στην 💬 [**ομάδα Discord**](https://discord.gg/hRep4RUj7f) ή στην [**ομάδα τηλεγραφήματος**](https://t.me/peass) ή **ακολουθήστε** μας στο **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Μοιραστείτε τα χάκινγκ κόλπα σας υποβάλλοντας PRs** στα [**HackTricks**](https://github.com/carlospolop/hacktricks) και [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) αποθετήρια του github.
</details>
## unlink
Αυτή η συνάρτηση αφαιρεί ένα κομμάτι από μια διπλά συνδεδεμένη λίστα. Οι κοινοί έλεγχοι εξασφαλίζουν ότι η δομή της συνδεδεμένης λίστας παραμένει συνεκτική κατά την αποσύνδεση των κομματιών.
* **Έλεγχοι Συνέπειας**:
* Έλεγχος εάν `P->fd->bk == P` και `P->bk->fd == P`.
* Μήνυμα σφάλματος: `corrupted double-linked list`
## \_int\_malloc
Αυτή η συνάρτηση είναι υπεύθυνη για την εκχώρηση μνήμης από το σωρό. Οι έλεγχοι εδώ εξασφαλίζουν ότι η μνήμη δεν παραμορφώνεται κατά την εκχώρηση.
* **Έλεγχος Μεγέθους Fastbin**:
* Όταν αφαιρείτε ένα κομμάτι από ένα fastbin, βεβαιωθείτε ότι το μέγεθος του κομματιού βρίσκεται εντός του εύρους του fastbin.
* Μήνυμα σφάλματος: `malloc(): memory corruption (fast)`
* **Έλεγχος Συνέπειας Smallbin**:
* Όταν αφαιρείτε ένα κομμάτι από ένα smallbin, βεβαιωθείτε ότι οι προηγούμενοι και επόμενοι σύνδεσμοι στη διπλά συνδεδεμένη λίστα είναι συνεκτικοί.
* Μήνυμα σφάλματος: `malloc(): smallbin double linked list corrupted`
* **Έλεγχος Εύρους Μνήμης Unsorted Bin**:
* Βεβαιωθείτε ότι το μέγεθος των κομματιών στο unsorted bin βρίσκεται εντός των ελάχιστων και μέγιστων ορίων.
* Μήνυμα σφάλματος: `malloc(): memory corruption`
* **Έλεγχος Συνέπειας Unsorted Bin (Πρώτο Σενάριο)**:
* Όταν εισάγετε ένα κομμάτι υπολειμματικής μνήμης στο unsorted bin, ελέγξτε εάν `unsorted_chunks(av)->fd->bk == unsorted_chunks(av)`.
* Μήνυμα σφάλματος: `malloc(): corrupted unsorted chunks`
* **Έλεγχος Συνέπειας Unsorted Bin (Δεύτερο Σενάριο)**:
* Ίδιο με τον προηγούμενο έλεγχο, αλλά ενεργοποιείται όταν εισάγετε μετά από διαίρεση ενός γρήγορου ή μικρού κομματιού.
* Μήνυμα σφάλματος: `malloc(): corrupted unsorted chunks 2`
## \_int\_free
Αυτή η συνάρτηση απελευθερώνει προηγουμένως εκχωρημένη μνήμη. Οι έλεγχοι εδώ βοηθούν να εξασφαλιστεί η σωστή αποδέσμευση μνήμης και να αποτραπεί η παραμόρφωση μνήμης.
* **Έλεγχος Ορίων Δείκτη**:
* Βεβαιωθείτε ότι ο δείκτης που απελευθερώνεται δεν είναι τυλιγμένος γύρω από τη μνήμη.
* Μήνυμα σφάλματος: `free(): invalid pointer`
* **Έλεγχος Μεγέθους**:
* Βεβαιωθείτε ότι το μέγεθος του κομματιού που απελευθερώνεται είναι τουλάχιστον `MINSIZE` ή πολλαπλάσιο του `MALLOC_ALIGNMENT`.
* Μήνυμα σφάλματος: `free(): invalid size`
* **Έλεγχος Μεγέθους Fastbin**:
* Για κομμάτια fastbin, βεβαιωθείτε ότι το μέγεθος του επόμενου κομματιού βρίσκεται εντός των ελάχιστων και μέγιστων ορίων.
* Μήνυμα σφάλματος: `free(): invalid next size (fast)`
* **Έλεγχος Διπλής Απελευθέρωσης Fastbin**:
* Όταν εισάγετε ένα κομμάτι σε ένα fastbin, βεβαιωθείτε ότι το κομμάτι στην κορυφή δεν είναι το ίδιο με αυτό που εισάγετε.
* Μήνυμα σφάλματος: `double free or corruption (fasttop)`
* **Έλεγχος Συνέπειας Fastbin**:
* Όταν εισάγετε σε ένα fastbin, βεβαιωθείτε ότι τα μεγέθη του κομματιού στην κορυφή και του κομματιού που εισάγετε είναι τα ίδια.
* Μήνυμα σφάλματος: `invalid fastbin entry (free)`
* **Έλεγχος Συνέπειας Κορυφής Κομματιού**:
* Για κομμάτια που δεν είναι fastbin, βεβαιωθείτε ότι το κομμάτι δεν είναι το ίδιο με το κομμάτι κορυφής.
* Μήνυμα σφάλματος: `double free or corruption (top)`
* **Έλεγχοι Ορίων Μνήμης**:
* Βεβαιωθείτε ότι το επόμενο κομμάτι μνήμης βρίσκεται εντός των ορίων της αρένας.
* Μήνυμα σφάλματος: `double free or corruption (out)`
* **Έλεγχος Bit Prev\_inuse**:
* Βεβαιωθείτε ότι το bit προηγούμενου σε χρήση κομματιού στο επόμενο κομμάτι είναι επισημασμένο.
* Μήνυμα σφάλματος: `double free or corruption (!prev)`
* **Έλεγχος Κανονικού Μεγέθους**:
* Βεβαιωθείτε ότι το μέγεθος του επόμενου κομματιού βρίσκεται εντός των έγκυρων εύρων.
* Μήνυμα σφάλματος: `free(): invalid next size (normal)`
* **Έλεγχος Συνέπειας Unsorted Bin**:
* Όταν εισάγετε ένα συνενωμένο κομμάτι στο unsorted bin, ελέγξτε εάν `unsorted_chunks(av)->fd->bk == unsorted_chunks(av)`.
* Μήνυμα σφάλματος: `free(): corrupted unsorted chunks`
<details>
<summary><strong>Μάθετε το χάκινγκ στο AWS από το μηδέν μέχρι τον ήρωα με το</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (Ειδικός Ερυθρού Συνεργείου AWS του HackTricks)</strong></a><strong>!</strong></summary>
Άλλοι τρόποι υποστήριξης του HackTricks:
* Αν θέλετε να δείτε την **εταιρεία σας διαφημισμένη στο HackTricks** ή να **κατεβάσετε το HackTricks σε μορφή PDF** ελέγξτε τα [**ΣΧΕΔΙΑ ΣΥΝΔΡΟΜΗΣ**](https://github.com/sponsors/carlospolop)!
* Αποκτήστε το [**επίσημο PEASS & HackTricks swag**](https://peass.creator-spring.com)
* Ανακαλύψτε [**την Οικογένεια PEASS**](https://opensea.io/collection/the-peass-family), τη συλλογή μας από αποκλειστικά [**NFTs**](https://opensea.io/collection/the-peass-family)
* **Εγγραφείτε** στην 💬 [**ομάδα Discord**](https://discord.gg/hRep4RUj7f) ή στην [**ομάδα τηλεγραφήματος**](https://t.me/peass) ή **ακολουθήστε** μας στο **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Μοιραστείτε τα χάκινγκ κόλπα σας υποβάλλοντας PRs** στα [**HackTricks**](https://github.com/carlospolop/hacktricks) και [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) αποθετήρια του github.
</details>

View file

@ -0,0 +1,59 @@
# Υπερχείλιση Σωρού
<details>
<summary><strong>Μάθετε το χάκινγκ στο AWS από το μηδέν μέχρι τον ήρωα με το</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
Άλλοι τρόποι υποστήριξης του HackTricks:
* Αν θέλετε να δείτε την **εταιρεία σας διαφημισμένη στο HackTricks** ή να **κατεβάσετε το HackTricks σε μορφή PDF** ελέγξτε τα [**ΣΧΕΔΙΑ ΣΥΝΔΡΟΜΗΣ**](https://github.com/sponsors/carlospolop)!
* Αποκτήστε το [**επίσημο PEASS & HackTricks swag**](https://peass.creator-spring.com)
* Ανακαλύψτε [**την Οικογένεια PEASS**](https://opensea.io/collection/the-peass-family), τη συλλογή μας από αποκλειστικά [**NFTs**](https://opensea.io/collection/the-peass-family)
* **Εγγραφείτε** στην 💬 [**ομάδα Discord**](https://discord.gg/hRep4RUj7f) ή στην [**ομάδα τηλεγραφήματος**](https://t.me/peass) ή **ακολουθήστε** μας στο **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Μοιραστείτε τα χάκινγκ κόλπα σας υποβάλλοντας PRs** στα [**HackTricks**](https://github.com/carlospolop/hacktricks) και [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) αποθετήρια του github.
</details>
## Βασικές Πληροφορίες
Η υπερχείλιση σωρού είναι σαν μια [**υπερχείλιση στοίβας**](../stack-overflow/) αλλά στο σωρό. Βασικά σημαίνει ότι κάποιος χώρος είχε διατεθεί στο σωρό για να αποθηκεύσει κάποια δεδομένα και **τα αποθηκευμένα δεδομένα ήταν μεγαλύτερα από τον διαθέσιμο χώρο.**
Στις υπερχειλίσεις στοίβας γνωρίζουμε ότι κάποιοι καταχωρητές όπως ο δείκτης εντολών ή το πλαίσιο στοίβας θα αποκατασταθούν από τη στοίβα και θα μπορούσε να είναι δυνατό να εκμεταλλευτεί αυτό κάποιος. Στην περίπτωση των υπερχειλίσεων σωρού, **δεν υπάρχει καμία ευαίσθητη πληροφορία που αποθηκεύεται από προεπιλογή** στο κομμάτι του σωρού που μπορεί να υπερχειλιστεί. Ωστόσο, θα μπορούσε να είναι ευαίσθητες πληροφορίες ή δείκτες, οπότε η **κρισιμότητα** αυτής της ευπάθειας **εξαρτάται** από το **ποια δεδομένα μπορούν να αντικατασταθούν** και πώς μπορεί ένας επιτιθέμενος να εκμεταλλευτεί αυτό.
{% hint style="success" %}
Για να βρείτε τις μετατοπίσεις υπερχείλισης μπορείτε να χρησιμοποιήσετε τα ίδια πρότυπα όπως στις [**υπερχειλίσεις στοίβας**](../stack-overflow/#finding-stack-overflows-offsets).
{% endhint %}
### Υπερχειλίσεις Στοίβας έναντι Υπερχειλίσεων Σωρού
Στις υπερχειλίσεις στοίβας η διάταξη και τα δεδομένα που θα υπάρχουν στη στοίβα τη στιγμή που μπορεί να ενεργοποιηθεί η ευπάθεια είναι αρκετά αξιόπιστα. Αυτό οφείλεται στο γεγονός ότι η στοίβα είναι γραμμική, αυξάνεται πάντα σε συγκρούουσα μνήμη, σε **συγκεκριμένα σημεία της εκτέλεσης του προγράμματος η μνήμη στοίβας αποθηκεύει συνήθως παρόμοιου είδους δεδομένα** και έχει κάποια συγκεκριμένη δομή με ορισμένους δείκτες στο τέλος του τμήματος στοίβας που χρησιμοποιείται από κάθε συνάρτηση.
Ωστόσο, στην περίπτωση μιας υπερχείλισης σωρού, επειδή η χρησιμοποιούμενη μνήμη δεν είναι γραμμική αλλά **οι εκχωρημένοι κομμάτια είναι συνήθως σε ξεχωριστές θέσεις μνήμης** (όχι ένα δίπλα στο άλλο) λόγω **κάδων και ζωνών** που χωρίζουν τις εκχωρήσεις ανά μέγεθος και επειδή **η προηγούμενη ελευθέρωση μνήμης χρησιμοποιείται** πριν από την εκχώρηση νέων κομματιών. Είναι **δύσκολο να γνωρίζουμε το αντικείμενο που θα συγκρουστεί με το ευάλωτο** σε μια υπερχείλιση σωρού. Έτσι, όταν βρεθεί μια υπερχείλιση σωρού, είναι απαραίτητο να βρεθεί ένας **αξιόπιστος τρόπος για να το επιθυμητό αντικείμενο να είναι το επόμενο στη μνήμη** από αυτό που μπορεί να υπερχειλιστεί.
Ένας από τους τεχνικές που χρησιμοποιούνται γι' αυτό είναι η **Διαμόρφωση Σωρού** που χρησιμοποιείται για παράδειγμα [**σε αυτή την ανάρτηση**](https://azeria-labs.com/grooming-the-ios-kernel-heap/). Στην ανάρτηση εξηγείται πώς όταν στο πυρήνα iOS όταν μια ζώνη εξαντλεί τη μνήμη για να αποθηκεύσει κομμάτια μνήμης, την επεκτείνει με μια σελίδα πυρήνα, και αυτή η σελίδα χωρίζεται σε κομμάτια των αναμενόμενων μεγεθών που θα χρησιμοποιηθούν με τη σειρά (μέχρι την έκδοση iOS 9.2, τότε αυτά τα κομμάτια χρησιμοποιούνται με τυχαίο τρόπο για να δυσκολέψει η εκμετάλλευση αυτών των επιθέσεων).
Συνεπώς, στην προηγούμενη ανάρτηση όπου συμβαίνει μια υπερχείλιση σωρού, για να αναγκαστεί το υπερχειλισμένο αντικείμενο να συγκρουστεί με ένα αντικείμενο θύμα, αρκετά **`kallocs` είναι αναγκασμένα από αρκετά νήματα για να εξασφαλίσουν ότι όλα τα ελεύθερα κομμάτια είναι γεμάτα και ότι δημιουργείται μια νέα σελίδα**.
Για να αναγκαστεί αυτή η γέμιση με αντικείμενα συγκεκριμένου μεγέθους, η **εκχωρηση εκτός γραμμής που σχετίζεται με ένα iOS mach port** είναι ένας ιδανικός υποψήφιος. Διαμορφώνοντας το μέγεθος του μηνύματος, είναι δυνατό να καθοριστεί ακριβώς το μέγεθος της εκχώρησης `kalloc` και όταν το αντίστοιχο mach port καταστραφεί, η αντίστοιχη εκχώρηση θα απελευθερωθεί αμέσως πίσω στο `kfree`.
Στη συνέχεια, μερικά από αυτά τα αντικείμενα μπορούν να **απελευθερωθούν**. Η λίστα ελεύθερωσης **`kalloc.4096` απελευθερώνει στοιχεία με τη σειρά τελευταίο που μπαίνει πρώτο**, που βασικά σημαίνει ότι αν κάποια σημεία απελευθερωθούν και η εκμετάλλευση προσπαθήσει να εκχωρήσει αρκετά αντικείμενα θύματα ενώ προσπαθεί να εκχωρήσει το ευάλωτο αντικείμενο υπερχείλισης, είναι πιθανό ότι αυτό το αντικείμενο θα ακολουθηθεί από ένα αντικείμενο θύμα.
## Παράδειγμα ARM64
Στη
```bash
python3 -c 'print("/"*0x400+"/bin/ls\x00")' > hax.txt
```
<details>
<summary><strong>Μάθετε το χάκινγκ στο AWS από το μηδέν μέχρι τον ήρωα με το</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
Άλλοι τρόποι υποστήριξης του HackTricks:
* Αν θέλετε να δείτε την **εταιρεία σας να διαφημίζεται στο HackTricks** ή να **κατεβάσετε το HackTricks σε μορφή PDF** ελέγξτε τα [**ΣΧΕΔΙΑ ΣΥΝΔΡΟΜΗΣ**](https://github.com/sponsors/carlospolop)!
* Αποκτήστε το [**επίσημο PEASS & HackTricks swag**](https://peass.creator-spring.com)
* Ανακαλύψτε την [**Οικογένεια PEASS**](https://opensea.io/collection/the-peass-family), τη συλλογή μας από αποκλειστικά [**NFTs**](https://opensea.io/collection/the-peass-family)
* **Εγγραφείτε στη** 💬 [**ομάδα Discord**](https://discord.gg/hRep4RUj7f) ή στην [**ομάδα telegram**](https://t.me/peass) ή **ακολουθήστε** μας στο **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Μοιραστείτε τα χάκινγκ κόλπα σας υποβάλλοντας PRs στα** [**HackTricks**](https://github.com/carlospolop/hacktricks) και [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) αποθετήρια στο GitHub.
</details>

View file

@ -0,0 +1,25 @@
# Χρήση Μετά το Δωρεάν
<details>
<summary><strong>Μάθετε το χάκινγκ στο AWS από το μηδέν μέχρι τον ήρωα με το</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
Άλλοι τρόποι υποστήριξης του HackTricks:
* Αν θέλετε να δείτε την **εταιρεία σας διαφημισμένη στο HackTricks** ή να **κατεβάσετε το HackTricks σε PDF** ελέγξτε τα [**ΣΧΕΔΙΑ ΣΥΝΔΡΟΜΗΣ**](https://github.com/sponsors/carlospolop)!
* Αποκτήστε το [**επίσημο PEASS & HackTricks swag**](https://peass.creator-spring.com)
* Ανακαλύψτε [**την Οικογένεια PEASS**](https://opensea.io/collection/the-peass-family), τη συλλογή μας από αποκλειστικά [**NFTs**](https://opensea.io/collection/the-peass-family)
* **Εγγραφείτε** στην 💬 [**ομάδα Discord**](https://discord.gg/hRep4RUj7f) ή στην [**ομάδα τηλεγραφήματος**](https://t.me/peass) ή **ακολουθήστε** μας στο **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Μοιραστείτε τα χάκινγκ κόλπα σας υποβάλλοντας PRs** στα [**HackTricks**](https://github.com/carlospolop/hacktricks) και [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) αποθετήρια του GitHub.
</details>
## Βασικές Πληροφορίες
Όπως υποδηλώνει το όνομά του, αυτή η ευπάθεια συμβαίνει όταν ένα πρόγραμμα **αποθηκεύει κάποιο χώρο** στη στοίβα για ένα αντικείμενο, **γράφει** κάποιες πληροφορίες εκεί, **το απελευθερώνει** εμφανώς επειδή δεν χρειάζεται πλέον και στη συνέχεια **έχει πρόσβαση ξανά**.
Το πρόβλημα εδώ είναι ότι δεν είναι παράνομο (δεν **θα υπάρχουν σφάλματα**) όταν ένα **απελευθερωμένο μνήμης προσπελαύνεται**. Έτσι, αν το πρόγραμμα (ή ο επιτιθέμενος) κατάφερε να **εκχωρήσει την απελευθερωμένη μνήμη και να αποθηκεύσει αυθαίρετα δεδομένα**, όταν η απελευθερωμένη μνήμη προσπελαύνεται από τον αρχικό δείκτη εκείνα τα δεδομένα θα έχουν αντικατασταθεί προκαλώντας μια **ευπάθεια που θα εξαρτάται από την ευαισθησία των δεδομένων** που αποθηκεύτηκαν αρχικά (αν ήταν ένας δείκτης μιας συνάρτησης που θα κληθεί, ένας επιτιθέμενος θα μπορούσε να τον ελέγξει).
### Επίθεση First Fit
Μια επίθεση First Fit στοχεύει στον τρόπο με τον οποίο ορισμένοι διαχειριστές μνήμης, όπως στο glibc, διαχειρίζονται την απελευθερωμένη μνήμη. Όταν απελευθερώνετε ένα τμήμα μνήμης, προστίθεται σε μια λίστα και οι νέες αιτήσεις μνήμης τραβούν από αυτήν τη λίστα από το τέλος. Οι επιτιθέμενοι μπορούν να χρησιμοποιήσουν αυτήν τη συμπεριφορά για να χειρίζονται **ποια τμήματα μνήμης επαναχρησιμοποιούνται, ενδεχομένως κερδίζοντας έλεγχο επί αυτών**. Αυτό μπορεί να οδηγήσει σε προβλήματα "χρήσης μετά την απελευθέρωση", όπου ένας επιτιθέμενος θα μπορούσε **να αλλάξει το περιεχόμενο της μνήμης που επαναχρησιμοποιείται**, δημιουργώντας έναν κίνδυνο ασφάλειας.

View file

@ -0,0 +1,64 @@
# First Fit
<details>
<summary><strong>Μάθετε το χάκινγκ στο AWS από το μηδέν μέχρι τον ήρωα με το</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (Ειδικός Ερυθράς Ομάδας AWS του HackTricks)</strong></a><strong>!</strong></summary>
Άλλοι τρόποι υποστήριξης του HackTricks:
* Αν θέλετε να δείτε την **εταιρεία σας διαφημισμένη στο HackTricks** ή να **κατεβάσετε το HackTricks σε μορφή PDF** ελέγξτε τα [**ΣΧΕΔΙΑ ΣΥΝΔΡΟΜΗΣ**](https://github.com/sponsors/carlospolop)!
* Αποκτήστε το [**επίσημο PEASS & HackTricks swag**](https://peass.creator-spring.com)
* Ανακαλύψτε [**την Οικογένεια PEASS**](https://opensea.io/collection/the-peass-family), τη συλλογή μας από αποκλειστικά [**NFTs**](https://opensea.io/collection/the-peass-family)
* **Εγγραφείτε στη** 💬 [**ομάδα Discord**](https://discord.gg/hRep4RUj7f) ή στη [**ομάδα τηλεγραφήματος**](https://t.me/peass) ή **ακολουθήστε** μας στο **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Μοιραστείτε τα χάκινγκ κόλπα σας υποβάλλοντας PRs στα** [**HackTricks**](https://github.com/carlospolop/hacktricks) και [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) αποθετήρια του github.
</details>
## **First Fit**
Όταν απελευθερώνετε μνήμη σε ένα πρόγραμμα που χρησιμοποιεί το glibc, χρησιμοποιούνται διαφορετικά "bins" για τη διαχείριση των τμημάτων μνήμης. Εδώ υπάρχει μια απλουστευμένη εξήγηση δύο συνηθισμένων σεναρίων: μη ταξινομημένα bins και fastbins.
### Μη Ταξινομημένα Bins
Όταν απελευθερώνετε ένα τμήμα μνήμης που δεν είναι γρήγορο τμήμα, πηγαίνει στο μη ταξινομημένο bin. Αυτό το bin λειτουργεί σαν μια λίστα όπου τα νέα απελευθερωμένα τμήματα προστίθενται στην αρχή (το "κεφάλι"). Όταν ζητάτε ένα νέο τμήμα μνήμης, ο διαχειριστής κοιτά στο μη ταξινομημένο bin από το πίσω μέρος (τη "ουρά") για να βρει ένα τμήμα που είναι αρκετά μεγάλο. Αν ένα τμήμα από το μη ταξινομημένο bin είναι μεγαλύτερο από αυτό που χρειάζεστε, τότε γίνεται διαίρεση, με το μέρος μπροστά να επιστρέφεται και το υπόλοιπο να παραμένει στο bin.
Παράδειγμα:
* Δεσμεύετε 300 bytes (`a`), στη συνέχεια 250 bytes (`b`), απελευθερώνετε το `a` και ζητάτε ξανά 250 bytes (`c`).
* Όταν απελευθερώνετε το `a`, πηγαίνει στο μη ταξινομημένο bin.
* Αν στη συνέχεια ζητήσετε ξανά 250 bytes, ο διαχειριστής βρίσκει το `a` στην ουρά και το διαιρεί, επιστρέφοντας το μέρος που ταιριάζει με το αίτημά σας και κρατώντας το υπόλοιπο στο bin.
* Το `c` θα δείχνει στο προηγούμενο `a` και θα είναι γεμάτο με τα δεδομένα του `a`.
```c
char *a = malloc(300);
char *b = malloc(250);
free(a);
char *c = malloc(250);
```
### Fastbins
Τα Fastbins χρησιμοποιούνται για μικρά κομμάτια μνήμης. Αντίθετα με τα unsorted bins, τα fastbins προσθέτουν νέα κομμάτια στην αρχή, δημιουργώντας ένα συμπεριφορά last-in-first-out (LIFO). Αν ζητήσετε ένα μικρό κομμάτι μνήμης, ο allocator θα το πάρει από την αρχή του fastbin.
Παράδειγμα:
* Δεσμεύετε τέσσερα κομμάτια μνήμης των 20 bytes το καθένα (`a`, `b`, `c`, `d`).
* Όταν τα απελευθερώσετε με οποιαδήποτε σειρά, τα απελευθερωμένα κομμάτια προστίθενται στην αρχή του fastbin.
* Αν στη συνέχεια ζητήσετε ένα κομμάτι 20 bytes, ο allocator θα επιστρέψει το πιο πρόσφατα απελευθερωμένο κομμάτι από την αρχή του fastbin.
```c
char *a = malloc(20);
char *b = malloc(20);
char *c = malloc(20);
char *d = malloc(20);
free(a);
free(b);
free(c);
free(d);
a = malloc(20); // d
b = malloc(20); // c
c = malloc(20); // b
d = malloc(20); // a
```
## Άλλες Αναφορές & Παραδείγματα
* [https://heap-exploitation.dhavalkapil.com/attacks/first\_fit](https://heap-exploitation.dhavalkapil.com/attacks/first\_fit)
* [https://8ksec.io/arm64-reversing-and-exploitation-part-2-use-after-free/](https://8ksec.io/arm64-reversing-and-exploitation-part-2-use-after-free/)
* ARM64. Use after free: Δημιουργήστε ένα αντικείμενο χρήστη, απελευθερώστε το, δημιουργήστε ένα αντικείμενο που λαμβάνει το απελευθερωμένο κομμάτι και επιτρέπει την εγγραφή σε αυτό, **αντικαθιστώντας τη θέση του user->password** από το προηγούμενο. Χρησιμοποιήστε ξανά τον χρήστη για **παράκαμψη του ελέγχου του κωδικού πρόσβασης**