BROP - Blind Return Oriented Programming

Μάθετε το χάκινγκ στο AWS από το μηδέν μέχρι τον ήρωα με το htARTE (Ειδικός Ερυθρού Συνεργείου AWS του HackTricks)!

Άλλοι τρόποι υποστήριξης του HackTricks:

Βασικές Πληροφορίες

Ο στόχος αυτής της επίθεσης είναι να καταχραστεί ένα ROP μέσω ενός buffer overflow χωρίς καμία πληροφορία για το ευάλωτο δυαδικό. Αυτή η επίθεση βασίζεται στο ακόλουθο σενάριο:

  • Μια ευπαθής στοίβα και γνώση για το πώς να την ενεργοποιήσετε.

  • Ένα εφαρμογή διακομιστή που επανεκκινείται μετά από κάθε κατάρρευση.

Επίθεση

1. Εύρεση ευπαθούς μετατόπισης αποστέλλοντας έναν επιπλέον χαρακτήρα μέχρι να ανιχνευθεί μια δυσλειτουργία του διακομιστή

2. Βία-δύναμη του canary για διαρροή αυτού

3. Βία-δύναμη αποθηκευμένων RBP και RIP διευθύνσεων στη στοίβα για να τις διαρρεύσετε

Μπορείτε να βρείτε περισσότερες πληροφορίες σχετικά με αυτές τις διαδικασίες εδώ (BF Forked & Threaded Stack Canaries) και εδώ (BF Διευθύνσεις στη Στοίβα).

4. Εύρεση του gadget στάσης

Αυτό το gadget επιτρέπει ουσιαστικά να επιβεβαιωθεί ότι κάτι ενδιαφέρον εκτελέστηκε από το ROP gadget επειδή η εκτέλεση δεν κατέρρευσε. Συνήθως, αυτό το gadget θα είναι κάτι που σταματά την εκτέλεση και θα βρίσκεται στο τέλος της αλυσίδας ROP κατά την αναζήτηση ROP gadgets για να επιβεβαιώσετε ότι ένα συγκεκριμένο ROP gadget εκτελέστηκε

5. Εύρεση BROP gadget

Αυτή η τεχνική χρησιμοποιεί το ret2csu gadget. Και αυτό οφείλεται στο γεγονός ότι αν έχετε πρόσβαση σε αυτό το gadget στη μέση ορισμένων εντολών, λαμβάνετε gadgets για να ελέγξετε τα rsi και rdi:

Αυτά θα ήταν τα gadgets:

  • pop rsi; pop r15; ret

  • pop rdi; ret

Παρατηρήστε πώς με αυτά τα gadgets είναι δυνατόν να ελέγξετε 2 ορίσματα μιας συνάρτησης προς κλήση.

Επίσης, παρατηρήστε ότι το ret2csu gadget έχει μια πολύ μοναδική υπογραφή επειδή θα αποσυρθούν 6 καταχωρητές από τη στοίβα. Έτσι, αποστέλλοντας μια αλυσίδα όπως:

'A' * μετατόπιση + canary + rbp + ΔΙΕΥΘΥΝΣΗ + 0xdead * 6 + STOP

Αν το STOP εκτελεστεί, αυτό σημαίνει βασικά ότι χρησιμοποιήθηκε μια διεύθυνση που αποσύρει 6 καταχωρητές από τη στοίβα. Ή ότι η χρησιμοποιηθείσα διεύθυνση ήταν επίσης μια διεύθυνση STOP.

Για να αφαιρέσετε αυτήν την τελευταία επιλογή εκτελείται μια νέα αλυσίδα όπως η ακόλουθη και δεν πρέπει να εκτελεστεί το STOP gadget για να επιβεβαιωθεί ότι η προηγούμενη αποσύρθηκε 6 καταχωρητές:

'A' * μετατόπιση + canary + rbp + ΔΙΕΥΘΥΝΣΗ

Γνωρίζοντας τη διεύθυνση του ret2csu gadget, είναι δυνατόν να συμπεράνετε τη διεύθυνση των gadgets για τον έλεγχο του rsi και rdi.

6. Εύρεση PLT

Η πίνακας PLT μπορεί να αναζητηθεί από το 0x400000 ή από τη διευθυνση RIP που διέρρευσε από τη στοίβα (αν χρησιμοποιείται PIE). Τα κεντρίσματα του πίνακα είναι χωρισμένα κατά 16B (0x10B), και όταν καλείται μια συνάρτηση ο διακομιστής δεν καταρρέει ακόμα κι αν τα ορίσματα δεν είναι σωστά. Επίσης, η ελέγχουσα διεύθυνση ενός κεντρίσματος στο PLT + 6B δεν καταρρέει καθώς είναι ο πρώτος κώδικας που εκτελείται.

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

  • 'A' * μετατόπιση + canary + rbp + ΔΙΕΥΘΥΝΣΗ + STOP -> χωρίς κατάρρευση

  • 'A' * μετατόπιση + canary + rbp + (ΔΙΕΥΘΥΝΣΗ + 0x6) + STOP -> χωρίς κατάρρευση

  • 'A' * μετατόπιση + canary + rbp + (ΔΙΕΥΘΥΝΣΗ + 0x10) + STOP -> χωρίς κατάρρευση

7. Εύρεση strcmp

Η συνάρτηση strcmp ορίζει τον καταχωρητή rdx στο μήκος του συγκρινόμενου συμβολοσειράς. Σημειώστε ότι το rdx είναι το τρίτο όρισμα και πρέπει να είναι μεγαλύτερο από 0 για να χρησιμοποιήσουμε αργότερα την write για να διαρρεύσουμε το πρόγραμμα.

Είναι δυνατόν να βρείτε τη θέση του strcmp στο PLT βασιζόμενοι στη συμπεριφορά του χρησιμοποιώντας το γεγονός ότι τώρα μπορούμε να ελέγξουμε τα 2 πρώτα ορίσματα των συναρτήσεων:

  • strcmp(<μη αναγνωσμένη διεύθυνση>, <μη αναγνωσμένη διεύθυνση>) -> κατάρρευση

  • strcmp(<μη αναγνωσμένη διεύθυνση>, <αναγνωσμένη διεύθυνση>) -> κατάρρευση

  • strcmp(<αναγνωσμένη διεύθυνση>, <μη αναγνωσμένη διεύθυνση>) -> κατάρρευση

  • strcmp(<αναγνωσμένη διεύθυνση>, <αναγνωσμένη διεύθυνση>) -> χωρίς κατάρρευση

Είναι δυνατόν να ελέγξετε αυτό καλώντας κάθε καταχώρηση του πίνακα PLT ή χρησιμοποιώντας τη

8. Εύρεση Write ή ισοδύναμου

Τέλος, απαιτείται ένα εργαλείο που εξάγει δεδομένα για να εξάγει το δυαδικό. Και αυτή τη στιγμή είναι δυνατόν να ελέγξουμε 2 ορίσματα και να ορίσουμε το rdx μεγαλύτερο από 0.

Υπάρχουν 3 κοινές συναρτήσεις που θα μπορούσαν να καταχραστούνται γι' αυτό:

  • puts(data)

  • dprintf(fd, data)

  • write(fd, data, len(data)

Ωστόσο, το αρχικό έγγραφο αναφέρει μόνο τη write, οπότε ας μιλήσουμε γι' αυτήν:

Το τρέχον πρόβλημα είναι ότι δεν γνωρίζουμε πού βρίσκεται η συνάρτηση write μέσα στο PLT και δεν γνωρίζουμε έναν αριθμό fd για να στείλουμε τα δεδομένα στο socket μας.

Ωστόσο, γνωρίζουμε πού βρίσκεται ο πίνακας PLT και είναι δυνατόν να βρούμε την write βασιζόμενοι στην συμπεριφορά της. Και μπορούμε να δημιουργήσουμε πολλαπλές συνδέσεις με τον εξυπηρετητή και να χρησιμοποιήσουμε ένα υψηλό FD ελπίζοντας ότι ταιριάζει με κάποια από τις συνδέσεις μας.

Υπογραφές συμπεριφοράς για την εύρεση αυτών των συναρτήσεων:

  • 'A' * offset + canary + rbp + (BROP + 0x9) + RIP + (BROP + 0x7) + p64(0) + p64(0) + (PLT + 0xb) + p64(ENTRY) + STOP -> Αν υπάρχουν εκτυπωμένα δεδομένα, τότε βρέθηκε το puts

  • 'A' * offset + canary + rbp + (BROP + 0x9) + FD + (BROP + 0x7) + RIP + p64(0x0) + (PLT + 0xb) + p64(ENTRY) + STOP -> Αν υπάρχουν εκτυπωμένα δεδομένα, τότε βρέθηκε το dprintf

  • 'A' * offset + canary + rbp + (BROP + 0x9) + RIP + (BROP + 0x7) + (RIP + 0x1) + p64(0x0) + (PLT + 0xb ) + p64(STRCMP ENTRY) + (BROP + 0x9) + FD + (BROP + 0x7) + RIP + p64(0x0) + (PLT + 0xb) + p64(ENTRY) + STOP -> Αν υπάρχουν εκτυπωμένα δεδομένα, τότε βρέθηκε η write

Αυτόματη Εκμετάλλευση

Αναφορές

Last updated