120

I would like to see what hosts are in my known_hosts file but it doesn't appear to be human readable. Is it possible to read it?

More specifically there is a host that I can connect to via several names and I want to find out what the fingerprint I expect for it from my known hosts file.

Update: I'm using OpenSSH_5.3p1 Debian-3ubuntu7, OpenSSL 0.9.8k 25 Mar 2009

A line from my known_hosts file looks something like this,

|1|guO7PbLLb5FWIpxNZHF03ESTTKg=|r002DA8L2JUYRVykUh7jcVUHeYE= ssh-rsa AAAAB3NzaC1yc2EAAFADAQABAAABAQDWp73ulfigmbbzif051okmDMh5yZt/DlZnsx3DEOYHu3Nu/+THJnUAfkfEc1XkOFiFgbUyK/08Ty0K6ExUaffb1ERfXXyyp63rpCTHOPonSrnK7adl7YoPDd4BcIUZd1Dk7HtuShMmuk4l83X623cr9exbfm+DRaeyFNMFSEkMzztBYIkhpA2DWlDkd90OfVAvyoOrJPxztmIZR82qu/5t2z58sJ6Jm2xdp2ckySgXulq6S4k+hnnGuz2p1klviYCWGJMZfyAB+V+MTjGGD/cj0SkL5v/sa/Fie1zcv1SLs466x3H0kMllz6gAk0/FMi7eULspwnIp65g45qUAL3Oj
143

You've got HashKnownHosts set to "yes" in your ssh_config file, so the hostnames aren't available in plaintext.

If you know the hostname you're looking for ahead of time, you can search for it with:

    ssh-keygen -H -F hostname

Here's the relevant section from the ssh-keygen(1) man page:

 -F hostname
         Search for the specified hostname in a known_hosts file, listing
         any occurrences found.  This option is useful to find hashed host
         names or addresses and may also be used in conjunction with the
         -H option to print found keys in a hashed format.
  • 3
    Does hash known hosts essentially mean it's not possible? i.e. I need to know the name of the host in order to look at it's info? – Colin Newell Feb 13 '12 at 15:54
  • 7
    @ColinNewell That's right, you need to know the hostname(s). It's a security measure to keep an attacker from harvesting hostnames/IP addresses of other boxes you frequent if your machine is compromised. – pdo Feb 13 '12 at 15:58
  • 1
    Don't be scared when there is no output at all, but try not the full qualified hostname but the hostname instead. – math May 7 '13 at 17:58
  • 6
    Not sshd_config, but ssh_config. – Fish Monitor Nov 21 '13 at 10:31
  • 10
    @pdo - your command does not always work. If the host has SSH on port other than 22, then the format in known_hosts is different. Then you have to use the following command: ssh-keygen -H -F [host.example.com]:2222 – Martin Vegter Jul 13 '14 at 15:56
17

For future searchers, this article (non-disclaimer: I'm not affilated) has a relatively simple Perl script to brute-force hashed IPs and hostnames in known_hosts.

http://blog.rootshell.be/2010/11/03/bruteforcing-ssh-known_hosts-files/

It allows starting from a particular IP address. It could also easily be modified to use a dictionary.

Also, in June 2014, the John the Ripper project added support for known_hosts cracking, which can take advantage of multiple CPU cores, GPUs, dictionary mangling, etc.

You can also use this nmap snippet to generate a dictionary of all RFC1918 IP addresses to use as a dictionary:

nmap -sL -Pn -n 192.168.0.0/16 172.16.0.0/12 10.0.0.0/8 |\
    grep '^Nmap scan report for' | cut -d\  -f5 >ips.list
4

Does ssh-keygen -l -f ~/.ssh/known_hosts help? (Using -vyou also get nice little treasure maps, e.g.

+--[ RSA 2048]----+
|        .        |
|       + .       |
|      . B .      |
|     o * +       |
|    X * S        |
|   + O o . .     |
|    .   E . o    |
|       . . o     |
|        . .      |
+-----------------+
  • 2
    Not in the strictest sense no, it's all still base64. pdo's explanation of it being hashed suggests it's a one way thing so I guess I'm stuck unless I know the hostname. – Colin Newell Feb 13 '12 at 15:57
  • That helped me. What I wanted specifically was a combination. To find the previously verified ssh fingerprint, you can run: ssh-keygen -l -f ~/.ssh/known_hosts -F <hostname> – isaaclw Sep 22 '15 at 21:30
  • uh, ssh-keygen -l -F <hostname> is even simplier – isaaclw Sep 24 '15 at 15:08
2

There is host string/ip at the beginning of each "known_hosts" line (before the "ssh-dss" or "ssh-rsa" string):

hostgn6 ssh-dss AAAB3NzaC1kc3MAAACBAIfGV4+/28Zr+dT/i+ifydUBS0dMRUjCtExIThOj3Yexynu+wSRGjMm4GfF+og2kAljZyUjhBFeM+WYbJzcDSDB [...] ==
yumyumn6.dik6.dir2g.some.net ssh-dss AAAAB3NzaC1kc3MAAACBAIfGV4+/28Zr+dT/i+ifydUBS0dMRUjCtExITh [...] ==
  • 2
    ...and thus awk '{print $1}' known_hosts does the trick. Be aware that servers listening on non-standard ports end up as, say, [some-server]:5555 in known_hosts. – sr_ Feb 13 '12 at 14:35
  • 3
    Unfortunately not in mine. Mine looks more like base64 encoded data. The data is also pipe delimited in my file. – Colin Newell Feb 13 '12 at 14:40
  • Which ssh software are you using then (we were assuming that you were using the almost-standart openssh software) ? – Ouki Feb 13 '12 at 14:49
  • I've added more details to my question. – Colin Newell Feb 13 '12 at 15:11
  • 7
    As stated by @pdo, your sshd as "HashKnownHosts" set to on, which may appear a bit anal, but security concern it is. And of course there is no way to simply reverse the hashes and get the hostnames from your "known_hosts". – Ouki Feb 13 '12 at 15:41
2

Use the -l option to ssh-keygen to list fingerprints, and the -F option to search for a hostname in your known_hosts file.

$ ssh-keygen -l -F sdf.org
# Host sdf.org found: line 835 type RSA
2048 6e:cd:53:4f:75:a1:e8:5b:63:74:32:4f:0c:85:05:17 |1|9J47PEllvWk/HJ6LPz5pOB2/7rc=|ld0BtQh5V3NdhBHBwR/ZqSv8bqY= (RSA)

You can use ssh-keyscan to compare the fingerprint in your known_hosts to the one from the server.

$ ssh-keyscan sdf.org | awk '{print $3}' | base64 -d | openssl md5 -c
# sdf.org SSH-2.0-OpenSSH_7.1
# sdf.org SSH-2.0-OpenSSH_7.1
no hostkey alg
(stdin)= 6e:cd:53:4f:75:a1:e8:5b:63:74:32:4f:0c:85:05:17

Not the answer you're looking for? Browse other questions tagged or ask your own question.