Lesser Known Trickery for Unmasking Hashed known_hosts Entries.
After seeing this tweet by Craig, and remembering that you can just bruteforce hashed known_hosts entries with Hashcat or similar, I was having my morning dose of wakey wakey stuff and had a realisation that I don't think anyone else has documented. So I thought I'd note it down.
Lets look at the hashed ssh format again.
We generated a test file by SSH'ing (but not authenticating) to a random internet host with SSH open for the purposes of this demonstration.
# cat test_known_hosts
|1|lMGYt1yxsIf+pJcok1PpatAnOPU=|0k/zYt2gyj7Av/710k5DEcmthJs= ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCoWUv45k64FE/1Wq52JEk9mv6PuM87VHinKPUxORwe1ea1H2Uy3sf3+TnlON1KdkI1JwUtUfUXIPXI9OcouDdRUw3OC6gYaNXR8yFCGt9L4/OekMzcp/Pa0o1TDCt1x7nDYJgbM9NIygL54cPDLCpdK9cEHX0SGme49BCQvtROFyG6/fuE32OLoXII2M1oxDnuvuUTsYZyFIu2hoplASGxzxT6QqH+nttsiLZ9BSlOQma0zQfmML5s5myTfOZ8PpAGuSdzDfEXoSxNf/kD6uGs5dmI+YorjneiBiEp9ske/mGN/P3qnEGT1iLvFBV42j/oSVMoD/S4Fs6Fc7KwjFnL
Now, the first bits of that are where the IP and its salt live. We could crack those, but - why burn CPU/GPU time? The second half is more interesting.
The second half is the SSH public key of the SSH server that was connected to - SSH is a TOFU (trust on first use), and the known_hosts file exists to record the public key for each host.
Now, lets take that public key.
# cat test_known_hosts | cut -d ' ' -f 2,3 > test.pub
# cat test.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCoWUv45k64FE/1Wq52JEk9mv6PuM87VHinKPUxORwe1ea1H2Uy3sf3+TnlON1KdkI1JwUtUfUXIPXI9OcouDdRUw3OC6gYaNXR8yFCGt9L4/OekMzcp/Pa0o1TDCt1x7nDYJgbM9NIygL54cPDLCpdK9cEHX0SGme49BCQvtROFyG6/fuE32OLoXII2M1oxDnuvuUTsYZyFIu2hoplASGxzxT6QqH+nttsiLZ9BSlOQma0zQfmML5s5myTfOZ8PpAGuSdzDfEXoSxNf/kD6uGs5dmI+YorjneiBiEp9ske/mGN/P3qnEGT1iLvFBV42j/oSVMoD/S4Fs6Fc7KwjFnL
This corresponds to the public host key of the SSH server being connected to in this example.
We can search for these on engines such as Shodan or Censys by generating a fingerprint from this public key with ssh-keygen
.
# ssh-keygen -E md5 -lf test.pub
2048 MD5:8f:57:65:f5:62:2a:c3:a0:b8:d3:36:c6:f6:95:e7:14 no comment (RSA)
We then simply search this fingerprint using the Shodan search engine, and see if we get a hit.
This is it. We found the box from the known_hosts file, without bothering doing any time consuming cracking.
So, the lesson is: if you have popped some shell account on an authorised intrusion activity, but the known_hosts are hashed and you want to see where their login might work without burning CPU time that could be better spent cracking other things, just look up the fingerprints.
As an aside: This also nicely gets around the problem of if the user used ssh to a domain name instead of a bare IP - doing a bruteforce on a domain will take a shitload longer, and be less likely to succeed, than bruting an IP address.