Here is a quick and dirty method for hiding some of the banner information advertised by OpenSSH. This article focuses on how to use hexedit to update your sshd binary to reduce information leakage.
Hiding the version information from OpenSSH is not supported by configuration. This may have been added in some versions and could be achieved by compiling your own version from source or switching to port knocking – these approaches are not covered.
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 and create large databases to search for servers running software with known vulnerabilities. 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 (126.96.36.199) Host is up (0.0044s latency). rDNS record for 188.8.131.52: 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 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.
- 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
- Escalate to a root session:
$ sudo su
- Install hexedit:
# apt-get update && apt-get install hexedit
- 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
- 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.
- Check if there are any instances that we missed (we expect no output now):
# strings /tmp/sshd.new | grep Rasp
- Update sshd and restart the service for good measure:
# rm /usr/sbin/sshd # cp /tmp/sshd.new /usr/sbin/sshd # systemctl restart ssh.service
- 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.
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.
(last checked 2018-01-06)