OpenSSH stores lists of SSH public keys in known_hosts files, so it can verify that the host you're logging into is the host you expect and not a man-in-the-middle attacker. To reduce the risk of island-hopping attacks, OpenSSH has a HashKnownHosts yes option to store HMAC-SHA1 encrypted versions of host names and IPs in your known_hosts files rather than the clear text. This makes it harder for an attacker to use the information stored in your known_hosts. However, it also makes it harder for you to use that information.

I was digging through my known_hosts file yesterday compiling a list of servers where I have login accounts. I keep better track of these things recently (using GPG to symmetrically encrypt the list), but my known_hosts file predates my quality-accounting phase. Anyhow, I wrote up some simple tools to make reverse-engineering a known_hosts file a bit less painful.

You can use your monkeysphere keyring to see if you recognize any of the public keys. This avoids having to deal with the hashed names at all, but assumes none of your servers are sharing keys. unhash-known-hosts.sh automates this:

$ unhash-known-hosts.sh path/to/known_hosts
GnuPG ID 01234567 (ssh://server.example.net) matches |1|Bvjsg3lqJJ/M9rTYz1HfY+T/RoM=|DhZlGg3GFMWtVcjz4LNfJ8afi7w=
did not match |1|vug6FlX6GCaIIzkv3wS3zftQyyw=|PdMYEIaWTzHCv/4ZhNiR2DD6E0A=
...

Once you've got the low-hanging fruit out of the way, you can get a list of the high-hanging fruit:

$ unhash-known-hosts.sh path/to/known_hosts | sed -n 's/^did not match //p' > unknown_hosts

Start guessing with crack known hosts.py! IPs are usually a good starting point, because any host in your known_hosts file must have an entry for its IP.

$ crack_known_hosts.py --known-hosts unknown_hosts --ip 192.168.*.*

You can also run a full scan of alphanumeric entries up to a specified length (this gets slow quickly, which is, after all, why you hashed the entries in the fiest place).

$ crack_known_hosts.py --known-hosts unknown_hosts --alphanum 16

Removing entries from unknown_hosts as you crack them will make future crack_known_hosts.py attempts on that file faster.

Once you've cracked one name, you can use unique known hosts.py to find other entries that share the same key.

$ unique_known_hosts.py path/to/known_hosts

And there you have it. Happy cracking! ;).