function overwrite
Challenge
Story telling class 2/2 You can point to all kinds of things in C. Checkout our function pointers demo program. You can view source here. And connect with it using nc saturn.picoctf.net 55620
Solution
The program lets us input a string/story and then asks us for two numbers. The first number specifies the index of an array and the second number specifies the value to add at that array index. Crucially, only the upper bound of the array index is checked, which means we can go out of bounds and specify a negative number, thus allowing us to write to arbitrary memory locations. This is exactly what we did in PicoCTF 2019's L1im1tL355 challenge.
We are able to write to the array fun
:
Notice that the check
pointer is right above the fun
array. Therefore, that pointer will be the first thing we encounter when tracing backwards through memory with negative array indices. This is important because we will be able to set the check
pointer to easy_checker
instead of hard_checker
. easy_checker
calls the calculate_story_score
function and checks if the output is 1337
before printing the flag while hard_checker
checks for the value 1337
which is not obtainable because the program does not let us input enough characters.
The score is calculated by converting each character to an integer using ascii encoding and then taking the sum. With a little trial and error we see that aaaaaaaaaaaaa
will get a score of 1261
. So, we just need 1337-1261=76
more points. Looking at an ascii table, 76
corresponds to L
. So, we can use the string aaaaaaaaaaaaaL
to get a score of 1337
.
Now, we need to replace the check
pointer with easy_checker
's address. It currently points to hard_checker
's address and the value we specify will added to the current value. Therefore, we need to add the difference like so exe.symbols["easy_checker"] - exe.symbols["hard_checker"]
. This will subtract from hard_checker
the difference between easy_checker
and hard_checker
, thus making check
point to easy_checker
.
Finally, we just need to brute force the offset. Basically, we will trying writing the address delta to fun[-1]
and then to fun[-2]
etc until the flag is printed.
Fun the solution script.py to get the flag.
Flag
picoCTF{0v3rwrit1ng_P01nt3rs_529bfb38}
Last updated