Sekai CTF 2025 - Learning OOP
Author: naup96321
analyze
This is one cpp pwn challenge.
1 | int main(int argc, char *argv[]) { |
It have four functions.
- new pet
- play pet
- feed pet
- rest pet
If you call new pet
This function allows the user to create a new pet.
And its object will store to pets[]
User can choose one of four animals: Dog, Cat, Parrot, or Horse.
1 |
|
The Animal
base class defines shared properties and behaviors for all pets, while each derived class overrides play(), eat(), and sleep() with species-specific behavior.
1 | class Animal { |
The update() function simulates the passage of time for all pets. Each call ages them and reduces their fullness. Pets die when either their fullness reaches 0 or they exceed their maximum age.
1 | void update() { |
attack
set_name
have heap overflow.
1 | void set_name() { |
First, let me know the chunk layout of the Animal object.
We can easily to control pc by hijack vtable.
1 | +---------------------------+ <-- chunk base (prev_size) |
And I want to try to leak libc.
we can overflow and overwrite the next chunk’s size.
Overwrite this chunk’s size to 0x481
, it will align the header of one of the chunks you create.
After you finish overwriting the chunk size and the pet dies, we can free it to place the chunk into the unsorted bin.
Then, by adding another animal, malloc will allocate a chunk from the unsorted bin, causing its fd and bk pointers to overwrite another animal’s chunk.
When this animal dies during update(), its name will be printed on the screen. Since its name now points into libc, we can use this to leak a libc address.
mov rdi, qword ptr [rax + 0x640] ; call qword ptr [rax + 0x638]
When we call the get_max_age() function from update(), rax contains the vtable address (the vtable pointer stored on the heap address).

So change vtable pointer on heap address + 0x638
to system
+ 0x640
to /bin/sh address
Create a fake vtable on the heap and set the get_max_age
pointer to point to my gadget
Then overwrite an animal’s vtable pointer to point to the fake vtable. When get_max_age() is called, it will execute system("/bin/sh")
.
However, currently rsp is not 16-byte aligned.
system
will call do_system

First, it will push r13
. Maybe we can pass this instruction and let rsp 16-byte aligned.

Get shell ~
exploit
1 | from pwn import * |
after all
More challenges will do it later~