views:

777

answers:

5

How are buffer overflows used to exploit computers?

How is one able to execute arbitrary code simply by causing stack or heap overflows?

I understand that portions of the programs memory are overwritten that aren't supposed to be, but I don't see how this leads to one executing their own code. Also, must the 3rd party's malicious code be written in the target processors assembly language?

+11  A: 

This is the most widely known document on the subject: Smashing the Stack for Fun and Profit

However, 'stack overflows' have nothing to do with buffer overflows. Stack overflows are generally just an error case in bad code that can't be exploited for anything outside of a crash (DoS).

Edit: You also asked about heap overflows. This is a good document on the subject: http://www.w00w00.org/files/articles/heaptut.txt

Cody Brocious
Note that stack overflows can also be exploitable (e.g. by overwriting a return address on the stack). See e.g. http://stackoverflow.com/questions/286090/stack-overflow-exploit-in-c
sleske
+7  A: 

The stack contains both data and return address when you jump into a subroutine. If you manage to put a specific address on the stack where the return address is, you can force the CPU to jump to a particular memory location, the one where y ou put your own code. That's for buffer overflows. Heap overflows is a bit different and more difficult to exploit.

Stack overflows are just indication that you've run out of stack space (which is generally more limited, especially in the kernel).

Keltia
How would arbitrary code get loaded into the address space of the application though? If I remember my machine architecture classes right the CPU is designed to not execute anything in the data segment, to avoid security issues like this.
Cybis
Actually it's the operating system's job to ensure that data is not executed, and there may be vulnerabilities that can be exploited. Or you can just run the program's original code, but in the wrong sequence, perhaps simply getting it stuck in an infinite loop so it can't do the job it's supposed to.
Artelius
+1  A: 

The normal approach is that you have somewhere in memory the malicious code. Then you create a buffer overflow: the magic here is not to make it just overflow, but as you already mentioned, that certain parts of the program memory get overwritten. As the the stack contains not only the variables, but also when a function is called the return address, one tries to overwrite this one with the address of you malicious code. When the function with the buffer overflow returns to its caller, the function does not return to its original caller but instead to the malicious subroutine. As the now executed code has usally the privileges of the calling code, one tries to find/create this overflows in code which has higher permission than the evil code (else you could do it by directly calling the evil routine).

flolo
+5  A: 

Virtually all modern processors when calling a subroutine, pushes the return address on the same area as the local data(stack). For routines that doesn't check the upper limit of a variable(on particular the strcpy function), instruction address redirection(buffer overflow) can occur.

void make(char *me)
{
    char sandwich[4]; // local data, this is in stack.  the buffer for data is too small
    strcpy(sandwich, me);
    puts(sandwich);

    // implicit "return;" the return instruction(RET on Intel) instructs the processor to implicitly pop an address from stack then resume execution on that address
}

void main()
{
    // calling a subroutine (CALL on Intel) implicitly instructs the processor to push the next instruction's address(getchar line) on stack before jumping to make.
    make("Love Not War"); 
    getchar();

    puts("This will not execute.  The address to next instruction(getchar) gets overwritten with Not War");

}

"Also, must the 3rd party's malicious code be written in the target processors assembly language?" Yes

Stack overflow can occur from normally running program, example is recursive routines(function that calls itself) with overlooked terminating condition. The stack area will get filled with numerous local variables on stack plus the returning addresses.

Michael Buen
+5  A: 

Imagine two houses on the street. One is your friend's house and one is his evil paranoid neighbor's house three doors down. The evil paranoid neighbor never enters or leaves, and his place is locked up tight.

Now, your friend is such a good trusting friend, he'll let you store anything in his place, putting down boxes one after the other, starting at one wall. In fact, he's such a good friend that he'll keep putting down boxes one after the other, without checking to see if he's hit the wall, until they keep going in midair and finally pass right through two other houses on the street and into the evil paranoid neighbor's house. But your friend trusts you won't do that because he likes you (and he's a little naive).

So you have the opportunity to put something into the evil paranoid neighbor's house by exploiting your good trusting friend.


Replace the following terms and you'll see the analogy to a buffer overflow attack:

  • "your friend's house" --> "a portion of a program that doesn't check for buffer overflow"
  • "his evil paranoid neighbor's house" --> "another portion of a program that is supposed to be secure"
  • "boxes" --> "arguments/parameters to the program that doesn't check for buffer overflow"

This is successful only if someone figures out where the secure area of memory is, and what would have to be passed as an argument to the program in question, that would end up in the secure area, to have the desired effect. (whether it's data, or code that causes the exploiter's code to be executed)

Jason S