I am trying to exploit a stack based overflow vulnerability. All the examples I can find make use of a ret address though. The buffer overflow I found is inside the main function, and I cannot find any examples on how to do this.

The code looks like this:

int main(){
   while (1){
   //some code
      switch() {
         case 0:
         char id[128];
         sscanf(buffer,"%s", id);

The contents of buffer are controlled by the user.

closed as too broad by RoraΖ, schroeder, Eric G, ThoriumBR, D.W. Apr 21 '15 at 21:55

Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer. Avoid asking multiple distinct questions at once. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • 3
    What have you tried so far? Have you gotten a segfault? What exactly are you having trouble with? – RoraΖ Apr 21 '15 at 12:55
  • Yes. I managed to get a segfault, i know at how many bytes it segfaults. Than I looked up where my buffer was stored, and added that address reversed to the end of the payload. But than it just segfaults. All the examples i can find online are about returning from a function, and since this is all in the same function, that never happends here. How do I go about executing a payload when it does not return from a function? – Noah Goldsmid Apr 21 '15 at 13:13
  • That's a pretty broad question. It depends on where your overflow is writing to, and what system you're targeting. Not all buffer overflows are exploitable. – RoraΖ Apr 21 '15 at 14:40
  • I can only find examples and information about exploiting buffer overflows in a function call. Could you maybe point me to some information or examples about exploiting an iverflow thats inside the main function? – Noah Goldsmid Apr 21 '15 at 14:55
  • I had a look at the same a while back and couldn't work out how to exploit a stack overflow on main. It does depend what other code is in that loop though, and other local variables. – paj28 Apr 21 '15 at 18:10

You've run into the hardest part of exploiting a buffer overflow: determining how to get the code to execute. Injecting code is trivial once you've found the vulnerability, but getting the CPU to start executing that code, not so much.

Without a strong understanding of stack frame layout, you will find the rest difficult to follow.

One point of note is that in C, main, from the process's viewpoint, is just another function that is called (this is different in C++ see comment below). While you think of it as the beginning of execution, to the CPU it is a full function call with a return address on the stack. So exploiting a flaw in main is the same as exploiting a flaw in any other function.

As an attacker, all you can do with a buffer overflow is write to the data section of the process, you need to find a way to have the process read something from data that controls what will be executed. Basically, you need a place in data memory where the process will look to determine what should be executed next (ie: to determine the value of the program counter or PC).

The most common type of locations in data memory that affects the PC are a function's return pointer. When returning from a function, the CPU will read the return pointer off of the stack and set the PC to it (or the instruction after it - details CPU dependent). Unless you return from the main function it is very unlikely that you'll execute a successful attack. You'll need some place in data, preferably on the heap, where the processor will read data that is used to set the PC.

The other "common" (tho much less common) places in data memory that are used to exploit a buffer overflow attack are function pointers followed by a function call, and exception tables followed by an exception. Neither of these seem applicable to your application. So you probably have a non-exploitable stack buffer overflow vulnerability. The worst I suspect that you can do is crash your app.

The steps the attacker needs to take for a standard stack buffer overflow exploitation are:

  1. Identify stack buffer overflow vulnerability.
  2. Determine address of stack at time of vulnerability.
  3. Determine address of function return pointer in current stack frame.
  4. Write code (frequently called shellcode) for attack.
  5. Create input that loads code and modifies function return pointer to point to shellcode on stack.

So now that you've found the vulnerability, you need to determine the stack address for call to main. The easiest way to do this is to print the address of id. Next, the return pointer's location. This is likely two words lower in memory than id. Something like (char *)id-2*sizeof(int).

The next step is to write your shellcode. I'd suggest you create a function in your program that prints the string "attack successful" and then exits. Make your shellcode a call to this function.

Now sit down and layout the data on the stack (this stack frame layout reference should help) including a return address jumping to your id variable's buffer. Convert the stack data to ASCII and input it to the program.

This page has a more concrete example of what I've described.

  • You should state that your analysis is done for the C language (only). In C++, main can't be referred to by the program, so the compiler can choose to jump directly to cleanup code rather than actually returning from main. (In C, the compiler can do the same if it can prove the program doesn't call main explicitly) – Ben Voigt Apr 21 '15 at 18:31
  • Note that in my case it never returns from main. It stays in a while(1) loop. As far as I understand overflows, I can only overwrite local variables in this case. Is this correct? – Noah Goldsmid Apr 21 '15 at 20:24
  • Ahh. Good point @NoahGoldsmid. I don't think this example is exploitable.I updated my answer to reflect this. – Neil Smithline Apr 21 '15 at 20:54
  • To what location is that break in a case jumping to? How can you overwrite that address? – ott-- Apr 21 '15 at 21:25
  • You can't @ott--. The break will jump to an address compiled into the code. You need to attack function return pointers and exception tables because they contain code addresses that are written into the data portion of the process; the only part of the process that can be modified at runtime. – Neil Smithline Apr 21 '15 at 21:29

Not the answer you're looking for? Browse other questions tagged or ask your own question.