SHA1_HMAC for unknown text
#1
Im interested in brute-forcing known_hosts files for SSH, these look like this:

|[int]|[base64 SALT]|[base64 TARGET] ssh-rsa [base64]

These are SHA1_HMACs of the IP address or hostname where the Text (not the salt or key) is the password. (The Int at the beginning of the string defines the type of SHA hash e.g. 1, 256, 512).

e.g. if hmac.new(SALT, GUESS, sha1).digest() == TARGET then you have a match.

Hashcat has the modes 150 and 160 but nothing for unknown Text. Would it be hard to add support for this? I think it has some valuable uses when identifying hosts to move laterally within networks.
#2
What do you mean by "unknown text"? What is the technical difference to a password?
#3
For the example below:

#|1|cISUEz2xxa7ZeaVeGBzNjHRF5tU=|Td1EXemzcxAGovyEkvHYUx+UorQ= rsa-key blahblah

If we convert to hex we have:

17513529ea04fde116862d745a91afe0e7623ba6:dfdf3c415d1513cc2664beecb8dad840b2132c28

In this case the output of the hmac is known dfdf3c415d1513cc2664beecb8dad840b2132c28 and the key used is known 17513529ea04fde116862d745a91afe0e7623ba6 but I dont know the text that was hmac'd (in this case 192.168.1.61)
#4
isn't that just the same as hmac-sha1(key = $pass)?

edit: according to the argument order of hmac it should probably be hmac-sha1(key = $salt)
#5
I dont think so but I could be completely mis-reading this. I have the key (17513529ea04fde116862d745a91afe0e7623ba6) but I dont know the plain text that was hmac'd (192.168.1.61) - its the plain text I want to brute-force

If it helps this is what I used to brute-force it in python (where tkey.txt) contains:

|1|F1E1KeoE/eEWhi10WpGv4OdiO6Y=|3988QV0VE8wmZL7suNrYQLITLCg= ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgwCZx9lGaY+Zhz98TdWqZ01mTzOwRnQO0EIBM8Hx8olxMbrQ1Xa+x/7LBoGyJqeYFunZbFCVpAu+2SBkvf75qV8nTlq3WXnLnprsH5Sq/c9f29ZCcMHevI


Python:

import base64
import hmac
from hashlib import sha1

if __name__ == '__main__':
for kh in open("tkey.txt"):
print (kh.strip())
parts = kh.strip().split("|")
if len(parts) < 2:
continue

saltb64 = parts[2]
targetb64 = parts[3].split(" ")[0]

salt = base64.b64decode(saltb64)
target = base64.b64decode(targetb64)

for a in ["192"]:
for b in range(160, 256):
print(b) # For debugging
for c in range(0, 256):
for d in range(0, 256):

message = bytes("%s.%s.%s.%s" % (a,b,c,d), "ascii")
hashed = hmac.new(salt, message, sha1).digest()

if target == hashed:
print("%s|%s -> %s" % (salt.hex(), target.hex(), message))
print("%s|%s -> %s" % (saltb64, targetb64, message))
quit()
#6
you should be able to crack this by using
dfdf3c415d1513cc2664beecb8dad840b2132c28:17513529ea04fde116862d745a91afe0e7623ba6 --hex-salt -m 160
#7
Ah, thanks Smile I was missing --hex-salt Smile

dfdf3c415d1513cc2664beecb8dad840b2132c28:17513529ea04fde116862d745a91afe0e7623ba6:192.168.1.61
#8
Heres a IPv4 hcmask if anyone is in the same situation.

python3 parse_knownhosts.py.txt .ssh/known_hosts > unknown

dfdf3c415d1513cc2664beecb8dad840b2132c28:17513529ea04fde116862d745a91afe0e7623ba6

hashcat -m 160 --hex-salt -m 160 unknown -a 3 ipv4.hcmask.txt


Attached Files
.txt   parse_knownhosts.py.txt (Size: 342 bytes / Downloads: 4)
.txt   ipv4.hcmask.txt (Size: 3.67 KB / Downloads: 6)
#9
btw, here is a mask file for ipv4 addresses without leading zeros: https://pastebin.com/4HQ6C8gG
#10
Ah nice, I found it slower to process all of those rules for a single hash - I guess it'd be faster for longer lists tho?