BUFFER OVERFLOW 101
Buffer overflow is one of the painful topics for anyone to learn if he or she is new to penetration testing but trust me sooner or latter one surely will need to understand even if it’s just the basics. But before we go further down the road what exactly is a buffer overflow?
Buffer Overflow , is an anomaly where a program, while writing data to a buffer, overruns the buffer’s boundary and overwrites adjacent memory locations. This made possible due to poor programming skill that some developers have and also use functions that are vulnerable to buffer overflows example which include
1. sprintf
2. gets
3. scanf
4. strcpy
These function don’t keep track of the amount of data passed meaning you can put as much data as you possible can which in turn might lead to a buffer overflow. A successful buffer overflow can lead to changes the execution path of the program, triggering a response that damages files or exposes private information. For example, an attacker may introduce extra code, sending new instructions to the application to gain access to IT systems those instructions might include shell codes For today articles we are going to be looking into Stack-based buffer overflows are more common, and leverage stack memory that only exists during the execution time of a function.
And we are going to create a simple python program that automates the process rather than copying and pasting memory addresses and junk to the program. We are also going to be extracting memory addresses using ghidra a really nice tool for reverse engineering
Without much say let’s jump in
So i decided to try out some CTF platforms and see if i could get some good beginner binaries and i got one from a site called CTFLearn called favorite color
Let’s connect to the box using a SSH connection and see what we’ll find
Looking at the home directory we see a binary called color and a flag textfile
But we cannot read flag.txt
This is because we are not in root or color_pwn group but looking at the binary it has a SGID bit meaning if we exploit the binary successfully we will have access to the flag since we’ll be in the color_pwn group but how can we exploit the binary
First i copied the binary to my box and opened it up with ghidra
Next i decided to look at the main function of the program
Looking at the main function you can see that it calls another function called vuln
I decided to look for the vuln function in the binary and scrolling down we get the function
Looking at it we see the vulnerability that the binary has is that it uses gets in the user input which as we know it is vulnerable to a buffer overflow
Sweet now we know the vulnerability that the binary has the next step is figuring out how to exploit the vulnerability
So i executed the binary and tried to pass it some input and always got a boo!!!
The binary is not so polite right?
What if we put a large number of characters
Looking at the output above we get a segmentation fault the program just crashed. To find out the exact number of characters that caused the segmentation fault i will use gdb-peda
I will use gdb to create a pattern of 100 non repeating characters
I will run the program using the pattern generated by gdb peda
Looking at the screen shot below we still get a segmentation fault
But what we need to focus our attention on is the EIP the instruction pointer and find at what value was the EIP overwritten
To know the exact place we’ll use pattern_offset feature of GDB
Looking at the screenshot below we see that after 52 byte we started overflowing the EIP
What the instruction pointer does is to point the next memory location that the program is supposed to jump to
But first we need to know the security features that are enabled in the application
We’ll use a feature called checksec in gdb-peda to know the security features enabled in the binary
Looking at the output we see that only NX is enabled
What this basically does is that it makes the stack read only meaning we can insert shell code in the stack and execute the shellcode to get a shell in the box since the stack is read only
What we can do is a ret2libc (return to libc) but i decided to first look at the binary and see if there were any interesting functions we could jump to
Looking back on ghidra decompiled source code we see a place where system is called and if we could point EIP to that specific address and jump to it probably we could get a shell on the box
Let’s now begin creating our exploit script
The box has pwntools installed so i’ll just create the script using that box and not my host OS
First we need to set up the environment variable
I saved the script and executed it and voila we have an output
From our previous reconnaissance we remember that we started overflowing the EIP after 52 bytes meaning we need 52 junk characters to send the program first before sending it a memory location for the program to jump to
Then we’ve reached the EIP now we can put a memory location where the program will jump to. Looking at ghidra output we need to tell the program to jump to the place where the system shell was spawned
Now let’s add the memory location to our exploit
Now our payload is ready we need to send it to the binary. The reason why I’ve used p32(memory address) was to tell pwntools to convert the memory address into a 4 byte address and also to convert it to little Endian format which the binary can understand
We need to tell pwntools that when it executes the binary it should receive the output until the : sign
After it has received the output we then tell pwntools to send the payload we’ve created
Now our exploit is done let’s save it and then execute it
Looking at the above screenshot it seems that we’ve got a shell
Let’s try executing commands and see if it works
And voila we see that it works perfectly
Let’s try reading the flag
And we have the flag sweet. That wasn’t so hard
The reason why we were able to find the memory address for the shell was because ASLR was disabled on the binary. ASLR randomizes the memory addresses each time during execution of the program but since it’s disabled the memory addresses are static
Let’s pic the second address and see if it will work
Let’s save the script and execute it again
After running the script we see that it still works
Let’s try the third memory address
Let’s save the script and execute again
Looking at the screenshot below we still got a shell
This means that if you were anywhere near that shell memory address you could still get a shell on the box
Lastly one feature of pwntools that makes it really amazing is that you even don’t have to have python on the box that has a vulnerable binary you can use pwntools to login to the box via SSH and then tell pwntools to automatically inject the payload to the binary thereby giving you a shell. To demonstrate i made a few changes to the python source code as you see below
Added a login variable which told pwntools to login to the box and automatically execute the payload
Let’s save the source code and execute the exploit from our localbox
And as you can see above after a few seconds we got a call back and a shell on the box from our box
Sweet that’s it for now guys till next time it’s goodbye from me. If you liked the article you can clap for me down below and also follow me so that you don’t miss any upcoming articles