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. 1.