You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This challenge is pretty cool. It's main point is to show you that sometimes even even with an overwrite of a single byte (which is not even a return address), you can still achieve arbitrary code execution. Below is the step by step walkthrough on how to spawn /bin/sh in this exercise
The first thing to notice here is that you can only overwrite a single (least significant) byte of previous function EBP register stored on stack. By playing around with the total size of ExploitEducation environment variable (possibly could also work if you played with other environment variables instead), you can adjust the stack location in such a way that the new 'patched' EBP value stored on stack points to the region in stack which is controlled by you
If all we can do is to change the EBP value that belongs to the previous function, we need to look at it and see how does this influence its flow. Looking at main code just after the vulnerable greet returns :
So in theory, if we could cause EBP - 4 to point a memory address, just above which is yet another pointer to our shellcode, we could make the ret command to jump to it. So all we need to do is to play around with ExploitEducation to have our shell code + the mentioned above pointers + override the one byte of stored EBP value of main . Right ? Wrong !
Notice the call to puts before reaching the interesting opcodes where our games with pointer to pointer causes ret to jump to our shellcode. Since the area in stack where our shellcode is stored (thanks to buggy strncpy in greet ) is considered to be free and available by the main function, it overrides almost all of it in that puts call ... :(
So what can be done ? So first of all, after playing a bit with debugger we discover that some values in that stack are left intact after all. After some experiments we can find a couple of addresses which we can use to store that first pointer to which we can safely point our overridden EBP.
But where that first pointer shall point ? The bytes in stack, that are not ruined by that puts call are not enough to store our shellcode ... Well luckily that strdup at the end of greet call comes to our rescue ! Our whole buffer with the shellcode is preserved inside the heap ! So we can point that pointer to an address in heap where the shellcode can be found ! Luckily for us the allocated heap address is always the same in this exercise ....
The first pointer that points to an address in HEAP where the second pointer is stored (duplicated a couple of times just in case)
The second pointer that points to our shellcode in HEAP (again duplicated and surrounded by NOPs)
The shellcode
The least significant byte of mainEBP register stored on stack overridden in such a way that it points to a first pointer
Additional bytes that do not get copied and do not participate in the exploit, but cause the stack to get adjusted in such a way that last overridden byte of EBP can be used to point to a region controlled by us (otherwise it can only point to higher addresses which are not controlled by us)