0x260
Buffer Overflows

C is a high-level
programming language, but it assumes that the programmer is responsible for data
integrity. If this responsibility were shifted over to the compiler, the
resulting binaries would be significantly slower, due to integrity checks on
every variable. Also, this would remove a significant level of control from the
programmer and complicate the language.

While C's simplicity increases the programmer's control and the
efficiency of the resulting programs, it can also result in programs that are
vulnerable to buffer overflows and memory leaks if the programmer isn't careful.
This means that once a variable is allocated memory, there are no built-in
safeguards to ensure that the contents of a variable fit into the allocated
memory space. If a programmer wants to put ten bytes of data into a buffer that
had only been allocated eight bytes of space, that type of action is allowed,
even though it will most likely cause the program to crash. This is known as a
buffer overrun or overflow, since
the extra two bytes of data will overflow and spill out the end of the allocated
memory, overwriting whatever happens to come next. If a critical piece of data
is overwritten, the program will crash. The following code offers an
example.

overflow.c
code

void overflow_function (char *str)
{
char buffer[20];

strcpy(buffer, str); // Function that copies str to buffer
}

int main()
{
char big_string[128];
int i;

for(i=0; i < 128; i++) // Loop 128 times
{
big_string[i] = 'A'; // And fill big_string with 'A's
}
overflow_function(big_string);
exit(0);
}

The preceding code has a function called
overflow_function() that takes in a string pointer called str
and then copies whatever is found at that memory address into the local function
variable buffer, which has 20 bytes allocated for it. The main function
of the program allocates a 128-byte buffer called big_string and uses a
for loop to fill the buffer with As. Then it calls the
overflow_function() with a pointer to
that 128-byte buffer as its argument. This is going to cause problems, as
overflow_function() will try to cram 128 bytes of data into a buffer that only
has 20 bytes allocated to it. The remaining 108 bytes of data will just spill
out over whatever is found after it in memory space.

Here are the results:

$ gcc -o overflow overflow.c
$ ./overflow
Segmentation fault
$

The program crashed as a result of the overflow. For a programmer,
these types of errors are common and are fairly easy to fix, as long as the
programmer knows how big the expected input is going to be. Often, the
programmer will anticipate that a certain user input will always be a certain
length and will use that as a guide. But once again, hacking involves thinking
about things that weren't anticipated, and a program that runs fine for years
might suddenly crash when a hacker decides to try inputting a thousand
characters into a field that normally only uses several dozen, like a username
field.

So a clever hacker can cause a program to crash by inputting
unanticipated values that cause buffer overflows, but how can this be used to
take control of a program? The answer can be found by examining the data that
actually gets overwritten.