Ret2esp / Ret2reg
Ret2esp
Επειδή το ESP (Δείκτης Στοίβας) δείχνει πάντα στην κορυφή της στοίβας, αυτή η τεχνική περιλαμβάνει την αντικατάσταση του EIP (Δείκτης Εντολών) με τη διεύθυνση μιας εντολής jmp esp
ή call esp
. Με αυτόν τον τρόπο, το shellcode τοποθετείται ακριβώς μετά τον αντικατασταθέντα EIP. Όταν εκτελείται η εντολή ret
, το ESP δείχνει στην επόμενη διεύθυνση, ακριβώς εκεί που αποθηκεύεται το shellcode.
Αν η τυχαιοποίηση του Χώρου Διεύθυνσης (ASLR) δεν είναι ενεργοποιημένη σε Windows ή Linux, είναι δυνατόν να χρησιμοποιηθούν οι εντολές jmp esp
ή call esp
που βρίσκονται σε κοινόχρηστες βιβλιοθήκες. Ωστόσο, με την ASLR ενεργή, μπορεί να χρειαστεί να αναζητήσετε εντολές αυτού του τύπου εντός του ευάλωτου προγράμματος ίδιο του (και ίσως να χρειαστεί να ξεπεράσετε το PIE).
Επιπλέον, η δυνατότητα τοποθέτησης του shellcode μετά την διαφθορά του EIP, αντί για τη μέση της στοίβας, εξασφαλίζει ότι οποιεσδήποτε εντολές push
ή pop
που εκτελούνται κατά τη λειτουργία της συνάρτησης δεν επηρεάζουν το shellcode. Αυτή η παρεμβολή θα μπορούσε να συμβεί αν το shellcode τοποθετούνταν στη μέση της στοίβας της συνάρτησης.
Έλλειψη χώρου
Αν σας λείπει χώρος για εγγραφή μετά την αντικατάσταση του RIP (ίσως μόνο λίγα bytes), γράψτε ένα αρχικό jmp
shellcode όπως:
Και γράψτε το shellcode νωρίς στο stack.
Παράδειγμα
Μπορείτε να βρείτε ένα παράδειγμα αυτής της τεχνικής στο https://ir0nstone.gitbook.io/notes/types/stack/reliable-shellcode/using-rsp με ένα τελικό exploit όπως:
Μπορείτε να δείτε ένα άλλο παράδειγμα αυτής της τεχνικής στο https://guyinatuxedo.github.io/17-stack_pivot/xctf16_b0verflow/index.html. Υπάρχει ένας υπερχείλισμος buffer χωρίς το NX ενεργοποιημένο, χρησιμοποιείται ένα gadget για να μειώσει τη διεύθυνση του $esp
και στη συνέχεια ένα jmp esp;
για να μεταβεί στο shellcode:
Ret2reg
Επίσης, αν γνωρίζουμε ότι μια συνάρτηση επιστρέφει τη διεύθυνση όπου αποθηκεύεται το shellcode, μπορούμε να εκμεταλλευτούμε τις οδηγίες call eax
ή jmp eax
(γνωστή ως τεχνική ret2eax), προσφέροντας άλλη μέθοδο για την εκτέλεση του shellcode μας. Όπως και με το eax, οποιοδήποτε άλλο register που περιέχει μια ενδιαφέρουσα διεύθυνση θα μπορούσε να χρησιμοποιηθεί (ret2reg).
Παράδειγμα
Μπορείτε να βρείτε μερικά παραδείγματα εδώ:
Το
strcpy
θα αποθηκεύσει στοeax
τη διεύθυνση του buffer όπου αποθηκεύτηκε το shellcode και τοeax
δεν αντικαθίσταται, οπότε είναι δυνατή η χρήση ενόςret2eax
.
ARM64
Ret2sp
Στο ARM64 δεν υπάρχουν οδηγίες που επιτρέπουν τη μετάβαση στο μητρώο SP. Μπορεί να είναι δυνατό να βρεθεί ένα gadget που μετακινεί το sp σε ένα μητρώο και στη συνέχεια μεταβαίνει σε αυτό το μητρώο, αλλά στην libc του Kali μου δεν μπόρεσα να βρω κάποιο gadget σαν αυτό:
Οι μόνοι που ανακάλυψα θα άλλαζαν την τιμή του μητρώου όπου αντιγράφτηκε το sp πριν από την αλλαγή σε αυτό (έτσι θα έγινε άχρηστο):
Ret2reg
Αν ένα μητρώο έχει μια ενδιαφέρουσα διεύθυνση, είναι δυνατόν να αλλάξετε σε αυτήν απλά βρίσκοντας την κατάλληλη εντολή. Θα μπορούσατε να χρησιμοποιήσετε κάτι σαν:
Στο ARM64, είναι το x0
που αποθηκεύει την τιμή επιστροφής μιας συνάρτησης, οπότε μπορεί να συμβεί να το x0 αποθηκεύει τη διεύθυνση ενός buffer που ελέγχεται από τον χρήστη με ένα shellcode για εκτέλεση.
Παράδειγμα κώδικα:
Ελέγχοντας την αποσυναρμολόγηση της συνάρτησης είναι δυνατόν να δούμε ότι η διεύθυνση του buffer (ευάλωτο σε bof και ελεγχόμενο από τον χρήστη) είναι αποθηκευμένη στο x0
πριν επιστρέψουμε από την υπερχείλιση του buffer:
Είναι επίσης δυνατόν να βρεθεί το gadget br x0
στη συνάρτηση do_stuff
:
Θα χρησιμοποιήσουμε αυτό το gadget για να μεταβούμε σε αυτό επειδή το δυαδικό αρχείο είναι μεταγλωττισμένο ΧΩΡΙΣ PIE. Χρησιμοποιώντας ένα πρότυπο είναι δυνατόν να δούμε ότι το offset της υπερχείλισης του buffer είναι 80, έτσι το exploit θα είναι:
Αν αντί για το fgets
χρησιμοποιούνταν κάτι σαν το read
, θα ήταν δυνατό να παρακαμφθεί το PIE επίσης με τον απλό προσδιορισμό των τελευταίων 2 bytes της διεύθυνσης επιστροφής για να επιστρέψει στην εντολή br x0;
χωρίς την ανάγκη να γνωρίζει την πλήρη διεύθυνση.
Με το fgets
δεν λειτουργεί επειδή προσθέτει ένα null (0x00) byte στο τέλος.
Προστασίες
NX: Αν η στοίβα δεν είναι εκτελέσιμη, αυτό δεν θα βοηθήσει καθώς χρειαζόμαστε να τοποθετήσουμε το shellcode στη στοίβα και να κάνουμε άλμα για να το εκτελέσουμε.
Αναφορές
Last updated