Διπλή Απελευθέρωση
Reading time: 5 minutes
tip
Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Μάθετε & εξασκηθείτε στο Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Υποστηρίξτε το HackTricks
- Ελέγξτε τα σχέδια συνδρομής!
- Εγγραφείτε στην 💬 ομάδα Discord ή στην ομάδα telegram ή ακολουθήστε μας στο Twitter 🐦 @hacktricks_live.
- Μοιραστείτε κόλπα hacking υποβάλλοντας PRs στα HackTricks και HackTricks Cloud github repos.
Βασικές Πληροφορίες
Αν απελευθερώσετε ένα μπλοκ μνήμης περισσότερες από μία φορές, μπορεί να διαταραχθούν τα δεδομένα του αλγορίθμου κατανομής και να ανοίξει ο δρόμος για επιθέσεις. Έτσι συμβαίνει: όταν απελευθερώνετε ένα μπλοκ μνήμης, επιστρέφει σε μια λίστα ελεύθερων κομματιών (π.χ. το "fast bin"). Αν απελευθερώσετε το ίδιο μπλοκ δύο φορές στη σειρά, ο αλγόριθμος κατανομής το ανιχνεύει αυτό και ρίχνει ένα σφάλμα. Αλλά αν απελευθερώσετε ένα άλλο κομμάτι ενδιάμεσα, ο έλεγχος διπλής απελευθέρωσης παρακάμπτεται, προκαλώντας διαφθορά.
Τώρα, όταν ζητήσετε νέα μνήμη (χρησιμοποιώντας malloc
), ο αλγόριθμος κατανομής μπορεί να σας δώσει ένα μπλοκ που έχει απελευθερωθεί δύο φορές. Αυτό μπορεί να οδηγήσει σε δύο διαφορετικούς δείκτες να δείχνουν στην ίδια τοποθεσία μνήμης. Αν ένας επιτιθέμενος ελέγχει έναν από αυτούς τους δείκτες, μπορεί να αλλάξει τα περιεχόμενα αυτής της μνήμης, κάτι που μπορεί να προκαλέσει προβλήματα ασφαλείας ή ακόμη και να τους επιτρέψει να εκτελέσουν κώδικα.
Παράδειγμα:
#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 *)i2);
return 0;
}
Σε αυτό το παράδειγμα, μετά την πλήρωση του tcache με αρκετά ελευθερωμένα κομμάτια (7), ο κώδικας απελευθερώνει το κομμάτι h
, στη συνέχεια το κομμάτι i
, και μετά ξανά το h
, προκαλώντας μια διπλή απελευθέρωση (γνωστή και ως Fast Bin dup). Αυτό ανοίγει τη δυνατότητα λήψης επικαλυπτόμενων διευθύνσεων μνήμης κατά την επανακατανομή, πράγμα που σημαίνει ότι δύο ή περισσότερες δείκτες μπορούν να δείχνουν στην ίδια τοποθεσία μνήμης. Η χειραγώγηση δεδομένων μέσω ενός δείκτη μπορεί στη συνέχεια να επηρεάσει τον άλλο, δημιουργώντας έναν κρίσιμο κίνδυνο ασφαλείας και δυνατότητα εκμετάλλευσης.
Εκτελώντας το, σημειώστε πώς i1
και i2
πήραν την ίδια διεύθυνση:
Αρχικές κατανομές:
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
i1: 0xaaab0f0c23a0
i2: 0xaaab0f0c23a0
Παραδείγματα
- Dragon Army. Hack The Box
- Μπορούμε να κατανεμηθούν μόνο κομμάτια μεγέθους Fast-Bin εκτός από το μέγεθος
0x70
, το οποίο αποτρέπει την συνήθη υπερχείλιση του__malloc_hook
. - Αντίθετα, χρησιμοποιούμε διευθύνσεις PIE που ξεκινούν με
0x56
ως στόχο για Fast Bin dup (1/2 πιθανότητα). - Ένα μέρος όπου αποθηκεύονται οι διευθύνσεις PIE είναι στο
main_arena
, το οποίο βρίσκεται μέσα στο Glibc και κοντά στο__malloc_hook
- Στοχεύουμε σε μια συγκεκριμένη μετατόπιση του
main_arena
για να κατανεμηθεί ένα κομμάτι εκεί και συνεχίζουμε να κατανεμηθούμε κομμάτια μέχρι να φτάσουμε στο__malloc_hook
για να αποκτήσουμε εκτέλεση κώδικα. - zero_to_hero. PicoCTF
- Χρησιμοποιώντας Tcache bins και μια υπερχείλιση null-byte, μπορούμε να επιτύχουμε μια κατάσταση διπλής απελευθέρωσης:
- Κατανεμούμε τρία κομμάτια μεγέθους
0x110
(A
,B
,C
) - Απελευθερώνουμε το
B
- Απελευθερώνουμε το
A
και κατανεμούμε ξανά για να χρησιμοποιήσουμε την υπερχείλιση null-byte - Τώρα το πεδίο μεγέθους του
B
είναι0x100
, αντί για0x111
, οπότε μπορούμε να το απελευθερώσουμε ξανά - Έχουμε ένα Tcache-bin μεγέθους
0x110
και ένα μεγέθους0x100
που δείχνουν στην ίδια διεύθυνση. Έτσι έχουμε μια διπλή απελευθέρωση. - Εκμεταλλευόμαστε τη διπλή απελευθέρωση χρησιμοποιώντας Tcache poisoning
Αναφορές
tip
Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Μάθετε & εξασκηθείτε στο Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Υποστηρίξτε το HackTricks
- Ελέγξτε τα σχέδια συνδρομής!
- Εγγραφείτε στην 💬 ομάδα Discord ή στην ομάδα telegram ή ακολουθήστε μας στο Twitter 🐦 @hacktricks_live.
- Μοιραστείτε κόλπα hacking υποβάλλοντας PRs στα HackTricks και HackTricks Cloud github repos.