$ cat writeup.md…
$ cat writeup.md…
tjctf
Task: glibc 2.34 PIE binary leaks heap FILE* and puts@libc, then overwrites first 0x78 bytes of the FILE before calling fread; a prevent_fsop() check guards _wide_data and vtable. Solution: double FSOP — stage 1 forges FILE so fread's __underflow reads 0x200 bytes from stdin into the FILE itself, stage 2 sends a full House of Apple 2 layout that triggers system(\" sh\") via _IO_wfile_overflow → _IO_wdoallocbuf → fake wide vtable __doallocate on exit.
$ cat /etc/rate-limit
Rate limit reached (20 reads/hour per IP). Showing preview only — full content returns at the next hour roll-over.
I'm trying to test my FSOP prevention mechanism...
We are given a 64-bit PIE ELF binary (Ox78), the matching libc.so.6 (Ubuntu glibc 2.34), ld-linux-x86-64.so.2, and a Dockerfile. The remote is at nc tjc.tf 31378.
The binary has Full RELRO, PIE, NX, SHSTK, IBT — no canary, but all modern mitigations are on. With glibc 2.34, __free_hook and __malloc_hook are removed, so the only viable code-execution primitive is FSOP (File Stream Oriented Programming).
The challenge name "Ox78" is a hint: 0x78 is the number of bytes we can write into the FILE structure.
FILE *fp; // global void create_test_file() { umask(0); int fd = open("/tmp/test.txt", 0); close(fd); } void Ox78() { create_test_file(); char *testbuf = malloc(0x78); fp = fopen("/tmp/test.txt", "r"); printf("I'm trying to test my FSOP prevention mechanism...\n"); printf("Here's the address of the File Structure: 0x%llx\n", fp); void *puts_addr = /* resolved puts from GOT */; printf("I'm pretty confident you can't break out of this, " "so I'll give you a libc leak as well: %p\n", puts_addr); read(0, fp, 0x78); // ← THE VULNERABILITY prevent_fsop(); fread(testbuf, 1, 0x78, fp); prevent_fsop(); } int main() { setvbuf(stdin, NULL, _IONBF, 0); setvbuf(stdout, NULL, _IONBF, 0); Ox78(); return 0; }
FILE structure on the heapread(0, fp, 0x78) writes 0x78 bytes directly into the FILE structure from stdin. This lets us control all fields from offset 0x00 through 0x77:
...
$ grep --similar