I want to exploit a stack based buffer overflow for education purposes.
There is a typical function called with a parameter from main, which is given as input from the program a local buffer where the parameter is saved. Given an input such that nops+shellcode+address_shellcode
, I will exploit it.
After debugging with gdb I found the address of the shell code as it will pass as a parameter, and right after the strcpy
I examine the stack and the $ebp+8
which is the return address has successfully overwritten with the address of the shell code. So I have what I want. But when I stepped forward the execution I got:
->shellcode_address in ?? ()
and then
Cannot find bound of current function
The return address has the value that I want. Any ideas what is happening?
Also when I execute it I got a segmentation fault and I have compile it with -g -fno-stack-protector
. Why?
The debugger has knowledge about where the code for functions in your program begin and end, either because this information is provided in debugging data or because it uses any external symbols visible in the executable to provide rudimentary information.
When the stack is in a proper state, it contains a return address to the calling function and, somewhere above that, a return address to a higher-level calling function, and so on. While you are executing various debugger commands, it uses these return addresses (and other information on the stack and in the state of the process) to show you the names of these functions. This requires looking up the return address in the debugger’s knowledge about where the functions are.
Once you overflow a buffer and corrupt the stack, the proper return address is destroyed. Instead you have a different address (one pointing to your shellcode if your exploit has worked). When the debugger tries to figure out which function this address is in, it fails, because the address is not in any of the functions in your program.
When this failure occurs, the debugger prints the error message you see.
Usually, the debugger can still perform basic functions: It can show you registers and memory in your program, it can still single-step and set breakpoints, and so on. It will have trouble doing things that require more complicated interpretation: It cannot figure out where stack frames are, it cannot find local variables by name, and so on.
Assuming your Linux distro is recent, and you work on an x86ish architecture, you can no longer execute shell code from user space memory (this also applies to other architectures, I'm just not as familiar with them). There are a number of reasons, in your case most likely the setting of the nx bit. Go to your Linux security man pages, and you will see a large number of security measures default-enabled; and google "smashing the stack for fun in 2011" for possible ways around it. Compiling with '-fno-stack-protector' only means not to set a canary value; but this isn't enough. If you want to do this for educational purposes, I suggest installing a VM like virtualbox, and an old distro on it.
You're executing code on the stack, and ask GDB what function you're in.
Obviously, GDB is confused, because you're not in any function. So it shows the address and "??"
You have to compile with -no-stack-protector, because stack-protector protects you from exactly what you're trying to do.
I'm not saying there's no way to bypass it, but it takes more effort and a good understanding of its protection mechanism.
Most likely you have a buffer overrun problem somewhere in the function
(or something like that). It overwrites the current stack frame of your function
with irrelevant data, and destroys the return address in the process, which is
normally stored there among other things. The result is that the code "returns"
to some unpredictable location and can't figure out where it is it returned to.
This is what causes the error message.