Ret2esp / Ret2reg
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)
Επειδή ο ESP (Δείκτης Στοίβας) δείχνει πάντα στην κορυφή της στοίβας, αυτή η τεχνική περιλαμβάνει την αντικατάσταση του EIP (Δείκτης Εντολής) με τη διεύθυνση μιας jmp esp
ή call esp
εντολής. Κάνοντας αυτό, ο κώδικας shell τοποθετείται ακριβώς μετά την αντικατεστημένη EIP. Όταν εκτελείται η εντολή ret
, ο ESP δείχνει στην επόμενη διεύθυνση, ακριβώς εκεί που είναι αποθηκευμένος ο κώδικας shell.
Αν η Τυχαία Διάταξη Χώρου Διευθύνσεων (ASLR) δεν είναι ενεργοποιημένη σε Windows ή Linux, είναι δυνατόν να χρησιμοποιηθούν οι εντολές jmp esp
ή call esp
που βρίσκονται σε κοινές βιβλιοθήκες. Ωστόσο, με ASLR ενεργό, μπορεί να χρειαστεί να αναζητήσετε αυτές τις εντολές μέσα στο ευάλωτο πρόγραμμα (και μπορεί να χρειαστεί να νικήσετε PIE).
Επιπλέον, η δυνατότητα τοποθέτησης του κώδικα shell μετά την καταστροφή του EIP, αντί να είναι στη μέση της στοίβας, διασφαλίζει ότι οποιεσδήποτε εντολές push
ή pop
που εκτελούνται κατά τη διάρκεια της λειτουργίας της συνάρτησης δεν παρεμβαίνουν στον κώδικα shell. Αυτή η παρέμβαση θα μπορούσε να συμβεί αν ο κώδικας shell τοποθετούνταν στη μέση της στοίβας της συνάρτησης.
Αν σας λείπει χώρος για να γράψετε μετά την αντικατάσταση του RIP (ίσως μόνο μερικά bytes), γράψτε έναν αρχικό κώδικα shell jmp
όπως:
Και γράψτε το shellcode νωρίς στη στοίβα.
Μπορείτε να βρείτε ένα παράδειγμα αυτής της τεχνικής στο https://ir0nstone.gitbook.io/notes/types/stack/reliable-shellcode/using-rsp με μια τελική εκμετάλλευση όπως:
Μπορείτε να δείτε ένα άλλο παράδειγμα αυτής της τεχνικής στο https://guyinatuxedo.github.io/17-stack_pivot/xctf16_b0verflow/index.html. Υπάρχει μια υπερχείλιση buffer χωρίς ενεργοποιημένο το NX, χρησιμοποιείται ένα gadget για να μειώσει τη διεύθυνση του $esp
και στη συνέχεια ένα jmp esp;
για να μεταβεί στον shellcode:
Ομοίως, αν γνωρίζουμε ότι μια συνάρτηση επιστρέφει τη διεύθυνση όπου είναι αποθηκευμένο το shellcode, μπορούμε να εκμεταλλευτούμε τις εντολές call eax
ή jmp eax
(γνωστές ως τεχνική ret2eax), προσφέροντας μια άλλη μέθοδο για να εκτελέσουμε το shellcode μας. Ακριβώς όπως το eax, οποιοδήποτε άλλο καταχωρητή που περιέχει μια ενδιαφέρουσα διεύθυνση θα μπορούσε να χρησιμοποιηθεί (ret2reg).
Μπορείτε να βρείτε μερικά παραδείγματα εδώ:
strcpy
θα αποθηκεύσει στο eax
τη διεύθυνση του buffer όπου ήταν αποθηκευμένο το shellcode και eax
δεν επαναγράφεται, οπότε είναι δυνατή η χρήση ενός ret2eax
.
Στο ARM64 δεν υπάρχουν εντολές που να επιτρέπουν να πηδήξουμε στο καταχωρητή SP. Είναι πιθανό να βρούμε ένα gadget που μεταφέρει το sp σε έναν καταχωρητή και στη συνέχεια πηδά σε αυτόν τον καταχωρητή, αλλά στη libc της kali μου δεν μπόρεσα να βρω κανένα gadget όπως αυτό:
Οι μόνοι που ανακάλυψα θα άλλαζαν την τιμή του καταλόγου όπου το sp αντιγράφηκε πριν πηδήξει σε αυτό (έτσι θα γινόταν άχρηστο):
Αν ένας κατάλογος έχει μια ενδιαφέρουσα διεύθυνση, είναι δυνατόν να πηδήξεις σε αυτόν απλά βρίσκοντας την κατάλληλη εντολή. Θα μπορούσες να χρησιμοποιήσεις κάτι σαν:
Στο ARM64, είναι το x0
που αποθηκεύει την τιμή επιστροφής μιας συνάρτησης, οπότε θα μπορούσε να είναι ότι το x0 αποθηκεύει τη διεύθυνση ενός buffer που ελέγχεται από τον χρήστη με ένα shellcode για εκτέλεση.
Example code:
Έχοντας ελέγξει την αποσυναρμολόγηση της συνάρτησης, είναι δυνατόν να δούμε ότι η διεύθυνση του buffer (ευάλωτη σε bof και ελεγχόμενη από τον χρήστη) είναι αποθηκευμένη στο x0
πριν επιστρέψει από την υπερχείλιση του buffer:
Είναι επίσης δυνατό να βρούμε το gadget br x0
στη συνάρτηση do_stuff
:
Θα χρησιμοποιήσουμε αυτό το gadget για να κάνουμε άλμα σε αυτό, επειδή το δυαδικό είναι μεταγλωττισμένο ΧΩΡΙΣ PIE. Χρησιμοποιώντας ένα μοτίβο, είναι δυνατόν να δούμε ότι η απόσταση της υπερχείλισης του buffer είναι 80, οπότε η εκμετάλλευση θα είναι:
Αν αντί για fgets
χρησιμοποιούνταν κάτι όπως read
, θα ήταν δυνατό να παρακαμφθεί το PIE επίσης μόνο με την αντικατάσταση των τελευταίων 2 bytes της διεύθυνσης επιστροφής για να επιστρέψει στην εντολή br x0;
χωρίς να χρειάζεται να γνωρίζουμε τη συνολική διεύθυνση.
Με το fgets
δεν λειτουργεί γιατί προσθέτει ένα null (0x00) byte στο τέλος.
NX: Αν η στοίβα δεν είναι εκτελέσιμη, αυτό δεν θα βοηθήσει καθώς πρέπει να τοποθετήσουμε το shellcode στη στοίβα και να κάνουμε jump για να το εκτελέσουμε.
Μάθε & εξάσκησε το AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Μάθε & εξάσκησε το GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)