Better Living Through OpenSSH Config Files

By Red Siege | February 15, 2024

By: Justin Palk, Senior Security Consultant

 

SSH is an incredibly valuable tool for penetration testing. It provides us with a secure channel for administering machines, remotely executing tools, transferring files, forwarding ports and proxying traffic. But what if I told you it was possible to make it even better?

What if I told you you could have tab completion for opening connections to hosts you use regularly?

Or have it automatically forward ports or create the proxies you always use?

Or set your login user on a per-machine basis?

If you don’t know how to do all of this, let me introduce you to the OpenSSH client config file. This is going to be an overview of the features I find the most useful, rather than a deep-dive into all configuration options you can set on the client side.

A user’s OpenSSH client config file lives in ~/.ssh/config, alongside the authorized_keys file and the user’s public and private keys.

 

.ssh directory listing

 

The file consists of a series of host blocks setting the options for a given SSH server to connect to. At its most basic, a host block will consist of a mandatory hostname directive, and likely either a port and/or a user directive, as shown in the example below. Anything not specified in the config file will fall back on the SSH defaults, such as the current logged-in username and port 22/TCP.

host concentrator
  hostname 10.0.0.9
  port 2222
  user vpn-admin

With this block in a config file, typing ssh concentrator would be functionally equivalent to typing:

ssh vpn-admin@10.0.0.9 -p 2222

You can also tab-complete host entries in the config file on the command line, so typing ssh conc<tab> would expand out to ssh concentrator.

If there’s a port forward you use routinely on a host, such as forwarding a port on your local host to a local port on the remote server to access a C2 server’s admin port, you can use a LocalForward directive, specifying the <local IP>:<local port> <remote IP>:<remote port>. If you don’t specify a local IP, SSH will default to using localhost. The example below shows how to forward localhost port 40404/TCP on the client machine to localhost 40404/TCP on the server.

host teamserver
  hostname 10.10.0.2
  port 2222
  LocalForward 127.0.0.1:40404 127.0.0.1:40404

Similarly, you can set up a standard reverse port forward with a RemoteForward directive using the same syntax for hosts and ports. The example below would forward any requests coming to 10.10.0.3:8080 on the remote host to 127.0.0.1:8080 on the client.

host reverse-proxy
  hostname 10.10.0.3
  port 2222
  ReverseForward 10.10.0.3:8080 127.0.0.1:8080

To set up a SOCKS5 proxy every time you connect to a host, you can use the DynamicForward directive, which requires only the local IP and port to be specified. This block includes a DynamicForward directive which will open a SOCKS5 proxy on localhost port 9000/TCP every time you connect to the server.

host vps
  hostname 10.10.0.6
  port 2222
  DynamicForward 127.0.0.1:9000

To set common options used for multiple hosts, you can choose a naming scheme for those hosts and then use a wildcard host entry to set those common options. For example, let’s imagine we’re doing a penetration test of NoneSuch Ltd., and we have several pieces of infrastructure with port forwards we’re using for the test, including:

  • a C2 team server
  • a dropbox inside the client environment connected via VPN, and
  • a virtual private server we’re using to conduct external scans and testing

The team server will need a local port forward to access the C2 server’s admin port, and all three hosts will need SOCKS5 proxies on different ports. But they’ll all have some things in common, too, such as a port, a username, and a private key used for authentication. Also, we want to enable the escape command line on all connections (using host *, so we can use SSH control sequences to manage port forwards on the fly without having to end our session. That would give us a config file that looks like this:

host nonesuch-*
        port 22422
        user operator
        IdentityFile /home/operator/.ssh/nonesuch_id_ed25519

host nonesuch-teamserver
        hostname 10.0.10.2
        LocalForward 127.0.0.1:40404 127.0.0.1:40404
        DynamicForward 127.0.0.1:9000

host nonesuch-dropbox
        hostname 10.0.20.2
        DynamicForward 127.0.0.1:9001

host nonesuch-vps
        hostname 10.0.30.2
        DynamicForward 127.0.0.1:9002

host *
        EnableEscapeCommandLine yes

You could also use an SSH config file to streamline connections through a jumpbox. For example, if you had a series of VPN client hosts in a restricted VLAN, accessible only through a SSH jumpbox, you could use the ProxyCommand directive to make that jumpbox serve as a proxy server to transparently access those VPN hosts, as shown below.

host jumpbox
          hostname 10.100.0.1
          port 22422

host vpn-*
# %h and %p below are the host and port, and will draw from the other host entries
          ProxyCommand ssh jumpbox -W %h:%p
          user vpn-operator
          port 33533
          IdentityFile /home/operator/.ssh/vpn-id_ed25519
        
host vpn-1
          hostname 10.200.0.129
          
host vpn-2
          hostname 10.200.0.130
          
host vpn-3
          hostname 10.200.0.131
          
host vpn-4
          hostname 10.200.0.132
          
host vpn-5
          hostname 10.200.0.133

This is just scratching the surface of what you can do with an SSH config file, but it covers the day-to-day use cases that I’ve found to be really helpful. Taking just a few minutes to set up an SSH config file can remove little points of friction from your workflow and make everything go just that much more smoothly.


About Justin Palk, Senior Security Consultant:

Justin Palk has more than 16 years of experience in IT and information security, and has worked in the academic, federal civilian government and health research sectors. He has held a variety of roles including system administrator, developer, auditor, assessment team lead and web application penetration tester. He regularly competes in CTFs in the U.S. and Europe.

Certifications:
GCIH, GWAPT, GPEN, GMOB, GDSA

Connect on Twitter & LinkedIn

Extend Your Browser

By Red Siege | May 9, 2024

by Ian Briley, Security Consultant In my last blog, I discussed using only a browser for web application testing, emphasizing how useful built-in browser tools like the Inspector and Console […]

Learn More
Extend Your Browser

Introducing Delta Encoder

By Red Siege | April 15, 2024

By Corey Overstreet, Senior Security Consultant Recently, our own Mike Saunders released a novel shellcode obfuscation technique with the tool Jigsaw. If you haven’t checked out the GitHub repository or […]

Learn More
Introducing Delta Encoder

Using Microsoft Dev Tunnels for C2 Redirection

By Red Siege | April 9, 2024

by Justin Palk, Senior Security Consultant   As penetration testers, we’re always on the lookout for new ways to get our command-and-control (C2) traffic out of a client’s network, evading […]

Learn More
Using Microsoft Dev Tunnels for C2 Redirection

Find Out What’s Next

Stay in the loop with our upcoming events.