OpenSSH

Hide OpenSSH Version Banner

Here is a quick and dirty method for hiding some of the banner information advertised by OpenSSH[1]. This article focuses on how to use hexedit[2] to update your sshd binary to reduce information leakage.

Hiding the version information from OpenSSH is not supported by configuration[3]. This may have been added in some versions[4] and could be achieved by compiling your own version from source or switching to port knocking – these approaches are not covered.

Problem

SSH Servers such as OpenSSH advertise information such as protocol support, build version and host operating system. For example:

$ nc example.local 22
 SSH-2.0-OpenSSH_7.4p1 Raspbian-10+deb9u2

Would be attackers scan the internet[5] and create large databases to search for servers running software with known vulnerabilities[6]. While this may have somewhat legitimate uses such as research into market share of SSH servers or for system admins monitoring their network for machines requiring patches; its generally not a good idea to give away such information freely to the Internet.

You can also use telnet or nmap to snoop on the same information e.g:

$ nmap -A -T4 -p 22 example.local

Starting Nmap 7.60 ( https://nmap.org ) 
Nmap scan report for example.local (1.2.3.4)
Host is up (0.0044s latency).
rDNS record for 1.2.3.4: 1-2-3-4.kram.nz

PORT STATE SERVICE VERSION
22/tcp open ssh (protocol 2.0)
| fingerprint-strings:
| NULL:
|_ SSH-2.0-OpenSSH_7.4p1 Raspbian-10+deb9u2
$ telnet example 22
Trying ::1...
Connected to example.
Escape character is '^]'.
SSH-2.0-OpenSSH_7.4p1 Raspbian-10+deb9u2

Removing the Banner

Warning: Doing this while connected via SSH is risky as you can lock yourself out. If you are, set up a way to recover the original binary (i.e. set up another way to connect to the machine or a cron job to restore a copy of the original).

These steps use the hexedit[2] tool which is light weight and should be in your package manager. The goal is to write over the existing version string with text of your choice. The instructions are written for Debian / Systemd from steps followed on a Raspberri Pi running Raspbian.

  1. Check the current banner:
    $ echo "Hello" | nc localhost 22
    SSH-2.0-OpenSSH_7.4p1 Raspbian-10+deb9u2
    Protocol mismatch.

    In this case, the part of the banner we want to hide is “OpenSSH_7.4p1 Raspbian-10+deb9u2” which is broadcasting the versions of my SSH server and operating system. Hiding the protocol is a bit harder and not covered here.
    We can see this in the binary too:

    $ strings /tmp/sshd.new | grep Rasp
    OpenSSH_7.4p1 Raspbian-10+deb9u2
  2. Escalate to a root session:
    $ sudo su
  3. Install hexedit:
    # apt-get update && apt-get install hexedit
  4. Back up your sshd binary and create an editable working copy (as root):
    # cp /usr/sbin/sshd /tmp/sshd.backup
    # cp /tmp/sshd.backup /tmp/sshd.new
  5. Update the binary with hexedit:
    # hexedit /tmp/sshd.new

    Press TAB to switch from the HEX are to the ASCII area
    Use CTRL+S to bring up the search prompt and search for the text in your banner than you want to hide e.g. ‘OpenSSH_7.4’. You should see something like:

    0007DA54   61 67 65 6E  74 00 00 00  4F 70 65 6E  agent...Open
    0007DA60   53 53 48 5F  37 2E 34 70  31 20 52 61  SSH_7.4p1 Ra
    0007DA6C   73 70 62 69  61 6E 2D 31  30 2B 64 65  spbian-10+de
    0007DA78   62 39 75 32  00 00 00 00  4F 70 65 6E  b9u2....Open

    Use the arrow keys to highlight the start of the string that you want to update and type your replacement. Be careful to stay within the bounds of the length of the original banner. You can also press TAB to switch back to the HEX area if you wanted to just null out the string setting each word to ’00’.
    Your change should look something like:

    0007DA54   61 67 65 6E  74 00 00 00  48 65 72 65  agent...Here
    0007DA60   20 62 65 20  64 72 61 67  6F 6E 73 2E   be dragons.
    0007DA6C   20 54 75 72  6E 20 42 61  63 6B 00 00   Turn Back..
    0007DA78   00 00 00 00  00 00 00 00  4F 70 65 6E  ........Open

    Save your changes with CTRL+x and a Y.

  6. Check if there are any instances that we missed (we expect no output now):
    # strings /tmp/sshd.new | grep Rasp
  7. Update sshd and restart the service for good measure:
    # rm /usr/sbin/sshd
    # cp /tmp/sshd.new /usr/sbin/sshd
    # systemctl restart ssh.service
  8. Check that you can still SSH in (otherwise restore the backup or reinstall OpenSSH from your package manager!):
    # ssh user@localhost

This change will only be temporary as any time you update OpenSSH, the binary will be replaced.

Result

The process above will result in something like the following:

$ nc localhost 22
SSH-2.0-Here be dragons. Turn Back

Where before this would be along the lines of:

$ nc localhost 22 
SSH-2.0-OpenSSH_7.4p1 Raspbian-10+deb9u2

Which makes it just a little bit more obscure and secure.

References

(last checked 2018-01-06)

  1. https://www.openssh.com/
  2. https://sourceforge.net/projects/hexedit/
  3. https://man.openbsd.org/sshd_config.5
  4. https://scottlinux.com/2011/06/14/disable-debian-banner-suffix-on-ssh-server/
  5. http://resources.infosecinstitute.com/masscan-scan-internet-minutes/
  6. https://www.shodan.io/
  7. https://serverfault.com/questions/81690/how-to-hide-web-server-name-and-openssh-version-on-linux-when-scanning-server-po