Hello again! It’s been a busy few weeks which has kept me from being able to work on the Wargame, but I was finally able to find some time! Again, if you haven’t followed my other two blog posts, this post may not make a lot of sense, so I highly recommend at least skimming them if you feel lost. These posts are meant to help you learn things while I learn things, but they tend to build on each other as well. If you need a copy of the VM, you can download it from my GitHub account here.
On a side note, if you’re a veteran interested in or are currently working in Cybersecurity, feel free to swing by our slack channel! If you’re just genuinely curious about the field or have any other specific questions, please feel free to message me and I’ll try to get back to you! My contact info can be found at the bottom of this page or here.
Now, for a quick overview of this post. I completed the first 4 introduction tutorials and a simple program exploitation tutorial, that I felt were a good build up to how a buffer overflow works. These are all very basic and leave out a lot of the difficulties that you might face in a standard program that exists today, but they serve as a good foundation for understanding a very well known vulnerability and something that is tested in the OSCP certification. They are all limited to 32-bit and have ASLR and stack canaries turned off to allow for the ease of learning. Later challenges will not be as easy. I will also be writing guides to supplement these tutorials/challenges, so keep an eye out for that post next! But for now, we’ll get back to this series of posts!
What I learned:
- Makefiles: Again, I am still new to these and I may want to learn CMAKE a bit later, but for now, these makefiles will suffice for scripting my builds. I modified my previous version to support future plans on reusing a similar template. I wanted to try a few new things out that didn’t end up working, so I’m sure this will change again down the road!
- Introductory Buffer Overflow Tutorials/Challenges: I kept with a similar style to some of Protostars challenges which I felt like gave a good set of beginner challenges, in which I modified slightly. I intend on ramping up these challenges to include some of the more tricky things you might run into in the near future, but first, I want to help solidify some more of the basics, which may require a couple more basic challenges.
Changes to the Makefile for Module 1:
For conveniences sake, I will post and explanation from my previous blog post here, but more up to date to match my current one that you can see below! If you are unfamiliar with a makefile, I suggest you read my section titled ‘the makefiles’ in my previous blog post. It gives a bit more in depth to what a makefile is, whereas this section will only cover my specific makefile for Module 1 (Figure 1 below).
This is not something you will likely have to work with, unless you are a developer, so don’t feel in the dark if you don’t understand this! I used a couple of references for how to make this which can be found here and here.
- Line 6: I set a variable called CC to ‘gcc‘, which means we will be using the gcc compiler to compile this program. This is the standard compiler that is used to turn C program source files into an executable on Linux.
- Line 7: I set a variable called CFLAGS to ‘-g -std=c89 -m32 -fno-stack-protector‘ which are the flags I want the program to be compiled with. The ‘-g‘ flag will allow for more debug information provided with the file, the ‘-std=c89’ flag forces the compiler to use the older c89 standard (1989 C standard, which allows for the use of the function ‘gets’, which has since been deprecated), the ‘-m32‘ flag will compile this program into a 32bit binary, and the ‘-fno-stack-protector‘ will disable stack canaries, which is a buffer overflow protection that I will explain in a future post.
- Line 10: I set a variable called TARGET to a list of all files named ‘bufferoverflow‘, which is the name of the challenge program to be compiled, and then strip the .c at the end. This uses a bit of sed magic, which you should really learn to use if you don’t know it already! It allows for a quick and easy text modification. To create this list, I first use ‘:=’ after my variable ‘TARGETS’ which means to append, and then I use a ‘sort’ command on what is produced by the inside shell function. Sort will automatically remove all duplicates that is comes across, which what I needed since the inner function could spit up multiple files with the same name, due to how I wrote my sed logic. The ‘shell‘ part executes commands as if they were running on the bash shell, in which I run ‘ls .’ which will display all of the files in the current directory (current directory is what is meant by the ‘.’), then I use a ‘|’, which is known as a pipe, to redirect the output of the previous ‘ls’ command as input into the following command. The next command is a ‘grep’ on the expansion of the ‘CHALLENGE‘ variable (which expands to bufferoverflow). Grep is a Linux command that helps with searching. It takes a string of characters and displays the matches to that string from whatever area you give it as input, thus, it will match ‘bufferoverflow’ from all of the files in the current directory (the input I gave it from the previous ‘ls’ command). I then pipe (|) this as input into the ‘sed‘ command, which is used to manipulate text. The command I use (‘sed ‘s/.c/ /g‘) will replace any match of ‘.c’ in the input to a blank instead, which in the end, just leaves me just the names of the files of my challenges.
- Line 13: the all means to perform all of the commands we provide it, a better explanation is here. I use $(TARGETS) to expand the variable ‘TARGETS’, that I set earlier, which will come out to be bufferoverflow1, bufferoverflow2, etc…
- Line 15-25: This is wear the magic happens. Line 15 says that we have a ‘target’ that is set to ‘$(CHALLENGE)1’. This expands to be ‘bufferoverflow1’ and and in Line 16 we begin the compilation process. We expand a lot of our variables we used before, so it becomes ‘gcc -o bufferoverflow bufferoverflow.c -g -std=c89 -m32 -fno-stack-protector 2>/dev/null‘. This means to use GCC to compile our program, ‘bufferoverflow.c‘ with the flags ‘-g -std=c89 -m32 -fno-stack-protector‘. The ‘-o’ means to make our compiled file an object file called just ‘bufferoverflow‘, without an extension, for ease of executing later. The ‘2>/dev/null‘ is used because compiling this program spits out a few warnings due to the nature of how insecure the functions we are using are. The ‘2’ means ‘stderr‘ which is followed by a ‘>/dev/null’. The ‘>’ means to send the previous output into the following area as input, and ‘/dev/null’ is an area that Linux reserves for tossing information into a blackhole.
- Line 27-28: This is just used for a simple cleanup. It will remove (with linux command ‘rm’) the files that are expanded by the ‘TARGETS’ variable (bufferoverflow1, bufferoverflow2, etc…), but leave our original ‘bufferoverflow#.c‘ files, so we can recompile it again later.
32-bit Buffer Overflow Challenges/Tutorials Change:
Since working on these, I have reshaped my challenges as tutorials with Modules and intend on creating separate challenges that will not have a guide with varying levels of difficulty. This will give some shape to my tutorials that allow for teaching like a course as well as the ability to make it fun like a wargame/CTF. There will be blog posts for these modules that will go more in depth, so I will only give a layout of my framework and thought process here. I am by no means claiming that these are the latest and greatest ways to perform exploitation, as again, I am still a newbie myself.
Buffer Overflow -> Module 1 – Introduction [Hands On]:
Module 1 (at this time, subject to change) contains 4 programs that will serve as an introduction to what a buffer overflow is and how to perform one. These are Hands On tutorial/challenges, that you can follow my guide(s) from the soon to come set of tutorials/blog posts.
The first program serves to show what happens when you overflow a buffer by modifying a variable that is located on the stack. (Figure 2)
The second program introduces using an environment variable to hold information that can be used in turn to overflow a buffer. This would be analogous to storing shellcode in an environment variable, but I keep it simplified for now, for demonstration and teaching purposes. (Figure 3)
The third program introduces the idea of overflowing a buffer and overwriting a function pointer that is stored on the stack to redirect code flow into a function that was not originally intended to be called. (Figure 4)
The fourth program is an extension of the third program, in which we overflow the buffer passed the current stack frame and overwrite the return address in which we then return into a function that was not originally intended to be called. (Figure 5)
Buffer Overflow -> Module 2 – First Exploit:
In this module, we look at what it means to exploit a vulnerability in a program. I have provided 2 programs (which come from Hacking: The Art of Exploitation), notetaker.c (figure 6) and notesearch.c (Figure 7). They work as fully functional programs, one will take notes and store them in /var/notes, and the other program will look up notes for the current user. The can be found in the folder labeled ‘Vulnerable_Program‘.
Notesearch.c has a vulnerability which allows for a buffer overflow to occur, giving us the ability to have arbitrary code execution. We will use some predefined shellcode for now, that will spawn us in a root shell when the exploit is run successfully. Shellcode is a string of assembly code that looks like hexadecimal bytes, that will be interpreted as CPU instructions when pointed to by the EIP register. I will explain this a bit more in depth in a later tutorial on shellcode.
We will exploit this program in two different ways; via command line arguments passed to the program that we execute from a c program that will act as our driver, and via an environment variable that stores our shellcode. I will go in depth as to how these work in the tutorials to come as well.
Command Line Argument Method:
The command line argument method will require us to write a program or script that will call the program we wish to run (the vulnerable program, notesearch, for our case) with a command line argument. Notesearch takes a string as an argument and searches all of your stored notes for that specific string and returns those notes. Thus, after examining and determining that this argument is stored into an unchecked buffer which we can overflow, we can provide an argument that will both provide a payload (our shellcode) as well as a return address to that shellcode that overwrites the saved return address on the stack and begins executing our payload. (Figure 8) This is explained more in the later to come tutorials.
Environment Variable Method:
In the environment variable method, we need to export some shellcode into an environment variable that we will jump to and execute from. For this, we can write a program or script that can accomplish this task. In my case, I have a shell script that is based off of a similar script that can be found in Hacking: The Art of Exploitation, but you can play around with this yourself and create your own script if you would like. The code I used that can be found in the ‘Environment_Method‘ folder for Module 2 can be seen below. (Figure 9)
This method will also require obtaining the address of the environment variable that we store our shellcode in so that we know where to return to and begin executing from that location as if it were the next place in code flow for our program. Thus, we need to make a program or script that will obtain that address for us! (Figure 10)
Wrapping it up:
I hope this was a useful tutorial and/or learning opportunity for you guys! I will soon be adding the tutorials that you can follow along to understand all of this much better! If you have any feedback or want to chat, feel free to contact me on one of my many means of communication. Thanks!
Also, if you’re a veteran or active military (anywhere in the world) who interested in Cyber Security, consider joining our Slack channel, we would love to have you!