ITSEC Summit CTF 2025 - MyKisah [WRITE UP]
This is a National CTF Challenge, I only solved one because the baby is heap, easy is qemu escape 💀, medium and hard are windows pwn 🤮
Pwn - MyKisah
Introduction

Source Code
There is no source code, but this is the result of ChatGPT beautifying the code from the decompiler
1 |
|
Summary
Use get_idx to allocate beyond idx and gain arbitrary write, then leak libc by overwriting header chunk and free it to unsorted bins. After that, overwrite tls cookie to 0 and init to system and binsh then call exit to get shell
Solution
Given a binary file called MyKisah with a Dockerfile, I first grabbed libc and ld to patch with pwninit. After patching, I ran it and was presented with a menu with five options.

- Buat sesi nge-halu will
malloc(0x1e0)with chunk[0] = duration, chunk[1] = snooze, the title variable is thetitlevariable, the chunk address is thealarmvariable, and only 3 idx values can be entered. - Masuki dunia halu will
free(chunk)and set null in thetitlebut not in thealarm. - Edit sesi halu will ask the same input as option 1, but only change the
mallocvalue. - Cek jadwal halu will display the contents of the input.
- Bangun dari mimpi will call
exit.
The vulnerability in this program lies in the request for the index input.
1 | ssize_t get_idx() |
When requesting the index, it checks whether the bottom byte contains a null byte. If so, it returns a read result with the length of the input. This way, we can allocate up to the length of the input, which is 8 chunks.
Next, we can see that the structure of the title and alarm only stores 4 chunks.

If we allocate title at idx 4, it will overwrite the idx 0 pointer, allowing us to perform arbitrary writes.
1 | def write(where, what): |
Now we just need to leak the address. For the heap, simply allocate from the back and display idx 4.
1 | for i in reversed(range(9)): |
To leak the libc address, we can create a pointer to the heap header and overwrite it to size 0x5d1. When we free it, it will go to the unsorted bins.
1 | write(heap+0x298, 0x5d1) # pointer chunk 0 - 0x8 |
Before writing:
After writing:
Now we just need to get rip to get a shell. I used a technique from WWWW2Exec that gets a shell by overwriting a mangled exit. To find the init address, simply break in ``exit and view the contents of [rsi].

For the cookie, use the tls command in gef and view the PTR_MANGLE cookie and the overwritten location.

So, just overwrite tls cookie exit + 24 with system and the string to /bin/sh.
1 | write(cookie, 0) |
After that, just select option 5 and get the shell.

Solve Script
1 | #!/usr/bin/env python3 |
Flag
ITSEC{Rintaro-kun_watashi_wa_Waguri_Kauruko_desu,_soshite_anata_wa_Tsumigi_Rintaro_desu}