Help with pbkdf2_hmac_'sha512' hashes
#1
I'm a complete newbie and I'm trying to crack hashes created with this python script:

Code:
import hashlib
import binascii

password = input('Give a password to hash: ')
salt = b"2213dcd3820c18c559cc389c8bd22e6b3b0b3f410f01ecf1aac95faf1716e169"
pwdhash = hashlib.pbkdf2_hmac('sha512', password('utf-8'),
                               salt, 100000)
pwdhash = binascii.hexlify(pwdhash)
print((salt + pwdhash).decode('ascii'))

Inputting "foobar" into this script gives this string:
2213dcd3820c18c559cc389c8bd22e6b3b0b3f410f01ecf1aac95faf1716e169efee941dfcde93b0d550998db85b9773ca0a2e7f2ef59e9a4b1f1b630e7797437bfd7846cfef6e50d440c8e1e633bd4cc8a5381292e9221a1dd40fe77cc4b04b

Trying to crack it I wrote this python script to put hashes like this into the right format for hashcat:

Code:
import base64

with open("passwords.hash") as f:
   content = f.readlines()
content = [x.strip() for x in content]

f = open("passwords2.hashes", "a")
for hashes in content:
   beginning = "sha512:100000:"
   salt = hashes[:64].decode("hex").encode("base64")+":"
   password = hashes[64:].decode("hex").encode("base64")
   hashCatFormat = (beginning+salt+password).replace("\n","")
   f.write(hashCatFormat+"\n")

which turns the hash for foobar into:
sha512:100000:IhPc04IMGMVZzDici9IuazsLP0EPAezxqslfrxcW4Wk=:7+6UHfzek7DVUJmNuFuXc8oKLn8u9Z6aSx8bYw53l0N7/XhGz+9uUNRAyOHmM71MyKU4EpLpIhod1A/nfMSwSw==


I then created a textfile foo.txt which just reads "foobar" .

Unfortunately running:
$hashcat -m 12100 -a 0 -o cracked.txt passwords2.hash foo.txt

does not recover the example hash. What am I doing wrong?
Reply
#2
you first script (the hash generator) doesn't use the binary input, while your second script hex-decodes it and converts it to base64.

This line
Code:
salt = b"2213dcd3820c18c559cc389c8bd22e6b3b0b3f410f01ecf1aac95faf1716e169"

should be this:
Code:
salt = "2213dcd3820c18c559cc389c8bd22e6b3b0b3f410f01ecf1aac95faf1716e169".decode ('hex')

and then it should work fine.


What this means is that your 2 scripts are not currently interpreting the salt the same way. One says the salt is already AS-IS and using the raw bytes, while the other one says it should be converted to binary first (and then base64 decoded).


BTW: just concatenating salt and digests/hashes without a separator might also be quite dangerous, because what happens if there should be some leading zeros (but they are omitted because python doesn't have a fixed size for every hex string) etc... you would at least need to zero-pad it to a fixed size... (btw: there are a couple of projects that made this same error and lost a lot of money for doing these strange let's-just-concat-everything strategies).
I understand that you think that the first 64 bytes are always the salt, but what happens if the salt consist of 4 leading zeros (if the salt changes too, which should be the case of course for every different hash) and they do not end up in the output because of the non-fixed-hex-length?
Reply
#3
(02-03-2019, 09:35 AM)philsmd Wrote: you first script (the hash generator) doesn't use the binary input, while your second script hex-decodes it and converts it to base64.

This line
Code:
salt = b"2213dcd3820c18c559cc389c8bd22e6b3b0b3f410f01ecf1aac95faf1716e169"

should be this:
Code:
salt = "2213dcd3820c18c559cc389c8bd22e6b3b0b3f410f01ecf1aac95faf1716e169".decode ('hex')

and then it should work fine.


What this means is that your 2 scripts are not currently interpreting the salt the same way. One says the salt is already AS-IS and using the raw bytes, while the other one says it should be converted to binary first (and then base64 decoded).

Thank you so, so much! That finally worked. Since my task was to crack hashes from the first script I adjusted my second one like so:
Code:
import base64

with open("passwords.hash") as f:
    content = f.readlines()
content = [x.strip() for x in content]
salt = b"2213dcd3820c18c559cc389c8bd22e6b3b0b3f410f01ecf1aac95faf1716e169"
salt = salt.encode("base64")

f = open("passwords2.hash", "a")
for hashes in content:
   beginning = "sha512:100000:"
   password = ":"+hashes[64:].decode("hex").encode("base64")
   hashCatFormat = (beginning+salt+password).replace("\n","")
   f.write(hashCatFormat+"\n")

This finally did the trick.


Quote:BTW: just concatenating salt and digests/hashes without a separator might also be quite dangerous, because what happens if there should be some leading zeros (but they are omitted because python doesn't have a fixed size for every hex string) etc... you would at least need to zero-pad it to a fixed size... (btw: there are a couple of projects that made this same error and lost a lot of money for doing these strange let's-just-concat-everything strategies).

I understand that you think that the first 64 bytes are always the salt, but what happens if the salt consist of 4 leading zeros (if the salt changes too, which should be the case of course for every different hash) and they do not end up in the output because of the non-fixed-hex-length?

Yes that makes a lot of sense. I will pass this on to the author of the first script.




Again thank you very much!
Reply