Sunday, December 17, 2006

Tricks with SSH

Do you want to ssh to your NATed box at home? Want to connect in to your machine at work that drops SYN packets at the perimeter? Tired of having to live without tab-completion and other handy features when an exploit sends a shell back to netcat? SSH to the rescue.

First, from the firewalled machine (call it BoxA) run:
ssh -nNT -R 2222:localhost:22 &
then on
ssh user@localhost -p2222

So what exactly does this do? Let's take a look at the relevant sections from ``man ssh'':

-n Redirects stdin from /dev/null (actually, prevents reading from stdin). This must be used when ssh is run in the background.

-N Do not execute a remote command. This is useful for just forwarding ports (protocol version 2 only).

-T Disable pseudo-tty allocation.

-R [bind_address:]port:host:hostport
Specifies that the given port on the remote (server) host is to be forwarded to the given host and port on the local side. This works by allocating a socket to listen to port on the remote side, and whenever a connection is made to this port, the connection is forwarded over the secure channel, and a connection is made to host port hostport from the local machine.
By default, the listening socket on the server will be bound to the loopback interface only. This may be overriden by specifying a bind_address.

``-nNT'' means we aren't going to give ssh any input, so don't execute a shell and don't allocate a tty. -R is a little trickier; it says start forwarding port 2222 of the remote machine (BoxB) to port 22 of the machine you're running ssh from (BoxA). Now when you run ssh localhost -p2222, you're connecting to the port forward that you just set up which sends your connection through an encrypted tunnel to BoxA, bypassing the firewall rules because the tunnel is already connected.


  • You're connecting to localhost from BoxB but the traffic is actually going to BoxA. This will confuse ssh who thinks that localhost should have the same fingerprint each time. To get around this, you'll likely have to delete the line beginning with ``localhost'' in your ~/.ssh/known_hosts.

  • If you're using an exploit you'll have to know the account's password (or steal an ssh key)

  • Don't complain to me if your sysadmin gets mad and blocks outbound ssh. =)

I love open source. They've really thought of everything.