tea-cash

Published: March 20, 2026

Description

You've stumbled upon a mysterious cash register that doesn't keep money -- it keeps secrets in memory. Traverse the free list and find all the free chunks to get to the flag. Download: heapedit , heapedit.c , libc.so.6 .

Download heapedit, heapedit.c, and libc.so.6.

Read heapedit.c to understand the heap memory layout.

cat heapedit.c
chmod +x heapedit

Solution

  1. Step 1Read the source and understand the use-after-free
    Read heapedit.c to understand the heap layout. The program allocates a chunk for the flag and then frees it into the tcache, but the data remains in memory. This is a use-after-free: you can still access the freed flag chunk's data before it gets overwritten.
    cat heapedit.c
  2. Step 2Find the flag chunk in memory with GDB
    Use GDB with the provided libc to map the heap and locate the freed flag chunk. The flag data stays in the chunk's user data region until another allocation reuses it.
    LD_PRELOAD=./libc.so.6 gdb ./heapedit
    # In GDB: set breakpoints, run, inspect heap:
    break main
    run
    heap chunks
    # Find the freed chunk with flag data and note its heap offset
  3. Step 3Exploit the tcache UAF to read the flag
    The heapedit binary lets you write specific byte values at heap offsets. Use this to: (1) overwrite the tcache's fd pointer in the freed flag chunk to chain it to a target, or (2) simply allocate a chunk of the same size to reclaim the freed flag chunk and read its contents.
    python3 << 'EOF' from pwn import * p = remote("<HOST>", <PORT_FROM_INSTANCE>) # or: p = process(["./heapedit"], env={"LD_PRELOAD": "./libc.so.6"}) # From GDB analysis: find heap offset of freed flag chunk # The program prompts for byte offset and value to write # Write a value that reallocates the freed chunk or reads its data p.recvuntil(b"byte you want to edit: ") p.sendline(b"<OFFSET_FROM_GDB>") p.recvuntil(b"value: ") p.sendline(b"<VALUE>") print(p.recvall()) EOF

Flag

picoCTF{t34_c4sh_...}

tea-cash exploits a tcache use-after-free: the flag is stored in a freed heap chunk. By manipulating the tcache fd pointer with the heapedit interface, you reallocate the freed flag chunk and read its contents.