|
Buffer Overflows in C
Vulnerabilities, Attacks, and Mitigations |
|
Prof. David Bernstein |
| Computer Science Department |
| bernstdh@jmu.edu |
main(int argc, char* argv[]))
void operation(int array[])
{
int length = sizeof(array) / sizeof(array[0]);
for (int i=0; i<length; i++)
{
// Operate on array[i]
}
}
array is a parameter and, so, is a
pointer typesizeof(array) is the size of an
int *, not the size of the array-1 in an array of non-negative
integers)char and
wchar_t
'\0')gets()
gets() to read characters (until it reaches a
newline or end-of-stream character)char line[81]; gets(line);
strcpy()
strcpy()
int main(int argc, char* argv[])
{
char file_name[65];
char *temp;
temp = argv[1] ? argv[1] : "";
strcpy(file_name, temp);
}
strcat()
strcat() to append a source string to
a target stringsprintf()
sprintf() to create a (formatted) stringchar line[81]; sprintf(line, "%2d: %s\n", i, user_input);
sprintf() assumes that the buffer it is passed
is large enough and the attacker might provide a string that
is too long (i.e., longer than 80 - 2 - 2 - 1 = 75
characters in this example)strncpy() to copy the first
n characters
from the source to the target when the source contains
n or more characters (which results in a non-null
terminated string)strlen() uses the null character to determine the
length of the string so any function that uses
strlen() will have problemsstrcpy()) iterate until
a null character is encountered so will have problems
char a[10], b[10]; strncpy(a, "0123456789", 10); // a will not be null-terminated strcpy(b, a); // b will probably overflow
... char buffer[BUFFER_SIZE]; long value = ...; long* p = ...; strncpy(buffer, argv[1], length); // Potential overflow into p *p = value; // Assign value to the address pointed to by p ...
... static int value = ...; static char buffer[BUFFER_SIZE]; static void (*f)(int i); f = &some_function; strncpy(buffer, argv[1], length); // Potential overflow into f (void)(*f)(value); // Execute the code pointed to by f ...
#include <stdio.h>
#include <string.h>
char eid[9]; // 8 characters plus '\0'
int grade;
int main(int argc, char* argv[])
{
// Initialize
strcpy(eid, "bernstdh");
grade = 100;
printf("EID: %8s Grade: %d\n", eid, grade);
// Copy user input into the eid
strcpy(eid, "bernstdh \x08\x08"); // 0x08 is ASCII backspace
printf("EID: %8s Grade: %d\n", eid, grade);
}
Address of eid: 0x0804a030
Address of grade: 0x0804a024
eid only requires 9 bytes, space
actually exists for 12 (for alignment reasons)