8

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?

Mogsdad
  • 40,814
  • 19
  • 140
  • 246
curious
  • 1,422
  • 5
  • 20
  • 43
  • Take a look at http://stackoverflow.com/questions/2420813/using-gdb-to-single-step-assembly-code-outside-specified-executable-causes-error, it explains that "Cannot find bounds of current function" just means gdb doesn't have debug info for the current instruction pointer, and that it's unhappy with this state of affairs. But you probably have another problem in addition to that. – Steve Jessop Jan 05 '12 at 11:30
  • How could i add debug info for the nop instruction, which is followed by other nops and in the end with shellcode? – curious Jan 05 '12 at 11:52
  • I don't know exactly how gdb works, but I expect you can't. gdb looks up the address of the instruction pointer in its big old table of debug info, that it has loaded from the executables it knows about. But the instruction pointer is on the stack, it's not covered by any debug info. Maybe in theory you could synthesize some DWARF data around the current stack address, and load that into gdb, but I've no idea how. – Steve Jessop Jan 05 '12 at 12:01
  • I don't think so. It a simple stack based buffer overflow exploit. I am missing sth else – curious Jan 05 '12 at 12:32

5 Answers5

8

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.

Eric Postpischil
  • 141,624
  • 10
  • 138
  • 247
3

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.

Viswesn
  • 4,030
  • 1
  • 26
  • 38
1

You corrupt the register with the function return address. Return address is now illegal and the debugger cannot access it. Ergo the message.

Nibal
  • 11
  • 1
1

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.

ugoren
  • 15,127
  • 2
  • 28
  • 59
  • Why i am not in any function? I am inside myfunction which has been called by main.And i changed the ret address of myfunction with an address at the stack where the nops are and the shellcode.I am compiling with -fno-stack-protector.I have already mentioned that. – curious Jan 05 '12 at 16:14
  • Once you have changed the return address to the shellcode, and the return operation jumped there, you're in the shellcode, not in any function. I thought you were asking why you need to compile with no-stack-protector, and answered. – ugoren Jan 05 '12 at 17:39
  • There is no other way as far as i know to spawn the shell other than overwrite the ret adress with the address of the shellcode preceding nops instructions.Am i wrong? – curious Jan 05 '12 at 17:41
  • There are many ways. You can vary the location of the shellcode - the stack, the heap, or even use existing libc code ("jump to libc"). You can also use different methods to jump to it - overrun a function pointer, the VFT (in C++), malloc control structures. And the code you jump to can vary a lot. And a serious hacker could add much much more. – ugoren Jan 05 '12 at 19:51
  • I wanted to pass it just as an input argument to the prog which would be the parameter to the vulnerable function – curious Jan 05 '12 at 20:06
  • Who voted this down and why? This is the only answer so far that addresses the message that appears to be from the debugger, “Cannot find bound of current function”. This answer fits the observed behavior: the buffer overflow has corrupted data that the debugger uses to interpret the stack and determine what function is being executed. This corruption results in the debugger being unable to do its job and displaying the error message. – Eric Postpischil Feb 06 '14 at 18:53
0

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.

gnometorule
  • 2,091
  • 2
  • 19
  • 28
  • This could explain why attempting to execute improper code could get an access violation. How does it explain the message “Cannot find bound of current function”, which is apparently a message from the debugger? – Eric Postpischil Feb 06 '14 at 18:51