10 KiB
Οίκος του Roman
{% hint style="success" %}
Μάθε & εξάσκησε στο Hacking του AWS:Εκπαίδευση HackTricks AWS Red Team Expert (ARTE)
Μάθε & εξάσκησε στο Hacking του GCP: Εκπαίδευση HackTricks GCP Red Team Expert (GRTE)
Υποστήριξε το HackTricks
- Ελέγξτε τα σχέδια συνδρομής!
- Συμμετέχετε 💬 στην ομάδα Discord ή στην ομάδα telegram ή ακολουθήστε μας στο Twitter 🐦 @hacktricks_live.
- Μοιραστείτε τεχνικές χάκινγκ υποβάλλοντας PRs στα αποθετήρια HackTricks και HackTricks Cloud.
Βασικές Πληροφορίες
Αυτή ήταν μια πολύ ενδιαφέρουσα τεχνική που επέτρεπε την 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
.
/*
Current heap layout:
0x0: fastbin_victim - size 0x70
0x70: alignment_filler - size 0x90
0x100: fake_libc_chunk - size 0x70 (contains a fd ptr to main_arena + 0x68)
0x170: leftover_main - size 0x20
0x190: relative_offset_heap - size 0x70
bin layout:
fastbin: fastbin_victim -> relative_offset_heap
unsorted: leftover_main
*/
-
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:
malloc(0x60);
malloc(0x60);
uint8_t* malloc_hook_chunk = malloc(0x60);
Μέρος 2: Επίθεση unsorted_bin
Για περισσότερες πληροφορίες μπορείτε να ελέγξετε:
{% content-ref url="unsorted-bin-attack.md" %} unsorted-bin-attack.md {% endcontent-ref %}
Βασικά, επιτρέπει την εγγραφή της τιμής main_arena + 0x68
σε οποιαδήποτε τοποθεσία που καθορίζεται στο chunk->bk
. Και για την επίθεση επιλέγουμε το __malloc_hook
. Στη συνέχεια, μετά την αντικατάστασή του, θα χρησιμοποιήσουμε μια σχετική αντικατάσταση για να δείχνει σε ένα one_gadget
.
Για αυτό ξεκινάμε παίρνοντας ένα κομμάτι και το τοποθετούμε στο unsorted bin:
uint8_t* unsorted_bin_ptr = malloc(0x80);
malloc(0x30); // Don't want to consolidate
puts("Put chunk into unsorted_bin\n");
// Free the chunk to create the UAF
free(unsorted_bin_ptr);
Χρησιμοποιήστε ένα UAF σε αυτό το κομμάτι για να δείξετε το unsorted_bin_ptr->bk
στη διεύθυνση του __malloc_hook
(το οποίο το είχαμε υπολογίσει με brute force προηγουμένως).
{% hint style="danger" %} Σημειώστε ότι αυτή η επίθεση διαφθείρει το unsorted bin (και τα small και large επίσης). Έτσι μπορούμε μόνο να χρησιμοποιήσουμε εκχωρήσεις από το fast bin τώρα (ένα πιο πολύπλοκο πρόγραμμα ενδέχεται να κάνει άλλες εκχωρήσεις και να καταρρεύσει), και για να ενεργοποιήσουμε αυτό πρέπει να εκχωρήσουμε τον ίδιο μέγεθος αλλιώς το πρόγραμμα θα καταρρεύσει. {% endhint %}
Έτσι, για να ενεργοποιήσουμε την εγγραφή του 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
.