I tried to exploit the following code but without succes. I tried an input of 60 + 1 characters but it didn't work.
CFI using labels is enabled. Stack canaries, non-executable stack and ASLR are disabled. Can you make the program print "You won!\n"? (suppose isAdmin is a global variable instead of a variable defined in main(). Is it still possible to exploit the code?)
void g() {
char buff[60];
gets(buff);
}
void main() {
int isAdmin = 1;
g();
isAdmin = 0;
g();
if (isAdmin) { printf("You won!\n"); }
}
That simple it won't work!
It first depends on if the stack is growing top down or bottom up. With the latter you won't be able at all to overwrite variables on stack of the calling function, they reside in front of the array.
With the latter (admitted, the far more common variant), you might manage successfully to overwrite the isAdmin
variable. However, when calling a function, there's quite a bit of data reserved on stack, at very, very least, you'll find the return address there. And that one will be overwritten, too! So your programme would continue, or better: try to continue, at some arbitrary address in memory. The most likely result is a crash of your programme.
So your only realistic chance is inlining the function, e. g. with GCC:
inline void g() __attribute__((always_inline));
void g()
{
char buff[64];
gets(buff);
}
Be aware that this is not portable code, the __attribute__
annotation is GCC (and clang) specific.
That way, I indeed managed to produce your desired result (still requiring a top down stack!). You might need to provide quite a number of extra bytes, alignment issues might enforce quite some gaps in between the variables. However, depending on how much data you overwrite, you might still produce a crash (possibly before any output is produced).
In any case, you are far in the land of undefined behaviour, so there is absolutely no guarantee that you really get what you want, anything might happen instead.