Hacker News new | ask | show | jobs
by bcaa7f3a8bbc 2817 days ago
TL;DR:

OpenSSH uses ~/.ssh/known_hosts to record IPs, ports and public key fingerprints of, well, known SSH hosts. But it was argued many years ago that, the IPs and ports in known_hosts from a compromised system, can help attackers and viruses to discover more hosts to compromise. As a defense, OpenSSH introduced HashKnownHosts. Instead of saving IPs and addresses in plaintext, it saves HMAC-SHA1(host, salt). Some systems enable it by default, but most don't.

This research project showed that, it's still vulnerable to brute-force attacks, especially from GPUs, just like every password storage scheme, and explained the issue with proof-of-concept tools. Finally, the difficulty and impracticability is stated by the authors,

> It doesn't seem like there would be a clear solution. If they used a more expensive hashing algorythm like bcrypt, the GPUs could still crack the entire IPv4 address space. [...] Also, if bcrypt was used, this could cause slowness or performance issues potentially, especially for lower powered embedded devices.

But my personal opinion is, the entire thing just doesn't make much sense... Computing 10,000 rounds of PBKDF2, or a state-of-art KDF like Argon2 (which can consume ~4 GB of memory as the "Proof-of-Work" to stop GPUs), but just for protecting a humble IP address, seriously? Even if you guard your IP address like a private key, a attacker with a grid of GPUs probably can still use their resources to get the information from elsewhere, like, capture some packets, or scan the entire IPv4 Internet with ZMAP...

To me, if you seriously need to hide your hostname for your security, I would say the security is broken anyway... But in case it is really needed, to my mind there are two permanent solutions -

1. Use IPv6.

2. Introduce EncryptKnownHosts. You can implement it yourself using a shell script calling gpg before spawn an SSH instance.

Unlike 10,000 rounds of PBKDF2, this solution is absolute.

2 comments

You could just run `history | grep ssh` and look at all the domain names that show up.
That is true and it is the first place I usually check when I compromise a new server.

This wasn't mentioned in the post but imagine you compromised a server and found an unprotected ssh key. You don't know where it can be used, and the .bash_history has rolled over or has very few ssh commands in it. You see a lot of hosts in the known_hosts file though but it is hashed. That is where this would be helpful, and is why I went down this route.

Let's suggest an alternative scenario - the hosts and ports are encrypted.

Now what can the attackers do? Well, they still have hashes of public keys. The attacker can scan the entire IPv4 Internet with Z-MAP, and record all SSH public keys. With some hashing, the host can be identified. With online services like Censys (https://censys.io/), the attackers don't even have to scan and compute, but can directly obtain the information from a public database...

Also, to make it clear, while I'm saying that the attack is too impractical to make sense, I have full respect to your research project, thanks for analyzing this security issue for the community.

> first place I usually check when I compromise a new server

Probably don't want to admit publicly that you compromise servers, though I assume you mean with consent. :-)

Yes, with concent of course (Red Teaming).
Or run nmap, or look at your own IP address and just guess at it, or look at your /var/log/messages and ssh logs, all of which are likely just as effective and way less time-consuming than cracking hashed host information.

This isn't really a vulnerability. It's a curiosity. If you're on the sever (or NFS), and have access to this information already, then you're already in pretty damn good shape. This just allows you to be more thorough.

IMHO, the conclusion is that HashKnownHosts is as harmfull than usefull because it creates a false sentiment of security.