Stack Overflow

Support HackTricks

What is a Stack Overflow

Μια stack overflow είναι μια ευπάθεια που συμβαίνει όταν ένα πρόγραμμα γράφει περισσότερα δεδομένα στη στοίβα από όσα έχει εκχωρηθεί να κρατήσει. Αυτά τα επιπλέον δεδομένα θα επικαλύψουν τον γειτονικό χώρο μνήμης, οδηγώντας στη διαφθορά έγκυρων δεδομένων, διαταραχή της ροής ελέγχου και ενδεχομένως την εκτέλεση κακόβουλου κώδικα. Αυτό το πρόβλημα προκύπτει συχνά λόγω της χρήσης μη ασφαλών συναρτήσεων που δεν εκτελούν έλεγχο ορίων στην είσοδο.

Το κύριο πρόβλημα αυτής της επικαλύψης είναι ότι ο αποθηκευμένος δείκτης εντολών (EIP/RIP) και ο αποθηκευμένος δείκτης βάσης (EBP/RBP) για να επιστρέψει στην προηγούμενη συνάρτηση είναι αποθηκευμένα στη στοίβα. Επομένως, ένας επιτιθέμενος θα είναι σε θέση να επικαλύψει αυτά και να ελέγξει τη ροή εκτέλεσης του προγράμματος.

Η ευπάθεια προκύπτει συνήθως επειδή μια συνάρτηση αντιγράφει στη στοίβα περισσότερα byte από την ποσότητα που έχει εκχωρηθεί γι' αυτήν, επομένως μπορεί να επικαλύψει άλλα μέρη της στοίβας.

Ορισμένες κοινές συναρτήσεις που είναι ευάλωτες σε αυτό είναι: strcpy, strcat, sprintf, gets... Επίσης, συναρτήσεις όπως fgets, read & memcpy που δέχονται ένα όρισμα μήκους, μπορεί να χρησιμοποιηθούν με ευάλωτο τρόπο αν το καθορισμένο μήκος είναι μεγαλύτερο από το εκχωρηθέν.

Για παράδειγμα, οι παρακάτω συναρτήσεις θα μπορούσαν να είναι ευάλωτες:

void vulnerable() {
char buffer[128];
printf("Enter some text: ");
gets(buffer); // This is where the vulnerability lies
printf("You entered: %s\n", buffer);
}

Finding Stack Overflows offsets

Ο πιο κοινός τρόπος για να βρείτε stack overflows είναι να δώσετε μια πολύ μεγάλη είσοδο από As (π.χ. python3 -c 'print("A"*1000)') και να περιμένετε ένα Segmentation Fault που υποδεικνύει ότι η διεύθυνση 0x41414141 προσπαθήθηκε να προσπελαστεί.

Επιπλέον, μόλις βρείτε ότι υπάρχει ευπάθεια Stack Overflow, θα χρειαστεί να βρείτε την απόσταση μέχρι να είναι δυνατό να επικαλύψετε τη διεύθυνση επιστροφής, για αυτό συνήθως χρησιμοποιείται μια ακολουθία De Bruijn. Η οποία για μια δεδομένη αλφάβητο μεγέθους k και υποακολουθίες μήκους n είναι μια κυκλική ακολουθία στην οποία κάθε δυνατή υποακολουθία μήκους _n_** εμφανίζεται ακριβώς μία φορά** ως συνεχής υποακολουθία.

Με αυτόν τον τρόπο, αντί να χρειάζεται να καταλάβετε ποια απόσταση είναι απαραίτητη για να ελέγξετε το EIP με το χέρι, είναι δυνατό να χρησιμοποιήσετε ως padding μία από αυτές τις ακολουθίες και στη συνέχεια να βρείτε την απόσταση των byte που τελείωσαν επικαλύπτοντάς την.

Είναι δυνατό να χρησιμοποιήσετε pwntools για αυτό:

from pwn import *

# Generate a De Bruijn sequence of length 1000 with an alphabet size of 256 (byte values)
pattern = cyclic(1000)

# This is an example value that you'd have found in the EIP/IP register upon crash
eip_value = p32(0x6161616c)
offset = cyclic_find(eip_value)  # Finds the offset of the sequence in the De Bruijn pattern
print(f"The offset is: {offset}")

ή GEF:

#Patterns
pattern create 200 #Generate length 200 pattern
pattern search "avaaawaa" #Search for the offset of that substring
pattern search $rsp #Search the offset given the content of $rsp

Εκμετάλλευση Στοίβας Υπερχείλισης

Κατά τη διάρκεια μιας υπερχείλισης (υποθέτοντας ότι το μέγεθος της υπερχείλισης είναι αρκετά μεγάλο) θα είστε σε θέση να επικαλύψετε τις τιμές των τοπικών μεταβλητών μέσα στη στοίβα μέχρι να φτάσετε στο αποθηκευμένο EBP/RBP και EIP/RIP (ή ακόμα περισσότερα). Ο πιο κοινός τρόπος για να εκμεταλλευτείτε αυτόν τον τύπο ευπάθειας είναι να τροποποιήσετε τη διεύθυνση επιστροφής έτσι ώστε όταν η συνάρτηση τελειώσει, η ροή ελέγχου θα ανακατευθυνθεί όπου ο χρήστης καθόρισε σε αυτόν τον δείκτη.

Ωστόσο, σε άλλα σενάρια, ίσως απλά η επικαλύψη κάποιων τιμών μεταβλητών στη στοίβα να είναι αρκετή για την εκμετάλλευση (όπως σε εύκολες προκλήσεις CTF).

Ret2win

Σε αυτούς τους τύπους προκλήσεων CTF, υπάρχει μια συνάρτηση μέσα στο δυαδικό αρχείο που ποτέ δεν καλείται και που πρέπει να καλέσετε για να κερδίσετε. Για αυτές τις προκλήσεις χρειάζεται απλώς να βρείτε την απόσταση για να επικαλύψετε τη διεύθυνση επιστροφής και να βρείτε τη διεύθυνση της συνάρτησης που θα καλέσετε (συνήθως ASLR θα είναι απενεργοποιημένο) έτσι ώστε όταν η ευάλωτη συνάρτηση επιστρέψει, η κρυφή συνάρτηση θα κληθεί:

Ret2win

Stack Shellcode

Σε αυτό το σενάριο, ο επιτιθέμενος θα μπορούσε να τοποθετήσει ένα shellcode στη στοίβα και να εκμεταλλευτεί το ελεγχόμενο EIP/RIP για να μεταπηδήσει στο shellcode και να εκτελέσει αυθαίρετο κώδικα:

Stack Shellcode

ROP & Ret2... τεχνικές

Αυτή η τεχνική είναι το θεμελιώδες πλαίσιο για να παρακάμψετε την κύρια προστασία της προηγούμενης τεχνικής: Μη εκτελέσιμη στοίβα (NX). Και επιτρέπει την εκτέλεση αρκετών άλλων τεχνικών (ret2lib, ret2syscall...) που θα καταλήξουν να εκτελούν αυθαίρετες εντολές εκμεταλλευόμενοι υπάρχουσες εντολές στο δυαδικό αρχείο:

ROP - Return Oriented Programing

Υπερχείλιση Σωρού

Μια υπερχείλιση δεν θα είναι πάντα στη στοίβα, μπορεί επίσης να είναι στον σωρό για παράδειγμα:

Heap Overflow

Τύποι προστασιών

Υπάρχουν πολλές προστασίες που προσπαθούν να αποτρέψουν την εκμετάλλευση ευπαθειών, ελέγξτε τις στο:

Common Binary Exploitation Protections & Bypasses
Υποστήριξη HackTricks

Last updated