Description
Can you control your overflow?
Setup
Connect to the remote instance at tethys.picoctf.net <PORT_FROM_INSTANCE>.
Explore the menu options; they mirror heap0 (print/write/inspect safe_var/print flag).
nc tethys.picoctf.net <PORT_FROM_INSTANCE>Solution
- Step 1Write up to the boundaryThe buffer still sits 32 bytes before safe_var. Write exactly 32 filler characters (e.g., A) so the next four bytes overwrite safe_var itself.
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALearn more
This step advances beyond heap-0 by requiring controlled overwrite rather than just a null byte. The challenge now checks that
safe_varequals a specific string value ("pico"), not just that it's zero. This means you need to write exactly the right bytes at exactly the right position - a more precise exercise in heap overflow control.The 32-byte filler positions your subsequent bytes directly over
safe_var. Precision matters: one byte too few andsafe_varis untouched; one byte too many (with the wrong content) corrupts it to the wrong value. This "measure twice, write once" discipline is essential in exploit development, where imprecise overflows often cause crashes instead of code execution.In real heap exploits targeting metadata (like the allocator's free list pointer or size field), the offset from the overflow buffer to the target is determined by understanding the allocator's chunk layout. Tools like
pwndbg'sheapcommand visualize chunk layout in gdb, making it easier to measure these offsets dynamically. - Step 2Append the magic stringAppend pico immediately after the 32-byte filler when using menu option 2. The null terminator follows pico, leaving safe_var == "pico".
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApicoLearn more
The string
"pico"is 4 bytes:p=0x70,i=0x69,c=0x63,o=0x6f. These 4 bytes, written starting at the 33rd position, overwritesafe_varwith exactly the right value. The null terminator fromfgetsfollows at position 37, which either lands in the next heap chunk (harmlessly) or terminates the string naturally.This illustrates controlled heap overflow: you write a chosen value (not just zeros or garbage) to an adjacent heap object. In real exploits, controlled overwrites target function pointers (to redirect execution), heap freelist pointers (to enable arbitrary allocation), or security-critical flags (as here). The technique scales from simple guard variables to complex heap management structures.
The 36-character total payload (
A*32 + "pico") fits within a reasonable input buffer size. If the input function's size limit were only 32 bytes, this attack would be impossible - which is why proper input length validation must account for all adjacent data that could be affected, not just the buffer itself.Heap spraying is a related technique used in browser exploits: instead of precise single-object overwrites, the attacker fills the heap with many copies of a payload, hoping that some natural allocation lands in the sprayed region and gets mistaken for a valid pointer or object. The precision required here (exact offset, exact value) contrasts with the brute-force nature of spraying.
- Step 3Print the flagOnce safe_var contains pico, selecting option 4 prints the flag without further tricks.Use option 3 first if you want to confirm safe_var now shows pico, then call option 4.
Learn more
Using option 3 to verify the write before triggering the reward is good exploit development practice. Confirming intermediate state before proceeding helps isolate failures: if the flag doesn't print, you know whether the problem is the overflow payload or the flag-printing logic itself.
This two-step approach (write → verify → trigger) mirrors professional exploit development, where each stage is tested independently. In complex exploit chains with multiple vulnerabilities chained together (info leak → bypass ASLR → overflow → code execution), verifying each step prevents wasted time debugging the wrong stage.
The progression from heap-0 (zero any value), to heap-1 (write a specific value), to heap-2 (write a function pointer), to heap-3 (use-after-free) represents the learning ladder of heap exploitation. Each challenge adds one new concept: precision control, address knowledge, memory lifecycle awareness. Professional heap exploitation combines all of these plus allocator internals, making it one of the most technically demanding areas of binary exploitation.
Flag
picoCTF{starting_to_get_the_hang_c58...}
As soon as safe_var == pico, option 4 prints the flag shown above.