$ cat writeup.md…
$ cat writeup.md…
hackthebox
Task: A hardened PIE binary with Full RELRO, NX, Canary, and a heap message editor that allows unchecked byte writes by user-controlled offset. Solution: Leak libc through unsorted-bin metadata, recover the safe-linking key from a freed tcache chunk, poison tcache to land on environ, leak the stack, and return into a ret2libc ROP chain.
$ cat /etc/rate-limit
Rate limit reached (20 reads/hour per IP). Showing preview only — full content returns at the next hour roll-over.
No original organizer description was preserved in the task files.
The binary lets us create, save, revisit, and edit heap-backed messages. Despite strong mitigations and a modern provided glibc 2.41, one unchecked byte-write primitive is enough to build a full heap-to-stack exploitation chain.
challenge/funkynatorchallenge/glibc/libc.so.6The vulnerability is in process_message().
puts("please give the offset of the byte:"); size_t offset; scanf("%lu", &offset); ... message[offset] = (char)value;
offset is read as an unsigned long and never validated, so the menu option overwrite byte becomes an arbitrary relative one-byte write from the current heap chunk. That lets us:
fd pointers.funkify() only changes alphabetic characters to alternating case. Non-alphabetic bytes are left untouched, so heap metadata, pointer bytes, and ROP payload bytes survive as long as we avoid alphabetic characters where needed.
The initial plan was a House of Apple 2 / _IO_list_all attack. That line of attack was abandoned for a good reason:
_IO_list_all did not trigger code execution._IO_list_all with a sentinel like 0xdeadbeef still produced a normal exit.Instead of forcing FSOP further, the successful exploit pivoted completely to a more direct path: libc leak -> safe-linking key leak -> tcache poison -> environ leak -> stack ROP.
...
$ grep --similar