One of the problems with many of the BoF tutorials available online is that they make way too many assumptions of their readers and don’t fully explain, at each step, what the hacker is supposed to be DOING but also THINKING along the way. The thinking part is the most important of all because if you’re not clear in your thought processes and what you need to do at each step, you’re going to get confused and lost very quickly.
Which is why so many newer hackers struggle with this part of hacking and never make it past skiddie level to actual hacker who can create and edit their own exploits or those of other hackers.
Another problem I see with these tutorials is that many of them, labeled “basic”, demonstrate only how to check if the program the hacker is attacking is vulnerable but do not explicitly state that so that by the end, all the hacker has done is caused a SegFault but did NOT actually execute any code.
They also don’t explain WHAT a SegFault is. I’ve had hackers ask me after reading many of these guides how come they don’t have a root shell after they received a SegFault and the reason for that is, ALL they did was successfully check that the program they were examining was vulnerable. A SegFault isn’t code execution but that distinction is not being made in these articles and it’s creating chaos in the minds of those who are very new to this and have no clue what they are reading.
This is my attempt at bridging the gaps and giving you some help with what you may come across and how you can overcome this seemingly insurmountable hurdle that is Buffer Overflows. They aren’t insurmountable, you just need to learn the proper steps and pre-requisites so you’ll be successful.
At the end of this first tutorial of mine you’re going to be able to do the following:
1. Determine if your system is Big or Little Endian – a critical step many tutorials leave out and why many exploits will fail. I will explain why they will fail when I explain Checking Your Endianness.
2. Determine if your system is x86 or x64 because this determines how you will compile your code (what flags you will use or not use)
3. Turn off Stack Protection on your Kali system so you can actually smash the stack, otherwise you won’t be able to. Again, the tutorials skip over this part or badly explain it and when an error occurs, the tutorial doesn’t explain how to fix that error.
4. Turn off ASLR on your system and/or check if ASLR is on or off.
5. Check your GCC version of your system so that you can add the libraries needed to avoid a specific error you may receive if you don’t have them.
6. Learn how to convert HEX to DEC on the command line.
7. Learn how to find vulnerable C programs on a system using the FIND command. This is another weak area of tutorials. They explain how to check if it’s vulnerable but almost never explain HOW THE HACKER FOUND THE VULNERABLE PROGRAM ON THE REMOTE SYSTEM TO BEGIN WITH!
At the end of Part Two of my tutorial which I will post tomorrow or sometime this week, you will be able to do the following:
9. Learn what to do if you do not have access to the source code, what’s the first steps you take.
10. Learn what you can do with setuid, setgid and sticky bit programs and why they are SO important to the malicious hacker! Another thing not explained.
11. Learn how to find the PROPER decimal number to insert into the python payload we are going to craft for the vulnerable code I show you AND in the future with other code! This is the most frustrating part of this whole learning process, the tutorials aren’t explaining how the hacker arrived at the number they put in to the payload!
12. Determine the buffer size of the vulnerable program manually and with a fuzzer.
13. Determine if you were successful in executing your payload and did it write to the memory space you told it to which then determines if you can then execute shellcode! Also not explained properly IMO.
14. Understand what a NOP sled is and how you can use it to execute your code and in what circumstances you would need one.
15. History of Buffer Overflows, fun facts and the tutorials I think are the best out there on this subject.
And some other things I’m going to add in between.
Please understand this may look like a very lengthy process but once you get the proper steps and methodologies down, you will be able to perform a BoF quicker than it’s going to take you to learn them.
I’m not going to explain the stack and how it looks in this tutorial because the ones I link you to at the end of it do a very good job of that. All I’m doing with this is filling in gaps.
I am also not getting into 64 bit BoFs in this tutorial because that’s another whole walkthrough but I will write it at some point and post about it.
Okay?
Welcome, hacker, to one of the most frustrating parts of your journey. If you’re like me, learning this specific area of hacking was the most confusing experience out of all the others. This is because, as I said, the material you have at your disposal isn’t written as well as it should be. It is technically sound, but it’s too technical in some places and as stated, thinks you know more at the stage you’re reading it than you actually do. There’s a lot of gaps. Let’s begin filling in some of those gaps so that you have everything you need to do this in one place rather than researching for a month like I had to and then organizing all the information into one thing so it made sense to me.
This whole walkthrough will be in my Hacking Grimoire at some point.
Let’s get started.
1. Checking your Endianness on your system.
Before you do a BoF you need to determine if your system or the system you are planning on exploiting is Big or Little Endian otherwise you’re likely to fail in your mission. When doing a BoF, you need to know this because if it’s Big Endian you’re going to write the memory address out as is but if it’s Little Endian you need to write it out in REVERSE.
Read this for a better explanation of what I’m trying to say:
https://www.geeksforgeeks.org/little-and-big-endian-mystery/
After you compile this code and run it, if you see the 67 45 23 01 number, your system is Little Endian which means you need to reverse the memory addresses. If it’s 01 23 45 67, it’s Big Endian and you will write them as you see them. This part will become clearer later in this guide.
But like I said, the tutorials on BoFs don’t point out this pre-requisite and it creates confusion for a person who has never done them and trying to follow along and when they type the wrong thing, it doesn’t work but they don’t know why!
I want to be clear here, you are NOT using the following number to replace any memory address, you are just using this to determine if your system is Big or Little Endian. The number echoed back to you in the Terminal is the answer to what type of system you’re working on. That’s it.
root@kali:~/# ./biglittle
67 45 23 01
So let’s copy this code into memory.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
/* function to show bytes in memory, from location start to start+n*/ void show_mem_rep(char *start, int n) { int i; for (i = 0; i < n; i++) printf(" %.2x", start[i]); printf("\n"); } /*Main function to call above function for 0x01234567*/ int main() { int i = 0x01234567; show_mem_rep((char *)&i, sizeof(i)); getchar(); return 0; } |
Now let’s create a file called biglittle.c
|
1 |
nano biglittle.c |
Paste the code in the box above into the Terminal window.
CTRL + X to exit.
Y to save it.
ENTER to return back to Terminal.
Now you’re going to compile the program.
|
1 |
gcc biglittle.c -o biglittle |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
root@kali:~/# gcc biglittle.c -o biglittle biglittle.c: In function ‘show_mem_rep’: biglittle.c:7:10: warning: implicit declaration of function ‘printf’ [-Wimplicit-function-declaration] printf(" %.2x", start[i]); ^~~~~~ biglittle.c:7:10: warning: incompatible implicit declaration of built-in function ‘printf’ biglittle.c:7:10: note: include ‘<stdio.h>’ or provide a declaration of ‘printf’ biglittle.c:8:5: warning: incompatible implicit declaration of built-in function ‘printf’ printf("\n"); ^~~~~~ biglittle.c:8:5: note: include ‘<stdio.h>’ or provide a declaration of ‘printf’ biglittle.c: In function ‘main’: biglittle.c:16:4: warning: implicit declaration of function ‘getchar’ [-Wimplicit-function-declaration] getchar(); ^~~~~~~ |
Uh oh! What happened? This is where you want to pay attention to what the compiler is telling you. It’s saying we need to provide it further explanation OR add a simple line to our code.
So now let’s open our code again.
root@kali:~/# nano biglittle.c
At the very top of the file you are going to type
|
1 |
#include <stdio.h> |
CTRL + X to exit.
Y to save.
ENTER to go back to Terminal.
Why did we do that? Because of this line in all that error word salad: biglittle.c:8:5: note: include ‘<stdio.h>’ or provide a declaration of ‘printf’
Now let’s compile it again.
root@kali:~/# gcc biglittle.c -o biglittle
And now that should NOT give you an error.
Once again, at this stage all we’ve done is create a C program that can check whether our system is Big or Little Endian and now we need to run the code to see what type it is.
We are now going to give the biglittle program executable rights.
In terminal type:
|
1 |
chmod +x biglittle |
and press ENTER
Now run the program:
|
1 |
./biglittle |
root@kali:~/# ./biglittle
67 45 23 01
My system is Little Endian from the output.
67 45 23 01 = Little Endian.
01 23 45 67 = Big Endian.
That’s it.
I will write this designation down on my scratch paper that I always use while hacking.
That’s one hurdle resolved.
2. Determine if your system is x86 or x64
Now you need to determine whether your system or the remote system you’re on is x86 or x64 because if you try to compile a 32bit program on a 64bit machine and don’t supply the compiler with the proper flag, it won’t work.
In Terminal type:
|
1 |
uname -m |
If it returns x86_64 the system is 64 bit.
If it returns i686 the system is 32bit.
Okay onto the next part of this whole process.
3. Turn off Stack Protection.
In order to smash stacks you have to remove the stack protection in place to do that.
So you put in place the -fno-stack-protector flag when compiling.
|
1 |
gcc vuln.c -o vuln -fno-stack-protector |
That line means we are using the GCC compiler against the vuln.c program, outputting the compiled code to a file called vuln and removing stack protection from it.
So to remove the protection you are adding the -fno-stack-protector flag to your command.
If you do NOT remove the protection you will get an error like this
|
1 2 3 |
root@kali:~/#./vuln AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA *** stack smashing detected ***: <unknown> terminated Aborted |
Or like this if this is your command with the 510 being whatever number over the buffer size.
|
1 2 3 |
root@kali:~/# ./vuln `python -c 'print "A" * 510'` *** stack smashing detected ***: <unknown> terminated Aborted |
This means that the program was compiled like this gcc vuln.c -o vuln -fstack-protector-all
-fstack-protector-all <———- That flag tells it to protect the code against stack smashing.
4. Disable ASLR.
Address Space Layout Randomization (ASLR) is a protection mechanism against Buffer Overflows. It randomizes the memory space to thwart us in finding the addresses of functions so we can’t do attacks like BoF. In order to proceed we need to turn this off on our system.
On the remote system you can try one of these methods to see if you can turn it off
|
1 |
echo 0 > /proc/sys/kernel/randomize_va_space |
|
1 |
setarch `uname -m` -R ./vulnprogram |
|
1 |
setarch linux32 -R ./vulnprogram |
Where “./vulnprogram” is the name of whatever program you’re working with.
|
1 |
setarch `uname -m` -R $SHELL. |
That spawns a shell with ASLR disabled, and any command you run from that shell will also have ASLR disabled.
How do you check if it’s off?
|
1 |
cat /proc/sys/kernel/randomize_va_space |
If it returns 0 it’s OFF, if it returns 1 it’s ON.
5. Check your GCC version.
|
1 2 3 4 5 6 7 |
root@kali:~/# gcc --version gcc (Debian 7.3.0-3) 7.3.0 Copyright (C) 2017 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
This part is important. GCC is the compiler we’ll be using and which you will see referenced in a lot of BoF tutorials and in other tutorials where you need a compiler.
In GCC above 5.0 is missing some libraries we’ll need if we’re compiling 32bit programs on x64 bit systems that were present in 5.0 and below but not now if you’re version is above that.
If you try to compile it with the -m32 flag you may get an error that contains this language:
|
1 2 |
bits/libc-header-start.h: No such file compilation terminated |
You’re missing some gcc libraries. To fix it you’re going to paste this and hit ENTER
|
1 |
sudo apt-get install gcc-multilib g++-multilib |
6. Learn how to convert HEX to DEC on the command line.
I suggest you get an ASCII chart so you can do multiple conversions but if you don’t have it on your desk like I do, at all times. There’s a number of ways to convert it into Decimal (and octal, etc) on the command line. For this article, let’s just focus on Hex to Decimal.
Why you need this is when you’re looking at the EBP there’s going to be a Hex character there. In order to craft your payload with the correct decimal number (the A * 32 where 32 is the Decimal equivalent of the Hex representation you found in EBP) you need to know what the decimal is.
So let’s say we have 0x15a. That is 346 in Decimal. Here are some commands to convert from Hex (0x15a) to Decimal (346)
|
1 2 3 4 5 6 |
root@kali:~/# echo $((0x15a)) 346 root@kali:~/# printf '%d\n' 0x15a 346 root@kali:~/# perl -e 'printf ("%d\n", 0x15a)' 346 |
7. Learn how to find vulnerable C programs on a system using the FIND command.
So now let’s say you’re in a remote system and you do NOT have access to the source code of the vulnerable program nor do you have any idea if there’s a program that is vulnerable to BoF or not but you want to check if there might be. By using the FIND command on the system (assuming you have access to it and aren’t in a restricted shell that doesn’t let you) this is how you can do this.
Some of the C functions vulnerable to Buffer Overflow are:
gets
scanf
sprintf
strcpy
So doesn’t it stand to reason if we use the find command we can find programs on the system which have those functions in them and test them for BoF? Of course we can do this!
|
1 |
find . -name "*c*" | grep -R 'gets(' |
will find all C files you’re in that have the “gets(” string in it. You can substitute “gets(” for whatever you’re looking for (i.e. strcpy, etc)
*I originally copied the wrong command into the above box when I initially posted this as well as made a number of typos elsewhere. I apologize, I was very tired and working from three open Notepad windows when I posted this and didn’t copy the correct thing where it belonged. I should’ve been more careful and I’m sorry for the error.
How do you determine what directory you’re in? Easy.
|
1 |
pwd |
Hit enter and it will give you the path to where you are right now in the system.
You can use other techniques to find strings in files as well. I’m just showing you one way in order to illustrate your THINKING as soon as you get into a remote alien system. You have no idea what’s what or where anything is. So let’s start looking for them because they aren’t going to look for you!
Start researching other ways on how to find strings in files and save the methods someplace you can refer to them frequently as you practice this.
Here’s a great article on the vulnerable C functions and how to fix them
https://security.web.cern.ch/security/recommendations/en/codetools/c.shtml
Next part will explain more and by the end, you should be able to do a BoF.

Very nice! Thank you.