pfs
By Razz
Use-after-free
Author: Rahul Razz
Date: September 30th, 2025
Difficulty: Easy
Operating System: Linux
Tags: Binary-Exploitaion, pwn.college
Memory
Memory comes in different types...
ELF .text: where the code lives
ELF .plt: where library function stubs live
ELF .got: where pointers to imported symbols live
ELF .bss: used for uninitialized global writable data (such as global arrays without initial values)
ELF .data: used for pre-initialized global writable data (such as global arrays with initial values)
ELF .rodata: used for global read-only data (such as string constants)
stack: local variables, temporary storage, call stack metadata
But what if you needed a place to store long-lived dynamic memory. Example: a variable-length list of NPCs in a game.
What if you needed dynamic memory allocation?
What if you needed dynamic memory allocation?
Answer to Question: One idea: mmap
Little bit history of Memory
We're not the first to have this idea:
General Purpose:
Doug Lea releases dlmalloc into public domain in 1987.
Linux:
ptmalloc (Posix Thread aware fork of dlmalloc)
FreeBSD:
jemalloc (also used in Firefox, Android)
Windows:
Segment Heap, NT Heap
What does the heap do?
The heap, as implemented by ptmalloc/glibc (and analogues), provides:
malloc() - allocate some memory
free() - free a prior allocated chunk
And some auxiliary functions:
realloc() - change the size of an allocation
calloc() - allocate and zero-out memory
These functions are used, extensively, by practically every single
non-trivial piece of software.
Our Program
`$ ./babyheap_level1.0
###
### Welcome to ./babyheap_level1.0!
###
This challenge allows you to perform various heap operations, some of which may involve the flag. Through this series of
challenges, you will become familiar with the concept of heap exploitation.
This challenge can manage up to 1 unique allocations.
[*] Function (malloc/free/puts/read_flag/quit):`
> We can do:
>> malloc
>> free
>> puts (to print the content of allocated chunk)
>> read_flag
``` Function (malloc/free/puts/read_flag/quit): read_flag
[*] flag_buffer = malloc(330)
[*] flag_buffer = 0x5592918542e0
[*] read the flag!
```
***Our aim is to read the flag_buffer***
Working of malloc and Free with Tcache
"Thread Local Caching" in ptmalloc, to speed up repeated (small) allocations in a single thread.
Implemented as a singly-linked list, with each thread having a list header for different-sized allocations.
```
typedef struct tcache_perthread_struct
{
char counts[TCACHE_MAX_BINS];
tcache_entry *entries[TCACHE_MAX_BINS];
} tcache_perthread_struct;
typedef struct tcache_entry
{
struct tcache_entry *next;
struct tcache_perthread_struct *key;
} tcache_entry;
```
Flow of Our Exploit
1.