First Fit

Μάθετε & εξασκηθείτε στο Hacking του AWS:Εκπαίδευση HackTricks AWS Red Team Expert (ARTE) Μάθετε & εξασκηθείτε στο Hacking του GCP: Εκπαίδευση HackTricks GCP Red Team Expert (GRTE)

Υποστηρίξτε το HackTricks

Πρώτη Εφαρμογή

Όταν απελευθερώνετε μνήμη σε ένα πρόγραμμα που χρησιμοποιεί το glibc, διαφορετικά "bins" χρησιμοποιούνται για τη διαχείριση των τμημάτων μνήμης. Εδώ υπάρχει μια απλουστευμένη εξήγηση δύο συνηθισμένων σεναρίων: unsorted bins και fastbins.

Unsorted Bins

Όταν απελευθερώνετε ένα τμήμα μνήμης που δεν είναι γρήγορο τμήμα, πηγαίνει στο unsorted bin. Αυτό το bin λειτουργεί σαν μια λίστα όπου τα νέα απελευθερωμένα τμήματα προστίθενται στην αρχή (το "κεφάλι"). Όταν ζητάτε ένα νέο τμήμα μνήμης, ο διαχειριστής κοιτά στο unsorted bin από το πίσω μέρος (τη "ουρά") για να βρει ένα τμήμα που είναι αρκετά μεγάλο. Αν ένα τμήμα από το unsorted bin είναι μεγαλύτερο από αυτό που χρειάζεστε, τότε γίνεται διαίρεση, με το μέρος που επιστρέφεται να είναι αυτό που ταιριάζει στο αίτημά σας και το υπόλοιπο μέρος να παραμένει στο bin.

Παράδειγμα:

  • Δεσμεύετε 300 bytes (a), στη συνέχεια 250 bytes (b), απελευθερώνετε το a και ζητάτε ξανά 250 bytes (c).

  • Όταν απελευθερώνετε το a, πηγαίνει στο unsorted bin.

  • Αν στη συνέχεια ζητήσετε ξανά 250 bytes, ο διαχειριστής βρίσκει το a στην ουρά και το διαιρεί, επιστρέφοντας το μέρος που ταιριάζει με το αίτημά σας και κρατώντας το υπόλοιπο στο bin.

  • Το c θα δείχνει στο προηγούμενο a και θα είναι γεμάτο με τα δεδομένα του a.

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.

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

Άλλες Αναφορές & Παραδείγματα

  • ARM64. Use after free: Δημιουργία ενός αντικειμένου χρήστη, απελευθέρωσή του, δημιουργία ενός αντικειμένου που παίρνει το απελευθερωμένο κομμάτι και επιτρέπει την εγγραφή σε αυτό, αντικαθιστώντας τη θέση του user->password από το προηγούμενο. Χρησιμοποιήστε ξανά τον χρήστη για παράκαμψη του ελέγχου του κωδικού πρόσβασης

  • Το πρόγραμμα επιτρέπει τη δημιουργία σημειώσεων. Μια σημείωση θα έχει τις πληροφορίες της σημείωσης σε ένα malloc(8) (με ένα δείκτη προς μια συνάρτηση που θα μπορούσε να κληθεί) και ένα δείκτη προς ένα άλλο malloc(<size>) με τα περιεχόμενα της σημείωσης.

  • Η επίθεση θα είναι να δημιουργηθούν 2 σημειώσεις (note0 και note1) με μεγαλύτερο μέγεθος περιεχομένου malloc από το μέγεθος των πληροφοριών της σημείωσης και στη συνέχεια να τις απελευθερώσουν ώστε να μπουν στο fast bin (ή tcache).

  • Στη συνέχεια, δημιουργήστε μια άλλη σημείωση (note2) με μέγεθος περιεχομένου 8. Το περιεχόμενο θα βρίσκεται στη note1 καθώς το κομμάτι θα επαναχρησιμοποιηθεί, όπου θα μπορούσαμε να τροποποιήσουμε το δείκτη της συνάρτησης ώστε να δείχνει στη συνάρτηση win και στη συνέχεια να γίνει Use-After-Free η note1 για να κληθεί ο νέος δείκτης συνάρτησης.

  • Είναι δυνατόν να δεσμευτεί μνήμη, να γραφτεί η επιθυμητή τιμή, να απελευθερωθεί, να επαναδεσμευτεί και καθώς τα προηγούμενα δεδομένα εξακολουθούν να υπάρχουν, θα χειριστούν σύμφωνα με τη νέα αναμενόμενη δομή στο κομμάτι κάνοντας δυνατή την ρύθμιση της τιμής για να λάβετε τη σημαία.

  • Σε αυτήν την περίπτωση είναι απαραίτητο να γραφτεί το 4 μέσα σε ένα συγκεκριμένο κομμάτι που είναι το πρώτο που δεσμεύεται (ακόμα και μετά από την αναγκαστική απελευθέρωση όλων τους). Σε κάθε νέο δεσμευμένο κομμάτι αποθηκεύεται ο αριθμός του στον πίνακα δείκτη. Στη συνέχεια, δεσμεύστε 4 κομμάτια (+ το αρχικά δεσμευμένο), το τελευταίο θα έχει μέσα του το 4, απελευθερώστε τα και αναγκάστε την επαναδέσμευση του πρώτου, το οποίο θα χρησιμοποιήσει το τελευταίο κομμάτι που απελευθερώθηκε, το οποίο είναι αυτό με το 4 μέσα του.

Last updated