Dies ist eine alte Version des Dokuments!
The previous chapters explained different buffer overflow exploitation techniques. However, the effects of the overflows did not show up in the self-written code, but when calling standard library functions. One does not only need to be careful about writing safe code but also about using provided functions that make assumptions about the passed input. The standard library of the C programming language builds the foundation for larger applications but contains several functions which can - if they are used incorrectly - cause buffer overflows1).
Following functions of the C standard library are well-known examples causing buffer overflows. With each function description includes a demonstration of incorrect usage.
gets() reads a string from the standard input. There is no way to restrict the length of the input.
// gcc -std=c99 gets.c #include <stdio.h> int main() { char buffer[10]; gets(buffer); return 0; }
As there is no way to use gets()
safely, it was removed from the C standard with C11.
strcpy() copies a string to another memory location. The destination buffer might be smaller than the source buffer.
// gcc strcpy.c #include <string.h> int main() { char dst_buffer[10]; char const *src_buffer = "This string is too long for the dst_buffer"; strcpy(dst_buffer, src_buffer); return 0; }
strcat() concatenates two strings. The destination buffer might be too small to also contain the source buffer in addition to the existing string.
// gcc strcat.c #include <string.h> int main() { char dst_buffer[10] = "This "; char const *src_buffer = "string is too long for dst_buffer"; strcat(dst_buffer, src_buffer); return 0; }
scanf() and its related functions (sscanf(), fscanf(), etc.) read formatted input. By default, there is no length restriction on the input.
// gcc scanf.c #include <stdio.h> int main() { char buffer[10]; scanf("%s", buffer); return 0; }
sprintf() and vsprintf() write a formatted string to a buffer. By default, there is no length restriction on the generated string.
// gcc sprintf.c #include <stdio.h> int main() { char buffer[10]; sprintf(buffer, "Hallo %s!\n", "World"); return 0; }
In order to prevent buffer overflows caused by standard library functions, it is important to either validate the input in advance or use safer alternatives.
fgets() is a safer alternative to the gets()
or scanf()
function.
// gcc fgets.c #include <stdio.h> int main() { char buffer[10]; fgets(buffer, 10, stdin); return 0; }
When thinking about a safer alternative for strcpy()
, the most obvious solution is probably strncpy().
// gcc strncpy.c #include <string.h> int main() { char dst_buffer[10]; char const *src_buffer = "This string is too long for the dst_buffer"; strncpy(dst_buffer, src_buffer, 10); return 0; }
It is important to note that also strncpy()
can cause unintended effects. If the source buffer is larger than the size passed to strncpy()
, there is no '\0
' termination added to the destination string.
One alternative taking care of '\0
' termination is strlcpy()
. However, this function is not part of the C standard and only available on some Unix systems (e.g. BSD).
// gcc strlcpy.c #include <string.h> int main() { char dst_buffer[10]; char const *src_buffer = "This string is too long for the dst_buffer"; strlcpy(dst_buffer, src_buffer, 10); return 0; }
Similar to strncpy()
, the obvious alternative to strcat()
is strncat().
// gcc strncat.c #include <string.h> int main() { char dst_buffer[10] = "This "; char const *src_buffer = "string is too long for dst_buffer"; strncat(dst_buffer, src_buffer, 4); return 0; }
Again, also strcat()
can cause problems if the existing string is not terminated by a '\0
' character. Analogous to strlcpy()
, there is a safer alternative called strlcat()
taking the size of the destination buffer as a parameter on some Unix systems.
// gcc strlcat.c #include <string.h> int main() { char dst_buffer[10] = "This "; char const *src_buffer = "string is too long for dst_buffer"; strlcat(dst_buffer, src_buffer, 10); return 0; }
snprintf() and vsnprintf() are safer alternatives to the sprintf()
and vsprintf()
functions.
// gcc snprintf.c #include <stdio.h> int main() { char buffer[10]; snprintf(buffer, 10, "Hallo %s!\n", "World"); return 0; }
← Back to heap overflows | Overview | Continue with ASCII-armored addresses → |