One type of attack against computers on the Internet is sometimes referred to as "island-hopping". These attacks exploit trust relationships between systems, user accounts common across several systems, as well as user-customizable access control to allow an attacker to jump from system to system. In fact, the first worm released on the Internet back in 1988 was built upon this model. We're going to examine a contemporary variety of this attack where the attacker uses ssh to get around from system to system.
When you ssh to a remote server, your ssh client records the hostname, IP address and public key of the remote server in a file called known_hosts. When initiating subsequent ssh sessions, your ssh client compares the hostname, IP address and ssh key for the remote server to what was recorded earlier in your known_hosts file. If there are discrepancies, your ssh client either will abort the connection attempt or display an error message. This is good for a number of reasons, most importantly to stop man-in-the-middle attacks (MITM) where the attacker tries to hijack your ssh session by assuming the identity of the remote server. The bad news is that if an attacker takes over your account, they have a laundry list of other servers you have access to sitting right there in the known_hosts file.
Let's look at an example: An attacker has discovered a user's password on a server and successfully authenticates to the server through ssh. Once logged in the attacker views the contents of the victim's known_hosts file by simply doing a 'cat ~/.ssh/known_hosts'. This informs the attacker of at least some of the other servers where the victim has accounts. It is very likely that those accounts have the same password. The attacker then ssh's to all those servers, examining the victim's known_hosts files on each one. This can go on until the attacker owns all of the victim's user accounts on all the servers they have access to.
There are several effective methods of limiting the damage once the attacker has gained access to the first account, including two-factor authentication, using different passphrases for different systems, as well as hashing the known_hosts file. However, this article will only examine hashing the known_hosts file.
Beginning with the release of OpenSSH version 4.0, a new configuration directive was introduced: 'HashKnownHosts yes'. When you set this option in your ssh_config file, ssh will start recording a one-way cryptographic hash of the hostname and IP address rather than recording them in clear text. Later, when initiating subsequent ssh sessions, your ssh client will hash the hostname you type and look it up in the known_hosts file to find the previously-recorded ssh host key for the remote server. You will effectively still be able to automatically verify ssh host keys but attackers won't be able to harvest hostnames and IP addresses from the known_hosts file.
To illustrate the difference, here's an example known_hosts entry berore:
hostname.domain.com,192.168.0.1 ssh-rsa AAAAB3NzaC1yc2EAAAABI wAAAIEA1XY18+zA8VNK2YkzygOkMqUxHSTfxT1Xxx8CgDZgcQH8HUhPssW5tt vG8nKetlPQZAVk1C4WkWS1y5b3ekBhZTIxocp9Joc6V1+f2EOfO2mSLRwB16R Grdw6q7msrBXTC/dl+hF45kMMzVNzqxnSMVOa0sEPK2zK6Sg3Vi9fCSM=
...and after:
|1|BWO5qDxk/cFH0wa05JLdHn+j6xQ=|rXQvIxh5cDD3C43k5DPDamawVNA= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEA1XY18+zA8VNK2YkzygOkMqU xHSTfxT1Xxx8CgDZgcQH8HUhPssW5ttvG8nKetlPQZAVk1C4WkWS1y5b3ek BhZTIxocp9Joc6V1+f2EOfO2mSLRwB16RGrdw6q7msrBXTC/dl+hF45kMMz VNzqxnSMVOa0sEPK2zK6Sg3Vi9fCSM=
Please note that by default, OpenSSH will not hash the known_hosts file. You will need to enable the option for it to go into effect. Also to note is that enabling the option will not hash the existing entries in your known_hosts file. Only additions to the file made after the change will be hashed. To hash the hostnames and IP addresses in an existing known_hosts file, issue the following command: 'ssh-keygen -H'. After doing so, you will see a message like this:
/home/<you>/.ssh/known_hosts updated. Original contents retained as /home/<you>/.ssh/known_hosts.old WARNING: /home/<you>/.ssh/known_hosts.old contains unhashed entries Delete this file to ensure privacy of hostnames
Don't forget to delete ~/.ssh/known_hosts.old.
Sysadmins particularly concerned about security will often keep a system-wide ssh_known_hosts file with the public keys for all the servers in their groups' infrastructure. By default, it is located here: '/etc/ssh/ssh_known_hosts'. Additionally, they might disable their users' ability to add and change host keys on the fly by setting this configuration directive: 'StrictHostKeyChecking yes'. These two measures are quite effective in stopping a user from falling pray to an MITM attack. However, there is still the problem of hostnames and IP addresses recorded in clear text. In order to hash an existing system-wide ssh_known_hosts file, issue the following command as root: 'ssh-keygen -H -f /etc/ssh/ssh_known_hosts'.
Don't forget to delete /etc/ssh/ssh_known_hosts.old.
The ITSO recommends enabling the 'HashKnownHosts yes' and 'StrictHostKeyChecking yes' options in all ssh installations as well as hashing the contents of all existing users' known_hosts files and system-wide ssh_known_hosts files.