An SSH tunnel allows you to route traffic through an SSH connection. It encrypts the traffic and routes it from a port on one computer to a port on the remote computer. It’s also called SSH Port Forwarding.
A basic ssh connection takes the form: username@sshserverIP -p ssh-server-port. E.g. email@example.com -p 1234 (you don’t need the -p switch if using standard ssh port 22)
To perform port forwarding we add a switch such as -L or -R.
Local Port Forwarding
We use the -L for Local port forwarding with the following switch syntax:
-L <local-port-listening>:<remote-host>:<remote port>
Situation: Getting past a local firewall
Your work firewall is blocking traffic to the google.com domain. You have a host at home running an SSH server at 18.104.22.168. You can access your home PC through the work firewall.
Solution: Route the traffic through an SSH tunnel to your local PC which then acts as a gateway and accesses google.com for you.
The syntax is:
ssh- L local-listening-port:remote-host:report-port username@sshserver
e.g: ssh -L 9001:google.com:80 firstname.lastname@example.org
In effect the switch syntax consists of two host:port pairs like this:
-L local-host:local-port:remote-host:remote-port – but the syntax you use doesn’t bother with the local-host in these examples, as it’s assumed that it’s the computer you’re typing the command on. But it’s worth remembering this as the syntax is otherwise rather confusing, or it is for me anyway.
After that command is typed, you will be asked for the SSH server credentials, and an SHH connection is visibly formed (i.e you are connected to the remote server via SSH). In the background a listening port on your local computer is set up on 9001, waiting for traffic to the remote-host google.com. When it gets that request, it forwards it to the other end of the tunnel and from there out to the named remote-host (google.com)
Situation: Routing traffic to a service/app on the remote host
The remote host has a VNC server running on port 5900 but is behind a firewall. We only have SSH access through the firewall (i.e. only port 22 is open, not the VNC port 5900 so we cannot access VNC directly). We wish to route VNC traffic to the server, through the firewall, hidden inside the SSH tunnel, and also get the benefits of encrypted VNC traffic. The server’s IP is 22.214.171.124 and the user is “serveradmin”
Solution: route the vnc traffic through the SSH tunnel to the VNC server application (running on the same remote host as the SSH server)
ssh -L 5900:localhost:5900 email@example.com
Here we see that:
- <local-listening-port> = 5900
- <remote-host> = localhost
- <remote-port> = 5900
N.B. “localhost” is the loopback address for the remote server.
N.B. The listening port doesn’t need to be 5900, it could be any spare port.
This command sets up the SSH tunnel connection between the machines. A local port 5900 is set listening on your PC, ready to route traffic that arrives on it, to the SSH server at the other end of the tunnel. The SSH server at the other end is told to route traffic arriving through the tunnel to “localhost”, ie the host it is running on, on port 5900. Since the VNC server is on that host, listening on port 5900.
Once the traffic is set up, we can put the following details into a VNC viewer client: localhost:5900
Situation: Pivoting during Pentesting
This routing of traffic is useful in pen testing in a variety of ways. Let’s say you have obtained SSH access to a linux host and whilst on there have discovered there is a Windows machine on an internal network with RDP access. You want to brute force the RDP credentials. You don’t have enough privileges on the linux box to install a brute-force scanner so you want to run this on your local machine.
Solution: Route RDP traffic from your local hacking machine (say Kali) through the linux server via an SSH tunnel.
ssh -L 3389:192.168.0.220:3389 firstname.lastname@example.org
Here we set up an SSH connection with the linux box on 126.96.36.199 and forward our local (Kali machine) RDP port 3389 to the RDP port of the Windows machine on the target company’s internal network at 192.168.0.220. When we use an RDP client (or brute forcer) it connects to 3389 and gets routed to the internal Windows box.
N.B there are other methods of routing traffic to internal networks including sshuttle which sets up a VPN to the onward network thus allowing you to RDP directly to the 192.168.0.220 machine from your local machine (IP addressing ranges allowing)