Monday, May 25, 2015

Study on SSH tunneling

What is SSH?

Secure shell, better known as ssh, is a very popular protocols that enables users to remote control a machine through a shell securely. 
Besides a shell, ssh also supports other functions such as secure file transfer and tunneling. Today I studied and experimented the reverse ssh tunnel feature.

What is SSH tunneling?

Tunneling means transferring data of one protocol over another protocol.
In the case of SSH tunneling, ssh can transfer data of other protocols from a local port to a remote port (forward tunnel) or from a remote port to a local port (reverse tunnel). These two tunnels can be useful in different scenarios.

Forward tunnel

Forward tunnel is to map a local port to a remote port. 
For example, there is a ssh client, called C and a ssh server, called S, which are located in different networks. S has a service that listens to port 12345, but the firewall of the network only allow incoming SSH traffic. To access the service, C can setup a ssh tunnel to S, which map an arbitrary local port, say 54321, to the remote 12345 port. After the tunnel has been set up, C can access the service by connecting to port 54321 of localhost instead. The traffic will then be tunneled to port 12345 or S.

Reverse tunnel

Vice versa, reverse tunnel is to map a remote port to a local port. 
For example, now we want to access C through remote desktop (RDP), however, C is located in a NAT'ed network. Suppose port forwarding in the network gateway is not possible since it is not under C's control. It can be fulfilled by reverse tunnel. C can setup a ssh tunnel to S, which maps an arbitrary remote port, say 11111, to the local RDP port. Then, S can access C by RPD through the tunnel.

How to set up a SSH tunnel?

SSH tunnels by command line OpenSSH client and PuTTY will be described here.
[Warning: There are security risks in SSH tunnel, especially reverse tunnel. Try only if you know what you are doing.]

Forward tunnel

OpenSSH

The OpenSSH option -L can be used to setup a forward tunnel
-L [bind_address:]port:host:hostport
Using the previous example, to map local port 54321 to remote port 12345, we use the following command:
ssh -L 54321:localhost:12345 hostname_of_S

PuTTY

In connection->ssh->tunnels, enter the following:


And then click "Add" and "Apply".

Reverse tunnel

OpenSSH

Use the option 
-R [bind_address:]port:host:hostport
To map the remote port 11111 to local port 3389, we use the following command:
ssh -R 11111:localhost:3389 ip_of_S

PuTTY

Enter the following in PuTTY:

Example: Access the inaccessible network

[Warning: Again, mind the security risks. Try only if you know what you are doing.]
Here I list an example that utilize both forward and reverse tunnels to access a computer in an inaccessible network.
Suppose there are two networks, network A and network B, both networks do not allow incoming traffic. If a computer in network A wants to remote desktop another computer in network B, it can be done by tunneling through an accessible SSH server.
  1. First, the computer in network B needs to setup a reverse tunnel to the SSH server, mapping an arbitrary remote port, say 6789, to the local RDP port, i.e. 3389.
  2. Now, we want to access the reverse tunnel from network A. However, by default the reverse tunnel is accessible by SSH server only -- the mapped port only receives traffic from localhost. One way to access the reverse tunnel remotely is to set up a forward tunnel to it. We can setup a tunnel from a computer in network A to the SSH server, mapping local 6789 port to the remote 6789 port.
  3. Lastly, the computer in network A can be initiate a RPD connection to localhost:6789. It will be forwarded to port 6789 of the SSH server by the forward tunnel, which will in turn be forwarded to port 3389 of the computer in network B by the reverse tunnel.

Security Risks of SSH tunnel

From the example, we can see that covert channels can be created very easily in a company, by using SSH.  
Due to the flexibility and security of SSH, the risks of SSH tunnels are very difficult to mitigate. In order to mitigate the risks, the administrators need to:
  1. Forbid the use of any SSH tunnels unless approved.
  2. Forbid any unnecessary use of SSH client.
  3. Disable unnecessary SSH servers.
  4. Disable SSH port forwarding if not needed.
However, these measures are very difficult to execute.
Since all network traffic of SSH is encrypted, it is very difficult, if not impossible, to monitor the activities in a SSH session. The administrators do not know what is being transferred out, don't know what is being transferred in, don't know whether there is a forward tunnel or reverse tunnel. Nothing.

Not only is SSH difficult to monitor, it is also difficult to block.
To block covert channels from incoming SSH connections, administrators need to carefully configure sshd.
PortFoward should be disabled, if it is not necessary, to prevent any unexpected inbound forward tunnels. Administrators should also be aware of the possibility of a user running his own version of sshd so that he can has his desired configuration.
On the other hand, outgoing SSH traffic is very difficult to control. Since sshd can be run in any port, port blocking does not work unless very restricted outgoing rules are set (e.g. only allow outgoing traffic to a specific address or even block all outgoing ports). Otherwise, a user can just setup a SSH server running on any open port. It is very difficult for the administrators to identify and block the tunnels.

References:

http://en.wikipedia.org/wiki/Secure_Shell
http://en.wikipedia.org/wiki/Tunneling_protocol
http://unix.stackexchange.com/questions/88274/i-need-to-rdp-to-a-server-through-a-reverse-tunnel
http://www.sans.edu/research/security-laboratory/article/top-firewall-leaks
http://www.informit.com/articles/article.aspx?p=602977