This code contains a use-after-free (UAF) vulnerability, which is a type of memory corruption issue. Here’s a breakdown of the vulnerability:
Key Points of the Vulnerability:
xis Freed but Still Used- The
init()function allocates memory forxand initializes itsflagfield with"bico". - The
free_memory()function (option 5) freesxusingfree(x), but does not setxtoNULL. - After freeing,
xbecomes a dangling pointer, meaning it still points to the freed memory.
- The
- Use of Freed Memory
- Even after
xis freed, the program continues to use it in:print_heap()(option 1) → Accessesx->flag.- Option 3 → Prints
x->flag. check_win()(option 4) → Checksx->flagfor the value"pico".
- Even after
- Allocation Control via
alloc_object()(Option 2)- This function allows the user to allocate a chunk of arbitrary size and write data into it.
- If the newly allocated chunk occupies the same memory previously used by
x, the attacker can overwritex->flagwith"pico"to trigger the win condition.
Exploitation Steps:
- Free
x(Option 5) → Makesxa dangling pointer. - Allocate a new chunk (Option 2) with a size matching
sizeof(object)(which is 35 bytes:10+10+10+5).- Due to heap management (e.g., glibc’s
malloc), this new allocation may reuse the freedx’s memory.
- Due to heap management (e.g., glibc’s
- Write
"pico"into the new allocation → Overwritesx->flag. - Call
check_win()(Option 4) → Sincex->flagis now"pico", the program prints the flag.
✗ heap3 (black@d4rk-pr0xy) ⇝ nc tethys.picoctf.net 65429
freed but still in use
now memory untracked
do you smell the bug?
1. Print Heap
2. Allocate object
3. Print x->flag
4. Check for win
5. Free x
6. Exit
Enter your choice: 5
1. Print Heap
2. Allocate object
3. Print x->flag
4. Check for win
5. Free x
6. Exit
Enter your choice: 2
Size of object allocation: 35
Data for flag: qwertyuiopasdfghjklzxcvbnm1234pico
1. Print Heap
2. Allocate object
3. Print x->flag
4. Check for win
5. Free x
6. Exit
Enter your choice: 3
x = pico
1. Print Heap
2. Allocate object
3. Print x->flag
4. Check for win
5. Free x
6. Exit
Enter your choice: 4
YOU WIN!!11!!
picoCTF{now_thats**************}
Why This Works:
- After
free(x), the memory is returned to the heap manager but not zeroed out. - If a new allocation occupies the same space,
x->flagcan be controlled by user input. - The
check_win()function comparesx->flagwith"pico", allowing an attacker to manipulate it.
Mitigation:
- Nullify the pointer after freeing:
void free_memory() { free(x); x = NULL; // Prevent UAF } - Use-after-free detectors (e.g., AddressSanitizer).
- Avoid accessing freed memory by ensuring pointers are invalidated after
free().
This is a classic heap-based use-after-free bug that can lead to arbitrary code execution or, in this case, a fake win condition bypass.