House of Roman
Βασικές Πληροφορίες
Αυτή ήταν μια πολύ ενδιαφέρουσα τεχνική που επέτρεπε την RCE χωρίς διαρροές μέσω ψεύτικων fastbins, επίθεση στο unsorted_bin και σχετικές αντικαταστάσεις. Ωστόσο, έχει διορθωθεί.
Κώδικας
Μπορείτε να βρείτε ένα παράδειγμα στο https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c
Στόχος
RCE με κατάχρηση σχετικών δεικτών
Απαιτήσεις
Επεξεργασία δεικτών fastbin και unsorted bin
Πρέπει να υπάρχουν 12 bits τυχαιότητας που πρέπει να αναγκαστούν (πιθανότητα 0,02%) να λειτουργήσουν
Βήματα Επίθεσης
Μέρος 1: Το Fastbin Chunk δείχνει στο __malloc_hook
Δημιουργήστε αρκετά κομμάτια:
fastbin_victim
(0x60, μετατόπιση 0): UAF κομμάτι αργότερα για να επεξεργαστείτε το δείκτη του σωρού αργότερα ώστε να δείχνει στην τιμή της LibC.chunk2
(0x80, μετατόπιση 0x70): Για καλή ευθυγράμμισηmain_arena_use
(0x80, μετατόπιση 0x100)relative_offset_heap
(0x60, μετατόπιση 0x190): σχετική μετατόπιση στο κομμάτι 'main_arena_use'
Στη συνέχεια, ελευθερώστε το main_arena_use
, το οποίο θα τοποθετήσει αυτό το κομμάτι στη λίστα unsorted και θα λάβει ένα δείκτη στο main_arena + 0x68
τόσο στους δείκτες fd
όσο και bk
.
Τώρα δεσμεύεται ένα νέο κομμάτι fake_libc_chunk(0x60)
επειδή θα περιέχει τους δείκτες στο main_arena + 0x68
στους fd
και bk
.
Στη συνέχεια, ελευθερώνονται τα relative_offset_heap
και fastbin_victim
.
fastbin_victim
έχει έναfd
που δείχνει στοrelative_offset_heap
relative_offset_heap
είναι μια μετατόπιση απόστασης από τοfake_libc_chunk
, το οποίο περιέχει ένα δείκτη προς τοmain_arena + 0x68
Αλλάζοντας απλά το τελευταίο byte του
fastbin_victim.fd
είναι δυνατό να κάνουμε τοfastbin_victim
να δείχνει στοmain_arena + 0x68
Για τις προηγούμενες ενέργειες, ο επιτιθέμενος πρέπει να είναι ικανός να τροποποιήσει τον δείκτη fd του fastbin_victim
.
Στη συνέχεια, το main_arena + 0x68
δεν είναι τόσο ενδιαφέρον, οπότε ας το τροποποιήσουμε ώστε ο δείκτης να δείχνει στο __malloc_hook
.
Σημειώστε ότι το __memalign_hook
συνήθως ξεκινά με 0x7f
και μηδενικά πριν από αυτό, οπότε είναι δυνατό να το πλασάρουμε ως τιμή στο fast bin 0x70
. Επειδή τα τελευταία 4 bits της διεύθυνσης είναι τυχαία, υπάρχουν 2^4=16
πιθανότητες για την τιμή να καταλήξει εκεί που μας ενδιαφέρει. Έτσι εδώ πραγματοποιείται μια επίθεση BF ώστε το κομμάτι να καταλήξει ως εξής: 0x70: fastbin_victim -> fake_libc_chunk -> (__malloc_hook - 0x23)
.
(Για περισσότερες πληροφορίες σχετικά με τα υπόλοιπα bytes ελέγξτε την εξήγηση στο how2heap παράδειγμα). Αν η BF δεν λειτουργήσει, το πρόγραμμα απλώς καταρρέει (οπότε ξεκινήστε ξανά μέχρι να λειτουργήσει).
Στη συνέχεια, πραγματοποιούνται 2 mallocs για να αφαιρεθούν τα 2 αρχικά fast bin chunks και στη συνέχεια γίνεται μια τρίτη κλήση για να ληφθεί ένα κομμάτι στο __malloc_hook:
Μέρος 2: Επίθεση unsorted_bin
Για περισσότερες πληροφορίες μπορείτε να ελέγξετε:
Unsorted Bin AttackΒασικά, επιτρέπει την εγγραφή της τιμής main_arena + 0x68
σε οποιαδήποτε τοποθεσία που καθορίζεται στο chunk->bk
. Και για την επίθεση επιλέγουμε το __malloc_hook
. Στη συνέχεια, μετά την αντικατάστασή του, θα χρησιμοποιήσουμε μια σχετική αντικατάσταση για να δείχνει σε ένα one_gadget
.
Για αυτό ξεκινάμε παίρνοντας ένα κομμάτι και το τοποθετούμε στο unsorted bin:
Χρησιμοποιήστε ένα UAF σε αυτό το κομμάτι για να δείξετε το unsorted_bin_ptr->bk
στη διεύθυνση του __malloc_hook
(το οποίο το είχαμε υπολογίσει με brute force προηγουμένως).
Σημειώστε ότι αυτή η επίθεση διαφθείρει το unsorted bin (και τα small και large επίσης). Έτσι μπορούμε μόνο να χρησιμοποιήσουμε εκχωρήσεις από το fast bin τώρα (ένα πιο πολύπλοκο πρόγραμμα ενδέχεται να κάνει άλλες εκχωρήσεις και να καταρρεύσει), και για να ενεργοποιήσουμε αυτό πρέπει να εκχωρήσουμε τον ίδιο μέγεθος αλλιώς το πρόγραμμα θα καταρρεύσει.
Έτσι, για να ενεργοποιήσουμε την εγγραφή του main_arena + 0x68
στο __malloc_hook
εκτελούμε μετά την ρύθμιση του __malloc_hook
στο unsorted_bin_ptr->bk
απλώς πρέπει να κάνουμε: malloc(0x80)
Βήμα 3: Ρύθμιση του __malloc_hook σε σύστημα
Στο πρώτο βήμα καταλήξαμε να ελέγχουμε ένα κομμάτι που περιέχει το __malloc_hook
(στη μεταβλητή malloc_hook_chunk
) και στο δεύτερο βήμα καταφέραμε να γράψουμε το main_arena + 0x68
εδώ.
Τώρα, εκμεταλλευόμαστε μια μερική επικάλυψη στο malloc_hook_chunk
για να χρησιμοποιήσουμε τη διεύθυνση libc που γράψαμε εκεί (main_arena + 0x68
) για να δείξουμε μια διεύθυνση one_gadget
.
Εδώ είναι όπου απαιτείται να υπολογίσουμε με brute force 12 bits τυχαιότητας (περισσότερες πληροφορίες στο how2heap παράδειγμα).
Τέλος, αφού αντικατασταθεί η σωστή διεύθυνση, καλέστε το malloc
και ενεργοποιήστε το one_gadget
.
Αναφορές
Last updated