Stack Pivoting - EBP2Ret - EBP chaining
Βασικές Πληροφορίες
Αυτή η τεχνική εκμεταλλεύεται τη δυνατότητα να χειριστεί το Δείκτη Βάσης (EBP) για να αλυσίδωσει την εκτέλεση πολλαπλών συναρτήσεων μέσω προσεκτικής χρήσης του καταχωρητή EBP και της ακολουθίας εντολών leave; ret
.
Για να θυμηθείτε, το leave
σημαίνει βασικά:
Και καθώς το EBP βρίσκεται στη στοίβα πριν το EIP είναι δυνατό να το ελέγχετε ελέγχοντας τη στοίβα.
EBP2Ret
Αυτή η τεχνική είναι ιδιαίτερα χρήσιμη όταν μπορείτε να τροποποιήσετε τον καταχωρητή EBP αλλά δεν έχετε άμεσο τρόπο να αλλάξετε τον καταχωρητή EIP. Εκμεταλλεύεται τη συμπεριφορά των συναρτήσεων όταν ολοκληρώνουν την εκτέλεσή τους.
Αν, κατά την εκτέλεση της fvuln
, καταφέρετε να εισάγετε ένα ψεύτικο EBP στη στοίβα που δείχνει σε μια περιοχή στη μνήμη όπου βρίσκεται η διεύθυνση του shellcode σας (συν τέσσερα bytes για τη λειτουργία pop
), μπορείτε να ελέγχετε έμμεσα τον EIP. Καθώς η fvuln
επιστρέφει, το ESP ορίζεται σε αυτή την κατασκευασμένη τοποθεσία, και η επόμενη λειτουργία pop
μειώνει το ESP κατά 4, κάνοντάς το να δείχνει αποτελεσματικά σε μια διεύθυνση που έχει αποθηκευτεί από τον επιτιθέμενο εκεί.
Σημειώστε πώς χρειάζεστε να γνωρίζετε 2 διευθύνσεις: Εκεί όπου θα πάει το ESP, όπου θα χρειαστεί να γράψετε τη διεύθυνση που δείχνει το ESP.
Κατασκευή Εκμετάλλευσης
Πρώτα πρέπει να γνωρίζετε μια διεύθυνση όπου μπορείτε να γράψετε αυθαίρετα δεδομένα / διευθύνσεις. Το ESP θα δείχνει εδώ και θα εκτελέσει το πρώτο ret
.
Στη συνέχεια, πρέπει να γνωρίζετε τη διεύθυνση που χρησιμοποιείται από το ret
που θα εκτελέσει αυθαίρετο κώδικα. Θα μπορούσατε να χρησιμοποιήσετε:
Μια έγκυρη διεύθυνση ONE_GADGET.
Η διεύθυνση της
system()
ακολουθούμενη από 4 άχρηστα bytes και τη διεύθυνση του"/bin/sh"
(x86 bits).Η διεύθυνση ενός gadget
jump esp;
(ret2esp) ακολουθούμενη από το shellcode για εκτέλεση.Κάποια αλυσίδα ROP
Θυμηθείτε ότι πριν από οποιαδήποτε από αυτές τις διευθύνσεις στο ελεγχόμενο μέρος της μνήμης, πρέπει να υπάρχουν 4
bytes λόγω του pop
μέρους της εντολής leave
. Θα ήταν δυνατό να καταχραστείτε αυτά τα 4B για να ορίσετε ένα δεύτερο ψεύτικο EBP και να συνεχίσετε τον έλεγχο της εκτέλεσης.
Εκμετάλλευση Off-By-One
Υπάρχει μια συγκεκριμένη παραλλαγή αυτής της τεχνικής που είναι γνωστή ως "Off-By-One Exploit". Χρησιμοποιείται όταν μπορείτε να τροποποιήσετε μόνο το λιγότερο σημαντικό byte του EBP. Σε τέτοιες περιπτώσεις, η τοποθεσία μνήμης που αποθηκεύει τη διεύθυνση προς την οποία θα πρέπει να μεταβεί με το ret
πρέπει να μοιράζεται τα πρώτα τρία bytes με το EBP, επιτρέποντας μια παρόμοια χειραγώγηση με περισσότερους περιορισμένους όρους.
Συνήθως τροποποιείται το byte 0x00 για να μεταβεί όσο το δυνατόν πιο μακριά.
Επίσης, είναι συνηθισμένο να χρησιμοποιείται ένα RET sled στη στοίβα και να τοποθετείται η πραγματική αλυσίδα ROP στο τέλος για να είναι πιο πιθανό να δείχνει το νέο ESP μέσα στο RET SLED και να εκτελείται η τελική αλυσίδα ROP.
Αλυσίδα EBP
Επομένως, τοποθετώντας μια ελεγχόμενη διεύθυνση στην είσοδο EBP
της στοίβας και μια διεύθυνση στο EIP
για το leave; ret
, είναι δυνατό να μετακινηθεί το ESP
στην ελεγχόμενη διεύθυνση EBP
από τη στοίβα.
Τώρα, το ESP
ελέγχεται δείχνοντας σε μια επιθυμητή διεύθυνση και η επόμενη εντολή που θα εκτελεστεί είναι ένα RET
. Για να καταχραστείτε αυτό, είναι δυνατό να τοποθετήσετε στην ελεγχόμενη θέση του ESP αυτό:
&(επόμενο ψεύτικο EBP)
-> Φόρτωση του νέου EBP λόγω τουpop ebp
από την εντολήleave
system()
-> Καλείται από τοret
&(leave;ret)
-> Καλείται μετά τη λήξη του συστήματος, θα μετακινήσει το ESP στο ψεύτικο EBP και θα ξεκινήσει ξανά&("/bin/sh")
-> Παράμετρος για τοsystem
Βασικά με αυτόν τον τρόπο είναι δυνατό να αλυσίδωσετε αρκετά ψεύτικα EBPs για να ελέγξετε τη ροή του προγράμματος.
Αυτό είναι σαν ένα ret2lib, αλλά πιο πολύπλοκο χωρίς προφανές όφελος αλλά θα μπορούσε να είναι ενδιαφέρον σε κάποιες εξαιρετικές περιπτώσεις.
Επιπλέον, εδώ έχετε ένα παράδειγμα ενός προκλητικού που χρησιμοποιεί αυτή την τεχνική με ένα διαρροή στη στοίβα για να καλέσει μια νικητήρια συνάρτηση. Αυτό είναι το τελικό φορτίο από τη σελίδα:
Η EBP ενδέχεται να μη χρησιμοποιείται
Όπως εξηγείται σε αυτήν την ανάρτηση, αν ένα δυαδικό αρχείο μεταγλωττίζεται με κάποιες βελτιστοποιήσεις, το EBP δεν καταφέρνει να ελέγξει το ESP, επομένως, οποιαδήποτε εκμετάλλευση που λειτουργεί ελέγχοντας το EBP θα αποτύχει βασικά επειδή δεν έχει κανένα πραγματικό αποτέλεσμα. Αυτό συμβαίνει επειδή το προλόγιο και το επίλογο αλλάζουν αν το δυαδικό αρχείο είναι βελτιστοποιημένο.
Μη βελτιστοποιημένο:
Βελτιστοποιημένο:
Άλλοι τρόποι για να ελέγχετε το RSP
pop rsp
gadget
pop rsp
gadgetΣε αυτήν τη σελίδα μπορείτε να βρείτε ένα παράδειγμα χρησιμοποιώντας αυτήν την τεχνική. Για αυτήν την πρόκληση χρειαζόταν να καλεστεί μια συνάρτηση με 2 συγκεκριμένα ορίσματα, και υπήρχε ένα pop rsp
gadget και υπήρχε ένα διαρροή από τη στοίβα:
xchg <reg>, rsp εργαλείο
jmp esp
Ελέγξτε την τεχνική ret2esp εδώ:
pageRet2esp / Ret2regΑναφορές & Άλλα Παραδείγματα
64 bits, εκμετάλλευση off by one με ένα rop chain που ξεκινά με ένα ret sled
64 bit, χωρίς relro, canary, nx και pie. Το πρόγραμμα παρέχει ένα διαρροή για το stack ή το pie και ένα WWW ενός qword. Πρώτα πάρτε τη διαρροή του stack και χρησιμοποιήστε το WWW για να πάτε πίσω και να πάρετε τη διαρροή του pie. Στη συνέχεια χρησιμοποιήστε το WWW για να δημιουργήσετε έναν αιώνιο βρόγχο καταχρώμενοι τις καταχωρήσεις
.fini_array
+ καλώντας το__libc_csu_fini
(περισσότερες πληροφορίες εδώ). Καταχρώντας αυτήν τη "αιώνια" εγγραφή, γράφεται ένα ROP chain στο .bss και καταλήγει να το καλεί περιστρέφοντας με το RBP.
ARM64
Στο ARM64, οι πρόλογοι και επίλογοι των συναρτήσεων δεν αποθηκεύουν και ανακτούν το SP registry στη στοίβα. Επιπλέον, η εντολή RET
δεν επιστρέφει στη διεύθυνση που δείχνει το SP, αλλά στη διεύθυνση μέσα στο x30
.
Συνεπώς, από προεπιλογή, απλά καταχρώμενοι τον επίλογο δεν θα μπορούσατε να ελέγξετε το SP registry με τον υπεργραφόμενο κάποια δεδομένα μέσα στη στοίβα. Και ακόμη κι αν καταφέρετε να ελέγξετε το SP, θα χρειαζόσασταν έναν τρόπο να ελέγξετε το x30
register.
πρόλογος
επίλογος
Ο τρόπος για να εκτελέσετε κάτι παρόμοιο με το stack pivoting στο ARM64 θα ήταν να μπορείτε να ελέγχετε το SP
(ελέγχοντας κάποιο register του οποίου η τιμή περνά στο SP
ή επειδή για κάποιο λόγο το SP
παίρνει τη διεύθυνσή του από τη στοίβα και έχουμε ένα υπερχείλιση) και στη συνέχεια να καταχρηστείτε τον επίλογο για να φορτώσετε τον x30
register από έναν ελεγχόμενο SP
και να RET
σε αυτόν.
Επίσης, στην ακόλουθη σελίδα μπορείτε να δείτε το ισοδύναμο του Ret2esp στο ARM64:
pageRet2esp / Ret2regLast updated