OSCP: Understanding SSH Tunnels

FalconSpy
5 min readMay 13, 2020

SSH tunnels or port forwarding may be a bit confusing to understand.

There are three different types of SSH tunnels:

  1. Local Port Forwarding: Connections from the SSH client are forwarded via the SSH server to a destination server
  2. Remote Port Forwarding: Connections from the SSH server are forwarded via the SSH client to a destination server
  3. Dynamic Port Forwarding: Connections from various programs are forwarded via the SSH client to the SSH server and then the destination server

Throughout the OSCP lab and even potentially the exam you may need to utilize a SSH tunnel. You will most likely not encounter Dynamic Port Forwarding on the exam as this typically requires a system to act as your proxy but who knows.

Local Port Forwarding

I’d like to first note in order to perform a local port forward, you must have SSH access to your target or remote host. If you do not have direct SSH access, you may want to look at the Remote Port Forwarding section

This crudely drawn diagram with mspaint does a fairly good job explaining what a local port forward looks like:

The above diagram can be found at its source via: https://unix.stackexchange.com/questions/115897/whats-ssh-port-forwarding-and-whats-the-difference-between-ssh-local-and-remot

We will primarily be concerned with the top half of the diagram for the OSCP labs.

That being said, to explain what is occurring from left to right in the command ssh -L 123:localhost:456 remotehost we will break it down:

  • ssh — The ssh command itself
  • -L — Specifies a given port on the client side to be forwarded to the remote side
  • 123 — port 123 on our machine (Kali) to receive the forwarded port from the remote host
  • localhost — The forward to host. In this particular case it’s the victim machine
  • 456 — port 456 on the target machine (victim) to be forwarded to the remote host
  • remotehost — system we want to SSH into and forward ports from.
  • -N — not one of the flags above. However, this says do not execute a command. Useful if you do not want a ssh terminal open on the server after successful ssh execution.

Putting this all together, let’s say the server is running a website on port 8080 but you can only access it internally from the target’s network. Using an arbitrary port like 9000 on our Kali system we can use this to access the website.

The command to do this would be: ssh -L 9000:localhost:8080 victim

Once the tunnel has been established you can access this new website via http://localhost:9000

Another example would be using an SSH tunnel to get around a company firewall. This would be the second diagram from above.

Let’s say you really like chatting on the Freenode IRC server, specifically the Offensive Security #offsec channel. You can use a local port forward to get around the firewall and access the IRC server.

The following command will do just that: ssh -L 9000:irc.freenode.net:6667 user@server -N

Now we can use our favorite IRC client and connect to Freenode via /server localhost:9000 -j #offsec

Remote Port Forwarding

The attacker should be using this method to forward ports if they do not have SSH access on their victim. This method of forwarding is useful if you have a limited shell and would like to try and privilege escalate to a service not internet facing.

With the above being said, again, we have this crudely drawn diagram with mspaint that does a fairly good job explaining what a remote port forward looks like:

Again, the above diagram can be found at its source via: https://unix.stackexchange.com/questions/115897/whats-ssh-port-forwarding-and-whats-the-difference-between-ssh-local-and-remot

We will primarily be concerned with the top half of the diagram for the OSCP labs.

That being said, to explain what is occurring from left to right in the command ssh -R 123:localhost:456 remotehost we will break it down:

  • ssh — The ssh command itself
  • -R — Specifies a given port on the remote side to be forwarded to the client side
  • 123 — port 123 on the target machine (victim) to be forwarded to our Kali machine
  • localhost — The forward to host. In this particular case it’s our Kali machine
  • 456 — port 456 is the port we want on our Kali machine
  • remotehost —Our Kali machine
  • -N — not one of the flags above. However, this says do not execute a command. Useful if you do not want a ssh terminal open on the server after successful ssh execution.

Putting this all together:

Let’s say your target (example.com) is hosting a web service on port 8080 that is not directly accessible to you, the attacker (Kali), you would run the following command below:

ssh -R 7000:localhost:8080 user@example.com

When you run the above command, example.com:8080 is then forwarded to your attacking Kali machine on port 7000. From your Kali machine, you can now browse to http://localhost:7000 and reach example.com:8080 which you weren’t able to do before.

Dynamic Port Forwarding

You will want to use this when you have gained SSH access to a system. This will also be more useful if you have root level SSH access.

When setting up a dynamic port forward, it turns the SSH client into a SOCKS proxy.

We will also need to use proxychains if we want to nmap scan our non-rout-able target. Proxychains uses the default port of 9050.

To setup a dynamic port forward the following SSH command is recommended:

ssh -f -N -D 9050 user@victim_1.com

Proxychains by default should be running on port 9050. However, if you wish to use another port in the command above you will need to edit the conf file located at /etc/proxychains.conf or simply type locate proxychains.conf

From here we can use nmap to scan our non-rout-able target #2 via proxychains nmap target_2. Play around with the different options and flags to best see how to scan your new target.

Please note that scanning may run slower as a result of this method. It would obviously be much faster nmap wise if it was on your machine that you were pivoting through.

--

--