views:

1518

answers:

11

I have heard about a buffer overflow and I would like to know how to cause one.

Can someone show me a small buffer overflow example? New(And what they are used for?)

+10  A: 

A buffer overflow is just writing past the end of a buffer:

int main(int argc, const char* argv[])
{
    char buf[10];
    memset(buf, 0, 11);
    return 0;
}
Tim Lesher
A: 

In this context, a buffer is a portion of memory set aside for a particular purpose, and a buffer overflow is what happens when a write operation into the buffer keeps going past the end (writing into memory which has a different purpose). This is always a bug.

A buffer overflow attack is one which uses this bug to accomplish something that the program's author didn't intend to be possible.

dmckee
+15  A: 

A buffer overflow is basically when an created section (or buffer) of memory is written outside of its intended bounds. If an attacker can manage to make this happen from outside of a program it can cause security problems as it could potentially allow them to manipulate arbitrary memory locations, although many modern OS protect against the worst cases of this.

While both reading and writing outside of the indented bounds are generally considered a bad idea, the term buffer overflow is generally reserved for writing outside the bounds, as this can cause an attacker to easily modify the way your code runs. There is a good article on wikipedia about buffer overflows and the various ways then can be used for exploits.

In terms of how you could program one yourself, it would be a simple matter of

char a[4];
strcpy(a,"a string longer than 4 characters"); // write past end of buffer (buffer overflow)
printf("%s\n",a[6]); // read past end of buffer (also not a good idea)

Whether that compiles and what happens when it runs would probably depend on your operating system and compiler.

David Dean
Buffer overflows are usually more destructive when you're writing beyond the end of a buffer rather than reading [e.g., char x[2]; strcpy (x,"hello");] - this is because it frequently stuffs up many other variables and/or the stack frame.
paxdiablo
Don't have have to write past the bounds of the array for it to be considered a buffer overflow? In that case I think an example that changes the contents at a[200] would be better.
MahlerFive
@david if you read the first paragraph of wikipedia's article that you cite, a buffer overflow only happen when you 'write' outside the bounds of a buffer, your sample is *not* a proper buffer overflow.
Ismael
thanks, changed answer to reflect distinction on read/write
David Dean
That still isn't a buffer overflow. a is a pointer to a string, and the 2nd line is simply changing that reference. Plus, a is an array so it's not even a valid l-value and you're code won't compile. A fool-proof example would be strcpy(a, "a string longer than 4 characters");
wj32
gah! fixed again.
David Dean
+1  A: 

This should be enought to reproduce it:

void buffer_overflow() 
{
    char * foo = "foo";
    char buffer[10];

    for(int it = 0; it < 1000; it++) {
        buffer[it] = '*';
    }

    char accessViolation = foo[0];
}
alex2k8
+5  A: 

In addition to what has already been said, keep in mind that you'r program may or may not "crash" when a buffer overflow occurs. It should crash, and you should hope it does - but if the buffer overflow "overflows" into another address that your application has also allocated - your application may appear to operate normally for a longer period of time.

If you are using a later edition of Microsoft Visual Studio - I would suggest using the new secure counterparts in the stdlib, such as sprintf_s insted of sprintf, ect...

NTDLS
There is also `snprintf`, which has the advantage of being standardized (ISO C 99). There's also `asprintf` (GNU and BSD libc), `g_strdup_printf` (Glib).
sleske
+17  A: 

Classical example of a buffer-overflow:

// noone will ever have the time to type more than 64 characters...
char buf[64];
gets(buf); // let user put his name

The buffer overflow alone does most often not happen purposely. It happens most often because of a so-called "off-by-one" error. Meaning you have mis-calculated the array-size by one - maybe because you forgot to account for a terminating null character, or because some other stuff.

But it can also be used for some evil stuff. Indeed, the user long knew this hole, and then inserts say 70 characters, with the last ones containing some special bytes which overwrite some stack-slot - if the user is really tricky he/she will hit the return-address slot in the stack, and overwrites it so it jumps forward into that just inserted buffer: Because what the user entered was not his name, but his shell-code that he previously compiled and dumped out. That one will then just executed. There are some problems. For example, you have to arrange not to have a "\n" in that binary code (because gets would stop reading there). For other ways that mess with dangerous string functions, the binary zero is problematic because string functions stop copying there to the buffer. People have used xor with two times the same value to produce a zero too, without writing a zero byte explicitly.

That's the classic way of doing it. But there are some security blocks that can tell that such things happened and other stuff that make the stack non-executable. But i guess there are way better tricks than i just explained. Some assembler guy could probably now tell you long stories about that :)

How to avoid it

Always use functions that take a maximal-length argument too, if you are not 100% sure that a buffer is really large enough. Don't play such games as "oh, the number will not exceed 5 characters" - it will fail some day. Remember that one rocket where scientists said that the number will not exceed some magnitude, because the rocket would never be that fast. But some day, it was actually faster, and what resulted was an integer overflow and the rocket crashed (it's about a bug in Ariane 5, one of the most expensive Computer bugs in history).

For example, instead of gets use fgets. And instead of sprintf use snprintf where suitable and available (or just the C++ style things like istream and stuff)

Johannes Schaub - litb
Buffer overflow = buffer overrun?
Ahmed Said
i haven't know the latter term. wikipedia seem to say they mean the same.
Johannes Schaub - litb
A: 

(Flagged for deletion)

When StackOverflow becomes the top result for your Google search, this answer will be useless.
Darron
Come on... questions that google/wikipedia can answer really should not be posted.
@rbobby: There is a long-standing rule on StackOverflow that "Google it" is not an acceptable answer. You can be upset and think that StackOverflow is stupid for having that rule, but it's there all the same.
Omnifarious
+1  A: 

The "classic" buffer overflow example is:

int main(int argc, char *argv[])
{
    char buffer[10];
    strcpy(buffer, argv[1]);
}

That lets you play with the buffer overflow parameters and tweak them to your hearts content. The book "Hacking - The Art of Exploitation" (Link goes to Amazon) goes into great detail about how to play around with buffer overflows (purely as an intellectual exercise obviously).

Larry Osterman
A: 

With the correct answers given: To get more into this topic, you might want to listen to the Podcast Security Now. In Episode 39 (a while back) they discussed this in depth. This is a quick way to get a deeper understanding without requiring to digest a whole book.

(At the link you'll find the archive with multiple size versions as well as a transcript, if you're rather visually oriented). Audio is not the perfect medium for this topic but Steve is working wonders to deal with this.

Olaf
+1  A: 

If you want to check you program for buffer overflows, you could run it with tools like Valgrind. They will find some memory management bugs for you.

abababa22
A: 

Hacklord, about your question which is closed (this about check for default browser) Please check following keys in registry (Windows):

==========================================================
REGEDIT4

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\.shtml]
@="FirefoxHTML"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\.xht]
@="FirefoxHTML"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\.xhtm]
@="FirefoxHTML"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\.xhtml]
@="FirefoxHTML"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\.htm]
@="FirefoxHTML"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\.html]
@="FirefoxHTML"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\FirefoxHTML\DefaultIcon]
@="C:\\PROGRA~1\\MOZILL~1\\FIREFOX.EXE,1"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\FirefoxHTML\shell\open\command]
@="C:\\PROGRA~1\\MOZILL~1\\FIREFOX.EXE -url \"%1\""

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\ftp\DefaultIcon]
@="C:\\PROGRA~1\\MOZILL~1\\FIREFOX.EXE,1"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\ftp\shell\open\command]
@="C:\\PROGRA~1\\MOZILL~1\\FIREFOX.EXE -url \"%1\""

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\gopher\DefaultIcon]
@="C:\\PROGRA~1\\MOZILL~1\\FIREFOX.EXE,1"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\gopher\shell\open\command]
@="C:\\PROGRA~1\\MOZILL~1\\FIREFOX.EXE -url \"%1\""

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\http\DefaultIcon]
@="C:\\PROGRA~1\\MOZILL~1\\FIREFOX.EXE,1"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\http\shell\open\command]
@="C:\\PROGRA~1\\MOZILL~1\\FIREFOX.EXE -url \"%1\""

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\https\DefaultIcon]
@="C:\\PROGRA~1\\MOZILL~1\\FIREFOX.EXE,1"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\https\shell\open\command]
@="C:\\PROGRA~1\\MOZILL~1\\FIREFOX.EXE -url \"%1\""

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CHROME\DefaultIcon]
@="C:\\PROGRA~1\\MOZILL~1\\FIREFOX.EXE,1"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CHROME\shell\open\command]
@="C:\\PROGRA~1\\MOZILL~1\\FIREFOX.EXE -url \"%1\""

[HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main]
"Check_Associations"="No"
"IgnoreDefCheck"="Yes"
========================================================== 
anonymouse