Attachments : chall , main.cpp
So, this was an interesting challenge on CPP pwn from Cake CTF. This was the first time I tried my hands on cpp pwning.
First of all, let’s have a look on the security features
1 | Arch: amd64-64-little |
Partial RELRO and No PIE! Interesting.
Analyzing the source code of this challenge, we can easily spot a buffer overflow.
1 |
|
So, the program is reading data into _c_str
without any size check which can be used to cause a buffer overflow.
Now, let’s drop the binary in gdb and add some random data.
Interesting. It is clear that std::string
is stored in the heap and a pointer to that chunk is stored at 0x7fffffffdd20
, just after the buffer _c_str
. User data will be read into that chunk whenever std::cin>>test.str();
is called. We can use the buffer overflow on _c_str
to replace the pointer to a heap chunk with a GOT address. After that, calling std::cin>>test.str();
would read user supplied data into that particular GOT address. One suitable GOT entry is _ZStlsIcSt11char_trait@GLIBCXX_3.4.21
i.e 0x404040
. This will be executed whenever std::cout << "str: " << test.str() << std::endl;
is called i.e option 4.
Now, let’s perform a GOT overwrite to make the pointer at 0x404040
point to Test::call_me
i.e 0x4016de
.
1 | #!/usr/bin/env python3 |
References
https://ptr-yudai.hatenablog.com/entry/2021/11/30/235732
https://www.slideshare.net/AngelBoy1/pwning-in-c-basic