meme source: https://www.mememaker.net/meme/if-you-practice-4240
No matter how far you go, it is important to always practice the concept over and over again by giving yourself a new challenge in every opportunity. So in this post, we are going to take a look at another good challenge for practicing Linux exploitation which is SmashTheTux that come from "Vulhub" platform
but because I don't want you guys to be overwhelmed with the material I will cut the writeup into several parts.
VM can be download from this link: https://www.vulnhub.com/entry/smashthetux-101,138/
Warm-up -> 0x00:
Once you installed and started the VM in your VirtualBox, the machine will offer us 9 challenged in the home directory, each of them contains a common vulnerability in the Linux binary that we can exploit to take control the programthe first challenge 0x00, give use the following piece of vulnerable code:
If you are already indulged with binary exploitation long enough, you can spot right away which piece of the code that causes a buffer overflow vulnerability
it is the strcpy() function
so in this code it takes the first argument of the program as an input and copied to the "buf" variable
simple enough, right?
let's try to crash the program by putting a large amount string
from the result above we can see that we need at least 260 bytes to overflow the instruction pointer which is equivalent to gain control of the program flow and in the end, all we need to do is to point this to our shellcode in the stack.
But hold on, this binary is protected with NX features, this means that our shellcode is going to be useless since the stack region is marked as non-executable
there are a couple of ways to circumvent this defense, one of the most popular technique is called ret2libc
this means that we don't have to input any shellcode along with our input but we just reusing the code inside the program library to be able to pop a shell in the program.
so what code we need to reuse then?
you can reuse system() function in the C program library and let's passed "/bin/sh" as the parameter to grant as shell
from this information our payload should follow this format:
padding + system() + exit() + "/bin/sh"
I used exit() as the return value so we can have a clean exit.
The following python script will helo us to generate our payload
cool :) we got a shell. How about ASLR?
in this stage, we don't have to worry about it since it disables by default and I want this first stage to be a warm-up so no serious hacking required.
The real deal -> 0x01 (Format String to shell)
The second challenge gives us the following, piece of vulnerable code:we can see at the print function it passed without "string format" this will let us control the formatting and this lead to what so-called "format-string" vulnerability
we can test the vulnerability by inputting a format like "%x" to the prompt and we can see from the result it spit back what is inside the stack.
This is happening due to the absence of variable reference for format string if this is not provided along the format string the print function will start to take the value from the stack.
Example:
printf("%x", var1); => good way (have format string at the left and reference of variable at the right)
Don't underestimate the power of format string exploit, it can be leverage into code execution if you can craft the exploit right but it takes a lot of practice and passion to really master this.
In this time I will show you how an attacker can craft format string to take control over the program.
If you are new in format string exploit I strongly suggest to take a look at my previous post. This will give you a solid ground on how to conduct simple format string attack and it will easier for you to follow the rest of the blog
First, we need to take over the instruction pointer we can do this by overwriting the GOT address one of the function after print function.
In this challenge, we can see that after printf() function there is exit() function to terminate the program, we can overwrite the exit GOT function and point it to our shellcode to take over the program
(Don't know what is GOT? check this link: https://systemoverlord.com/2017/03/19/got-and-plt-for-pwning.html)
But before we can overwrite the GOT instruction, we need to find out at what iteration our input will show up at the stack.
we can find this information by following the above figure. The result shows that our result show at the fourth and we can access this value directly with the following operator
Next is to find out the GOT entry of the exit() function. Using gdb we can obtain this information easily by following this figure:
now all we need to do is to construct a python script to generate our payload to overwrite the GOT entry in exit() function.
In this python script, we will write the GOT exit() function with the location of the next four bytes of the original address. This new address will be the place of our shellcode
we utilizing the format "%hn" operator in the python script which is used for overwriting memory in the stack
the above figure shows us the state of the GOT entry before we use our exploit we can see that it contains 0x8048356
If we input our payload from the script we can see that we successfully overwrite the entry into the new address.
Now, that we are able to take control of the program execution all we need to do is to write our shellcode into the new address and the program will automatically execute our shellcode
The shellcode that I used I get it from shell-storm => link
important note: you need to put "\x90" at the end of the shellcode to make the exploit work since we are going to iterate to write the shellcode into the new address by two. Whatever shellcode you use, you need to make sure that it has or you make it an even length by adding nop.
1. the first loop is for generating reference to the address for us to put in the shellcode. Because we are going to use "%hn" operator we need to put a reference address where it will be written to.
2. the second loop will be used to writing the actual shellcode into the new address. In every iteration, it will take two bytes from the shellcode, unpack it, deduce it with the previous value of LSB to get the correct value and last is to append it with the format operator "%hn" along with at which index of reference it will be written to.
If we try to break down the first loop and second loop at the same time it will go like this:
First Loop Second Loop
0x8049754 -> %38668x%4$hn (overwrite GOT exit() function)
0x8049756 -> %28844x%5$hn (overwrite GOT exit() function)
0x8049758 -> %49453x%6$hn (overwrite value in 0x8049758 with shellcode)
0x804975a -> %6342x%7$hn (overwrite value in 0x804975a with shellcode)
0x804975c -> %10681x%8$hn (overwrite value in 0x804975c with shellcode)
0x804975e -> %23713x%9$hn (overwrite value in 0x804975e with shellcode)
0x8049760 -> %50910x%10$hn (overwrite value in 0x8049760 with shellcode)
0x8049762 -> %14660x%11$hn (overwrite value in 0x8049762 with shellcode)
0x8049764 -> %50933x%12$hn (overwrite value in 0x8049764 with shellcode)
0x8049766 -> %14842x%13$hn (overwrite value in 0x8049766 with shellcode)
0x8049768 -> %8204x%14$hn (overwrite value in 0x8049768 with shellcode)
0x804976a -> %17525x%15$hn (overwrite value in 0x804976a with shellcode)
0x804976c -> %49821x%16$hn (overwrite value in 0x804976c with shellcode)
if you put it again the exploit into the GDB we can see that our shellcode is written into the new address and if you continue the program it will spawn a shell for us :)
If you never see what Linux shellcode is, I suggest you check my previous post on how to writing your own Linux shellcode
Don't worry this also can work outside of the GDB too but you need to keep the STDIN to remain open so the shellcode will not terminate immediately.
Also do not worry if ASLR mode turns on in the machine it will not affect the exploit since we are not executing the shellcode at the stack memory region.
So I think that's all that I can write in this post today, hope you enjoy it and see you at the next part of the writeup :)
Comments
Post a Comment