Ret2lib
Βασικές Πληροφορίες
Η ουσία του Ret2Libc είναι να ανακατευθύνει τη ροή εκτέλεσης ενός ευάλωτου προγράμματος σε μια συνάρτηση μέσα σε ένα κοινόχρηστο βιβλιοθήκη (π.χ., system, execve, strcpy) αντί να εκτελεί κώδικα κέλυφους που παρέχεται από τον εισβολέα στη στοίβα. Ο εισβολέας δημιουργεί ένα φορτίο που τροποποιεί τη διεύθυνση επιστροφής στη στοίβα για να δείχνει στην επιθυμητή συνάρτηση βιβλιοθήκης, ταυτόχρονα διαμορφώνοντας τυχόν απαραίτητα ορίσματα για να ρυθμιστούν σωστά σύμφωνα με τον κανόνα κλήσης.
Παραδειγματικά Βήματα (απλουστευμένα)
Αποκτήστε τη διεύθυνση της συνάρτησης που θα καλείτε (π.χ. system) και την εντολή που θα καλείτε (π.χ. /bin/sh)
Δημιουργήστε μια αλυσίδα ROP για να περάσετε το πρώτο όρισμα που δείχνει στο συμβολοσειρά εντολών και τη ροή εκτέλεσης στη συνάρτηση
Εύρεση των διευθύνσεων
Υποθέτοντας ότι η
libc
που χρησιμοποιείται είναι αυτή από την τρέχουσα μηχανή, μπορείτε να βρείτε πού θα φορτωθεί στη μνήμη με:
Αν θέλετε να ελέγξετε αν το ASLR αλλάζει τη διεύθυνση της βιβλιοθήκης libc μπορείτε να κάνετε:
Γνωρίζοντας το libc που χρησιμοποιείται, είναι επίσης δυνατόν να βρεθεί το offset προς τη συνάρτηση
system
με:
Γνωρίζοντας το libc που χρησιμοποιείται, είναι επίσης δυνατό να βρεθεί το offset για το string
/bin/sh
function με:
Χρησιμοποιώντας το gdb-peda / GEF
Γνωρίζοντας την βιβλιοθήκη libc που χρησιμοποιείται, είναι επίσης δυνατό να χρησιμοποιηθεί το Peda ή το GEF για να ανακτηθεί η διεύθυνση της συνάρτησης system, της συνάρτησης exit και του string /bin/sh
:
Χρήση /proc/<PID>/maps
Αν η διεργασία δημιουργεί παιδιά κάθε φορά που επικοινωνείτε μαζί της (διακομιστής δικτύου), προσπαθήστε να διαβάσετε αυτό το αρχείο (ίσως χρειαστεί να είστε ροοτ).
Εδώ μπορείτε να βρείτε ακριβώς πού φορτώνεται η libc μέσα στη διεργασία και πού θα φορτωθεί για κάθε παιδί της διεργασίας.
Σε αυτήν την περίπτωση φορτώνεται στη θέση 0xb75dc000 (Αυτή θα είναι η βασική διεύθυνση της libc)
Άγνωστη libc
Μπορεί να είναι δυνατόν να μην γνωρίζετε την libc που φορτώνει το δυαδικό αρχείο (επειδή μπορεί να βρίσκεται σε έναν διακομιστή όπου δεν έχετε πρόσβαση). Σε αυτήν την περίπτωση μπορείτε να εκμεταλλευτείτε την ευπάθεια για να διαρρεύσετε μερικές διευθύνσεις και να βρείτε ποια libc βιβλιοθήκη χρησιμοποιείται:
Leaking libc address with ROPΚαι μπορείτε να βρείτε ένα πρότυπο pwntools γι' αυτό στο:
Leaking libc - templateΓνωρίζοντας την libc με 2 μετατοπίσεις
Ελέγξτε τη σελίδα https://libc.blukat.me/ και χρησιμοποιήστε μερικές διευθύνσεις συναρτήσεων μέσα στην libc για να ανακαλύψετε τη χρησιμοποιούμενη έκδοση.
Παράκαμψη του ASLR σε 32 bits
Αυτές οι επιθέσεις με brute-forcing είναι χρήσιμες μόνο για συστήματα 32bit.
Αν η εκμετάλλευση είναι τοπική, μπορείτε να δοκιμάσετε να κάνετε brute-force τη βασική διεύθυνση της libc (χρήσιμο για συστήματα 32bit):
Εάν επιτεθείτε σε ένα απομακρυσμένο διακομιστή, μπορείτε να δοκιμάσετε να δοκιμάσετε με βία τη διεύθυνση της συνάρτησης
usleep
τηςlibc
, περνώντας ως όρισμα τον αριθμό 10 (για παράδειγμα). Εάν σε κάποιο σημείο ο διακομιστής χρειάζεται 10 δευτερόλεπτα παραπάνω για να ανταποκριθεί, τότε βρήκατε τη διεύθυνση αυτής της συνάρτησης.
One Gadget
Εκτελέστε ένα κέλυφος απλά αναπηδώντας σε μία συγκεκριμένη διεύθυνση στην libc:
One Gadgetx86 Παράδειγμα Κώδικα Ret2lib
Σε αυτό το παράδειγμα, η brute-force του ASLR ενσωματώνεται στον κώδικα και το ευάλωτο δυαδικό αρχείο βρίσκεται σε έναν απομακρυσμένο διακομιστή:
Παράδειγμα Κώδικα x64 Ret2lib
Ελέγξτε το παράδειγμα από:
ROP - Return Oriented ProgramingΠαράδειγμα ARM64 Ret2lib
Στην περίπτωση του ARM64, η εντολή ret αναπηδάει στο σημείο όπου δείχνει το μητρώο x30 και όχι στο σημείο όπου δείχνει το μητρώο στοίβας. Έτσι είναι λίγο πιο περίπλοκο.
Επίσης, στο ARM64 μια εντολή κάνει αυτό που κάνει η εντολή (δεν είναι δυνατό να αλλάξετε στη μέση των εντολών και να τις μετατρέψετε σε νέες).
Ελέγξτε το παράδειγμα από:
Ret2lib + Printf leak - arm64Ret-into-printf (ή puts)
Αυτό επιτρέπει την διαρροή πληροφοριών από τη διεργασία καλώντας το printf
/puts
με κάποια συγκεκριμένα δεδομένα που τοποθετούνται ως όρισμα. Για παράδειγμα, η τοποθέτηση της διεύθυνσης του puts
στο GOT σε μια εκτέλεση του puts
θα διαρρεύσει τη διεύθυνση του puts
στη μνήμη.
Ret2printf
Αυτό σημαίνει ουσιαστικά την κατάχρηση ενός Ret2lib για να το μετατρέψετε σε μια ευπάθεια συμβολοσειράς printf
χρησιμοποιώντας το ret2lib
για να καλέσετε το printf με τις τιμές που εκμεταλλεύεστε (ακούγεται άχρηστο αλλά είναι δυνατό):
Άλλα Παραδείγματα & αναφορές
Ret2lib, δεδομένη μια διαρροή στη διεύθυνση μιας συνάρτησης στο libc, χρησιμοποιώντας ένα one gadget
64 bit, ενεργοποιημένο το ASLR αλλά χωρίς PIE, το πρώτο βήμα είναι να γεμίσετε ένα υπερχείλισμα μέχρι το byte 0x00 του canary και στη συνέχεια να καλέσετε το puts και να το διαρρεύσετε. Με το canary δημιουργείται ένα ROP gadget για να καλέσετε το puts και να διαρρεύσετε τη διεύθυνση του puts από το GOT και ένα ROP gadget για να καλέσετε
system('/bin/sh')
64 bits, ενεργοποιημένο το ASLR, χωρίς canary, υπερχείλισμα στη στοίβα στη main από μια παιδική συνάρτηση. ROP gadget για να καλέσετε το puts και να διαρρεύσετε τη διεύθυνση του puts από το GOT και στη συνέχεια να καλέσετε ένα one gadget.
64 bits, χωρίς pie, χωρίς canary, χωρίς relro, nx. Χρησιμοποιεί τη λειτουργία write για να διαρρεύσει τη διεύθυνση του write (libc) και καλεί ένα one gadget.
Χρησιμοποιεί μια συμβολοσειρά μορφοποίησης για να διαρρεύσει το canary από τη στοίβα και ένα υπερχείλισμα buffer για να καλέσει το σύστημα (είναι στο GOT) με τη διεύθυνση του
/bin/sh
.32 bit, χωρίς relro, χωρίς canary, nx, pie. Κατάχρηση ενός κακού δείκτη για να διαρρεύσει διευθύνσεις του libc και της στοίβας από τη στοίβα. Κατάχρηση του υπερχείλισμα buffer για να κάνει ένα ret2lib καλώντας
system('/bin/sh')
(η διεύθυνση της στοίβας χρειάζεται για να παρακάμψει έναν έλεγχο).
Last updated