WWW2Exec - atexit()
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Σήμερα είναι πολύ περίεργο να εκμεταλλευτείς αυτό!
atexit()
είναι μια συνάρτηση στην οποία άλλες συναρτήσεις περνιούνται ως παράμετροι. Αυτές οι συναρτήσεις θα εκτελούνται κατά την εκτέλεση ενός exit()
ή της επιστροφής της κύριας.
Αν μπορείς να τροποποιήσεις τη διεύθυνση οποιασδήποτε από αυτές τις συναρτήσεις ώστε να δείχνει σε ένα shellcode για παράδειγμα, θα κερδίσεις έλεγχο της διαδικασίας, αλλά αυτό είναι αυτή τη στιγμή πιο περίπλοκο.
Αυτή τη στιγμή οι διευθύνσεις στις συναρτήσεις που θα εκτελούνται είναι κρυμμένες πίσω από πολλές δομές και τελικά η διεύθυνση στην οποία δείχνουν δεν είναι οι διευθύνσεις των συναρτήσεων, αλλά είναι κρυπτογραφημένες με XOR και μετατοπίσεις με μια τυχαία κλειδί. Έτσι, αυτή τη στιγμή αυτός ο επιθετικός παράγοντας δεν είναι πολύ χρήσιμος τουλάχιστον σε x86 και x64_86.
Η συνάρτηση κρυπτογράφησης είναι PTR_MANGLE
. Άλλες αρχιτεκτονικές όπως m68k, mips32, mips64, aarch64, arm, hppa... δεν υλοποιούν τη συνάρτηση κρυπτογράφησης γιατί επιστρέφει το ίδιο με αυτό που έλαβε ως είσοδο. Έτσι, αυτές οι αρχιτεκτονικές θα μπορούσαν να επιτεθούν μέσω αυτού του παραδείγματος.
Μπορείς να βρεις μια σε βάθος εξήγηση για το πώς λειτουργεί αυτό στο https://m101.github.io/binholic/2017/05/20/notes-on-abusing-exit-handlers.html
Όπως εξηγήθηκε σε αυτή την ανάρτηση, αν το πρόγραμμα τερματίσει χρησιμοποιώντας return
ή exit()
θα εκτελέσει __run_exit_handlers()
που θα καλέσει τις καταχωρημένες καταστροφές.
Αν το πρόγραμμα τερματίσει μέσω της συνάρτησης _exit()
, θα καλέσει την exit
syscall και οι χειριστές εξόδου δεν θα εκτελούνται. Έτσι, για να επιβεβαιώσεις ότι εκτελείται το __run_exit_handlers()
, μπορείς να ορίσεις ένα breakpoint σε αυτό.
Ο σημαντικός κώδικας είναι (source):
Σημειώστε πώς το map -> l_addr + fini_array -> d_un.d_ptr
χρησιμοποιείται για να υπολογίσει τη θέση του πίνακα συναρτήσεων που θα καλέσουμε.
Υπάρχουν μερικές επιλογές:
Επαναγράψτε την τιμή του map->l_addr
για να δείχνει σε ένα ψεύτικο fini_array
με οδηγίες για την εκτέλεση αυθαίρετου κώδικα
Επαναγράψτε τις καταχωρήσεις l_info[DT_FINI_ARRAY]
και l_info[DT_FINI_ARRAYSZ]
(οι οποίες είναι περισσότερο ή λιγότερο διαδοχικές στη μνήμη), για να τις κάνετε να δείχνουν σε μια πλαστή Elf64_Dyn
δομή που θα κάνει ξανά ο array
να δείχνει σε μια μνήμη ζώνη που ελέγχεται από τον επιτιθέμενο.
Αυτή η αναφορά επαναγράφει το l_info[DT_FINI_ARRAY]
με τη διεύθυνση μιας ελεγχόμενης μνήμης στο .bss
που περιέχει ένα ψεύτικο fini_array
. Αυτός ο ψεύτικος πίνακας περιέχει πρώτα μια διεύθυνση one gadget που θα εκτελεστεί και στη συνέχεια τη διαφορά μεταξύ της διεύθυνσης αυτού του ψεύτικου πίνακα και της τιμής του map->l_addr
έτσι ώστε το *array
να δείχνει στον ψεύτικο πίνακα.
Σύμφωνα με την κύρια ανάρτηση αυτής της τεχνικής και αυτή την αναφορά το ld.so αφήνει έναν δείκτη στη στοίβα που δείχνει στον δυαδικό link_map
στο ld.so. Με μια αυθαίρετη εγγραφή είναι δυνατό να το επαναγράψετε και να το κάνετε να δείχνει σε ένα ψεύτικο fini_array
που ελέγχεται από τον επιτιθέμενο με τη διεύθυνση σε ένα one gadget για παράδειγμα.
Ακολουθώντας τον προηγούμενο κώδικα μπορείτε να βρείτε μια άλλη ενδιαφέρουσα ενότητα με τον κώδικα:
Σε αυτή την περίπτωση, θα ήταν δυνατό να αντικατασταθεί η τιμή του map->l_info[DT_FINI]
που δείχνει σε μια πλαστή δομή ElfW(Dyn)
. Βρείτε περισσότερες πληροφορίες εδώ.
__run_exit_handlers
Όπως εξηγείται εδώ, αν ένα πρόγραμμα τερματίσει μέσω return
ή exit()
, θα εκτελέσει __run_exit_handlers()
που θα καλέσει οποιαδήποτε συνάρτηση καταστροφέα έχει καταχωρηθεί.
Κώδικας από _run_exit_handlers()
:
Κώδικας από __call_tls_dtors()
:
Για κάθε καταχωρημένη συνάρτηση στη tls_dtor_list
, θα αποσυμπιέσει τον δείκτη από τη cur->func
και θα την καλέσει με το επιχείρημα cur->obj
.
Χρησιμοποιώντας τη συνάρτηση tls
από αυτό το fork του GEF, είναι δυνατόν να δούμε ότι στην πραγματικότητα η dtor_list
είναι πολύ κοντά στο stack canary και το PTR_MANGLE cookie. Έτσι, με μια υπερχείλιση σε αυτό, θα ήταν δυνατό να επικαλυφθεί το cookie και το stack canary.
Επικαλύπτοντας το PTR_MANGLE cookie, θα ήταν δυνατό να παρακαμφθεί η συνάρτηση PTR_DEMANLE
ρυθμίζοντάς την σε 0x00, που σημαίνει ότι το xor
που χρησιμοποιείται για να αποκτήσει τη πραγματική διεύθυνση είναι απλώς η διεύθυνση που έχει ρυθμιστεί. Στη συνέχεια, γράφοντας στη dtor_list
είναι δυνατό να αλυσιδωθούν πολλές συναρτήσεις με τη διεύθυνση της συνάρτησης και το επιχείρημά της.
Τέλος, σημειώστε ότι ο αποθηκευμένος δείκτης δεν θα xored μόνο με το cookie αλλά και θα περιστραφεί 17 bits:
Πρέπει να λάβετε υπόψη αυτό πριν προσθέσετε μια νέα διεύθυνση.
Βρείτε ένα παράδειγμα στην αρχική ανάρτηση.
__run_exit_handlers
Αυτή η τεχνική είναι εξηγημένη εδώ και εξαρτάται ξανά από το πρόγραμμα να τερματίζει καλώντας return
ή exit()
ώστε να κληθεί __run_exit_handlers()
.
Ας ελέγξουμε περισσότερα κώδικα αυτής της συνάρτησης:
Η μεταβλητή f
δείχνει στη initial
δομή και ανάλογα με την τιμή του f->flavor
θα κληθούν διαφορετικές συναρτήσεις.
Ανάλογα με την τιμή, η διεύθυνση της συνάρτησης που θα κληθεί θα είναι σε διαφορετική θέση, αλλά θα είναι πάντα demangled.
Επιπλέον, στις επιλογές ef_on
και ef_cxa
είναι επίσης δυνατός ο έλεγχος ενός ορίσματος.
Είναι δυνατόν να ελέγξετε τη initial
δομή σε μια συνεδρία αποσφαλμάτωσης με το GEF να τρέχει gef> p initial
.
Για να εκμεταλλευτείτε αυτό, χρειάζεστε είτε να leak ή να διαγράψετε το PTR_MANGLE
cookie και στη συνέχεια να αντικαταστήσετε μια είσοδο cxa
στην αρχική με system('/bin/sh')
.
Μπορείτε να βρείτε ένα παράδειγμα αυτού στο αρχικό blog post σχετικά με την τεχνική.
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)