SSHd: hide daemon version and OS info
2008-02-18 14:49Oftenly network services give away information on what platform thay run. If you look what SSH daemon replies on your telnet request, you’ll see string like this probably:
SSH-1.99-OpenSSH_3.8.1p1 Gentoo-8.2.4
It is obvious that as on of security measures it is good idea to may harder for attacker to gain any information about system we protect; for example, well-known Linux Iptables Tutorial says: “The best thing to do, is to give as little material as possible for the attacker to get a proper fingerprint on.” I could imagine only one reason for such unsecure behaviour of SSH service: to allow collect statistic information. But if you are admin of this host, you know what OS is there. If you are not, it’s not your business, right?
In most OSes and distros there is no command-line or config file option to turn off such verbosity. So, at first, there are the one way to do this: get sshd source, patch it, compile it, and install it. And you should do this after each security update.
But we could apply the simple patch right on the sshd binary executable, because we know exactly what to change. SSH daemon is written in C, so all the text strings are plain text strings, starting at fixed offset fron begin of file are ended by zero-byte. We could easily modyfy such string, if it is unique in binary file an if new text will be no longer than original one. At the and we will put a zero byte, it will be interpreted as the end.
What exactly would we like our SSH to answer? Theoretcally, it should be anything starting with ‘SSH’, but in practice there are some restrictions. There are different ssh server implementations, and many clients use that banner string to recognize specific servers with specific bugs (i.e, if you have Putty (ssh client), look to “Connection”>”SSH”>”Bugs” screen in settings window). This topic on commercial SSH implementation forum states that minimal safe string would be ‘SSH-2.0-0′. My own expirience is limited, but there was no problem with such banner string.
Searching for tool, my first look was at unix utility ’sed’, but it is wrong tool for this job. As sed documentation says:
Specifically, use awk or perl if you need to: (…) handle binary data (control characters). (perl: binmode)
So, I use perl one-liner (look at ‘perlrun’ for more explanation):
PERLIO=':raw'; export PERLIO; perl -pi.bak -e 's{(OpenSSH)_([^\x00]+Debian)}{$1\x00$2}’ /usr/sbin/sshd
.
