2 minute read

Published:

Buffer overflow attacks

Buffer overflow attack basically means that the content provided by the user to an application has a bigger size than what the application was expecting. In this case, if the application did not handle these kind of situations, then the user provided content will overwrite the stack of the application. In most cases this will corrupt the stack and the program will end with a segmentation fault.

Modern compiler, gcc, solves this problem automatically by using stack canaries. These are small markers places on the stack boundaries. If there is an overwrite of the stack then these canaries are also over written modifying the value of these canaries, which is detected by the compiler and halts the execution.

Let’s see this with an example. This is taken from here and modified as per requirement of this post.

Consider this C code

#include <signal.h>
#include <stdio.h>
#include <string.h>
int main(){
	char realPassword[20];
    char name[20];
	char givenPassword[20];

	strncpy(realPassword, "ddddddddddddddd", 20);
    puts("Enter name:");
    gets(name);
    puts("Enter password:");
	gets(givenPassword);
	
	if (0 == strncmp(givenPassword, realPassword, 20)){
		printf("SUCCESS!\n");
	}else{
		printf("FAILURE!\n");
	}
	printf("givenPassword: %s\n", givenPassword);
	printf("realPassword: %s\n", realPassword);
	return 0;
}

This is a simple C code that asks a user for his name and a password. The provided password is string compared with the realpassword. If the content matches then SUCCESS is printed, else FAILURE.

With the compiler protection

Please note the use of gets to get the user input. gets does not have boundary checks built into it, and hence if we provide more than the size required, 20 in this case, this will override the stack. Let’s try that.

gcc hello.c -o hello

./hello
Enter name:
Sandeep
Enter password:
test
FAILURE!
givenPassword: test
realPassword: ddddddddddddddd


./hello
Enter name:
Sandeep
Enter password:
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
*** stack smashing detected ***: <unknown> terminated
Aborted (core dumped)

Removing the compiler protection

If we try to enter more than the expected data, the compiler detects this. Actually, the protection mechanisms placed by the compiler detects this because compiler is not longer in the picture after the compilation is done. This detection is the feature of the modern gcc compilers. We can disable this with a flag. Let’s try again

gcc hello.c -o hello -fno-stack-protector
./hello
Enter name:
Sandeep
Enter password:
a
SUCCESS!
givenPassword: a
realPassword: a

Here, the program is compiler using -fno-stack-protector which disables the compiler stack protection and allows the buffer overflow attacks to go through.

In this case, the input provided us for the name overwrites the realpassword field. The referenced blog provides a detailed explanation of how this happens using gdb.