Stack Canaries
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)
StackGuard εισάγει μια ειδική τιμή γνωστή ως canary πριν από το EIP (Extended Instruction Pointer), συγκεκριμένα 0x000aff0d
(που αντιπροσωπεύει null, newline, EOF, carriage return) για να προστατεύσει από buffer overflows. Ωστόσο, οι συναρτήσεις όπως recv()
, memcpy()
, read()
, και bcopy()
παραμένουν ευάλωτες, και δεν προστατεύει το EBP (Base Pointer).
StackShield ακολουθεί μια πιο εξελιγμένη προσέγγιση από το StackGuard διατηρώντας μια Global Return Stack, η οποία αποθηκεύει όλες τις διευθύνσεις επιστροφής (EIPs). Αυτή η ρύθμιση διασφαλίζει ότι οποιαδήποτε υπερχείλιση δεν προκαλεί ζημιά, καθώς επιτρέπει τη σύγκριση μεταξύ των αποθηκευμένων και των πραγματικών διευθύνσεων επιστροφής για την ανίχνευση περιστατικών υπερχείλισης. Επιπλέον, το StackShield μπορεί να ελέγξει τη διεύθυνση επιστροφής σε σχέση με μια οριακή τιμή για να ανιχνεύσει αν το EIP δείχνει εκτός του αναμενόμενου χώρου δεδομένων. Ωστόσο, αυτή η προστασία μπορεί να παρακαμφθεί μέσω τεχνικών όπως Return-to-libc, ROP (Return-Oriented Programming), ή ret2ret, υποδεικνύοντας ότι το StackShield δεν προστατεύει επίσης τις τοπικές μεταβλητές.
-fstack-protector
:Αυτή η μηχανισμός τοποθετεί ένα canary πριν από το EBP, και αναδιοργανώνει τις τοπικές μεταβλητές για να τοποθετήσει τα buffers σε υψηλότερες διευθύνσεις μνήμης, αποτρέποντας την επικάλυψη άλλων μεταβλητών. Επίσης, αντιγράφει με ασφάλεια τα επιχειρήματα που περνούν στο stack πάνω από τις τοπικές μεταβλητές και χρησιμοποιεί αυτά τα αντίγραφα ως επιχειρήματα. Ωστόσο, δεν προστατεύει πίνακες με λιγότερους από 8 στοιχείων ή buffers εντός της δομής ενός χρήστη.
Το canary είναι ένας τυχαίος αριθμός που προέρχεται από το /dev/urandom
ή μια προεπιλεγμένη τιμή 0xff0a0000
. Αποθηκεύεται στο TLS (Thread Local Storage), επιτρέποντας στους κοινόχρηστους χώρους μνήμης μεταξύ νημάτων να έχουν παγκόσμιες ή στατικές μεταβλητές συγκεκριμένες για το νήμα. Αυτές οι μεταβλητές αντιγράφονται αρχικά από τη γονική διαδικασία, και οι παιδικές διαδικασίες μπορούν να τροποποιήσουν τα δεδομένα τους χωρίς να επηρεάσουν τη γονική ή τις αδελφές διαδικασίες. Παρ' όλα αυτά, αν χρησιμοποιηθεί μια fork()
χωρίς να δημιουργηθεί ένα νέο canary, όλες οι διαδικασίες (γονικές και παιδικές) μοιράζονται το ίδιο canary, καθιστώντας το ευάλωτο. Στην αρχιτεκτονική i386, το canary αποθηκεύεται στο gs:0x14
, και στην x86_64, στο fs:0x28
.
Αυτή η τοπική προστασία αναγνωρίζει συναρτήσεις με buffers ευάλωτα σε επιθέσεις και εισάγει κώδικα στην αρχή αυτών των συναρτήσεων για να τοποθετήσει το canary, και στο τέλος για να επαληθεύσει την ακεραιότητά του.
Όταν ένας web server χρησιμοποιεί fork()
, επιτρέπει μια επίθεση brute-force για να μαντέψει το canary byte by byte. Ωστόσο, η χρήση του execve()
μετά το fork()
επαναγράφει τον χώρο μνήμης, αναιρώντας την επίθεση. Το vfork()
επιτρέπει στην παιδική διαδικασία να εκτελείται χωρίς αναπαραγωγή μέχρι να προσπαθήσει να γράψει, οπότε δημιουργείται μια αναπαραγωγή, προσφέροντας μια διαφορετική προσέγγιση στη δημιουργία διαδικασιών και τη διαχείριση μνήμης.
Στα x64
binaries, το canary cookie είναι ένα 0x8
byte qword. Τα πρώτα επτά bytes είναι τυχαία και το τελευταίο byte είναι ένα null byte.
Στα x86
binaries, το canary cookie είναι ένα 0x4
byte dword. Τα πρώτα τρία bytes είναι τυχαία και το τελευταίο byte είναι ένα null byte.
Το λιγότερο σημαντικό byte και των δύο canaries είναι ένα null byte επειδή θα είναι το πρώτο στο stack που προέρχεται από χαμηλότερες διευθύνσεις και επομένως οι συναρτήσεις που διαβάζουν συμβολοσειρές θα σταματήσουν πριν το διαβάσουν.
Διαρροή του canary και στη συνέχεια επικάλυψη του (π.χ. buffer overflow) με την τιμή του.
Αν το canary forked σε παιδικές διαδικασίες μπορεί να είναι δυνατό να brute-force αυτό byte by byte:
Αν υπάρχει κάποια ενδιαφέρουσα διαρροή ή ευπάθεια αυθαίρετης ανάγνωσης στο binary μπορεί να είναι δυνατό να διαρρεύσει:
Επικάλυψη των αποθηκευμένων δεικτών στο stack
Το stack που είναι ευάλωτο σε υπερχείλιση stack μπορεί να περιέχει διευθύνσεις σε συμβολοσειρές ή συναρτήσεις που μπορούν να επαναγραφούν προκειμένου να εκμεταλλευτούν την ευπάθεια χωρίς να χρειάζεται να φτάσουν στο canary του stack. Ελέγξτε:
Τροποποίηση και των δύο canary master και thread
Μια υπερχείλιση buffer σε μια νηματική συνάρτηση που προστατεύεται με canary μπορεί να χρησιμοποιηθεί για τροποποίηση του master canary του νήματος. Ως αποτέλεσμα, η μείωση είναι άχρηστη επειδή ο έλεγχος χρησιμοποιείται με δύο canaries που είναι οι ίδιες (αν και τροποποιημένες).
Επιπλέον, μια υπερχείλιση buffer σε μια νηματική συνάρτηση που προστατεύεται με canary θα μπορούσε να χρησιμοποιηθεί για τροποποίηση του master canary που αποθηκεύεται στο TLS. Αυτό συμβαίνει επειδή, μπορεί να είναι δυνατό να φτάσουμε στη θέση μνήμης όπου αποθηκεύεται το TLS (και επομένως, το canary) μέσω μιας bof στο stack ενός νήματος. Ως αποτέλεσμα, η μείωση είναι άχρηστη επειδή ο έλεγχος χρησιμοποιείται με δύο canaries που είναι οι ίδιες (αν και τροποποιημένες). Αυτή η επίθεση εκτελείται στην αναφορά: http://7rocky.github.io/en/ctf/htb-challenges/pwn/robot-factory/#canaries-and-threads
Ελέγξτε επίσης την παρουσίαση του https://www.slideshare.net/codeblue_jp/master-canary-forging-by-yuki-koike-code-blue-2015 που αναφέρει ότι συνήθως το TLS αποθηκεύεται με mmap
και όταν δημιουργείται ένα stack νημάτων δημιουργείται επίσης με mmap
σύμφωνα με αυτό, το οποίο μπορεί να επιτρέπει την υπερχείλιση όπως φαίνεται στην προηγούμενη αναφορά.
Τροποποίηση της εγγραφής GOT του __stack_chk_fail
Αν το binary έχει Partial RELRO, τότε μπορείτε να χρησιμοποιήσετε μια αυθαίρετη εγγραφή για να τροποποιήσετε την εγγραφή GOT του __stack_chk_fail
ώστε να είναι μια ψεύτικη συνάρτηση που δεν μπλοκάρει το πρόγραμμα αν το canary τροποποιηθεί.
Αυτή η επίθεση εκτελείται στην αναφορά: https://7rocky.github.io/en/ctf/other/securinets-ctf/scrambler/
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)