When you have an active ssh session, you can use ssh escape sequences to modify the session at runtime.
Activating a sequence requires that the last key you entered was
<enter>, followed by
~ and lastly the sequence key. If you are unsure which key is for which sequence, use
? for the sequence key (e.g.
<enter>~?). This will print out the help menu.
Supported escape sequences: ~. - terminate connection (and any multiplexed sessions) ~B - send a BREAK to the remote system ~C - open a command line ~R - request rekey ~V/v - decrease/increase verbosity (LogLevel) ~^Z - suspend ssh ~# - list forwarded connections ~& - background ssh (when waiting for connections to terminate) ~? - this message ~~ - send the escape character by typing it twice (Note that escapes are only recognized immediately after newline.)
Some example use-cases
Terminating a session
$ ssh my-server # running inside an ssh session > ./do-stuff # let's assume that at this point the session hangs and we can either: # - wait for a timeout # - close the terminal on our side # - or better yet, terminate the ssh session using escape sequences # note the enter we do on the first line, to make sure the sequence will be recognized > > ~. Connection to 18.104.22.168 closed.
For a quick reminder on the syntax for each specific forwarding type, you can always enter the shell (with
<enter>~C) and type
? to get a list of available options.
ssh> ? Commands: -L[bind_address:]port:host:hostport Request local forward -R[bind_address:]port:host:hostport Request remote forward -D[bind_address:]port Request dynamic forward -KL[bind_address:]port Cancel local forward -KR[bind_address:]port Cancel remote forward -KD[bind_address:]port Cancel dynamic forward
It is important to note that forwarding can be between ports or UNIX sockets, or any combination of the two.
Forwarding local ports
Local forwarding means you want to open a port on your machine, which is tunneled to a remote resource. It is configured using the following parameters:
-L[bind_address:]port:host:hostport ╚═╦═══════════════╝ ╚═╦═════════╝ ╚» your machine ╚» ssh server
As we can see, we can omit
bind_address, which will default to any interface. For the purposes of this post, we will omit this field.
Access resources running on ssh server
If we have a Postgres instance running on our ssh server on its default port 5432, and we want to access it on our machine, as if it is running locally, we would use
-L 8000:localhost:5432. This would open a port (8000) on our machine, which when accessed would tunnel to the ssh server, where (on localhost) it would forward to Postgres (5432). Postgres in this sense is localhost, from the perspective of the ssh server.
Access resources running on another machine to which ssh server has network access
Following the previous example, if Postgres was on another machine (to which ssh server has network access), we would use
-L 8000:postgres-server:5432, where
postgres-server is the hostname/IP of the machine running Postgres.
Access arbitrary resources on the internet
If we would like to access any resource on the internet and hide behind our ssh server’s IP, we could use
-L 8000:my-website.com:80, and consume this resource as if is running localhost on our machine on port
8000. There is a much better way to do this, by using dynamic forwarding, explained later in this post.
Forwarding remote ports
Remote forwarding means you want to open a port on remote machine, which is tunneled to your local machine.
-R[bind_address:]port:host:hostport ╚═╦═══════════════╝ ╚═╦═════════╝ ╚» ssh server ╚» your machine
There is a setting in
GatewayPorts that will control who has access to the newly opened port. If this setting is set to
no, then only local connections (from the standpoint of the server) can be made. Setting it to
yes will allow connections from all reachable hosts. It can also be set to
clientspecified, which gives us some control on exactly who can access the resource.
If we have
GatewayPorts set to
clientspecified, then we can configure remote forwarding this way:
-R 192.168.1.2:2222:localhost:22 my-server
We are allowing
192.168.1.2 to connect to port
my-server which will be forwarded to port
client (our) machine.
Dynamic port forwarding
Dynamic port forwarding will essentially create a SOCKS5 proxy on the port you specify. With this, you can for instance redirect all your browser traffic through the proxy, allowing you to browse the web through the eyes of your SSH server. Any software that has the ability to route traffic through a SOCKS5 proxy will be able to take advantage of this.
This will open a SOCKS5 proxy on port 4321 on your local machine.
Firefox -> FoxyProxy -> Burp -> SSH SOCKS5 -> Internet
Let’s pretend you can only access certain resources from your SSH server, but you would still like to put BurpSuite between your browser and the resource you are trying to access. To get this working we will need Firefox, FoxyProxy plugin for Firefox and BurpSuite.
Configure FoxyProxy to connect to BurpSuite (by default Burp is listening on 8080). Then configure BurpSuite to connect to SOCKS5 by going to User Options -> Connections under SOCKS5 Proxy.