Port Forwarding
PRACTICE ! PRACTICE ! PRACTICE !
Last updated
PRACTICE ! PRACTICE ! PRACTICE !
Last updated
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
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
Depending on your needs, the SSH tunnel can be used to do either local or 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
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
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
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
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
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
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
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
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
As a result, PC-1 will spawn port 80 and listen for connections to be forwarded to port 80 on the attacker's machine
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
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
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: