hackmdio codimd Scrypt.kdf hash format
#1
I am trying to figure out how to audit hashes created by codimd open source software. Does anyone have any suggestions about re-formatting the password hashes for hashcat input?

Based on the code it looks like they are using NMP Scrypt.kdf
e.g. https://github.com/hackmdio/codimd/blob/...ls/user.js

For example I created a local docker installation of codimd and created a few user accounts with password lower case "a". The corresponding password hashes are stored in the database user table.

736372797074000e00000008000000011ebbfa9c2fd52e92f40903bc74ca18c54713990e72e789779e099f635faf42fea5e77289edfaf53a861aa55bd1db8d7f7c0cadcaf2cdc940210635115b1804554a1956c7e6616d78846c458e55800d3b

736372797074000e00000008000000018fb85c39632adb2ba7d599adccb839f37cced14770f1e6a45e7bee8a240a6d7e4c7e2033b74c8a19445553e46ed9bbfe5c446798ea47962380f5293d27ce5c6fcfb7d3b46530642845a7efd0d7837e21

Does anyone have any ideas about how to wrangle this hash into a format that will be accepted as input for hashcat. I think the closest mode may be 8900.
  • It seems that I will need to base64 the salt and digest. Based on the code, I believe the current format is hex. I'm not sure if I will have to convert to binary before base64 encoding or not.
  • I'm still not sure how to find / determine the salt. The hashes all share a common prefix so maybe they use a common salt such as uptime?
  • I'm still trying to figure out how to determine the P,n,r for 8900 format e.g. SCRYPT:1024:1:1:

Comments / tips are appreciated
Reply
#2
from https://hashcat.net/forum/thread-5765.html
SCRYPT:N:r:p:base64(salt):base64(digest)

from https://github.com/chrisveness/scrypt-kd...crypt.d.ts
const params = Scrypt.pickParams(0.1); // => e.g. { logN: 15, r: 8, p: 1 }

logN = 15 --> N = 2**15 = 32768

So I understand my input format should start with
SCRYPT:32768:8:1
Reply
#3
related forum article
re: https://hashcat.net/forum/thread-5765.html
Reply
#4
https://github.com/Tarsnap/scrypt/blob/master/FORMAT


scrypt encrypted data format

----------------------------



offset length

0 6 "scrypt"

6 1 scrypt data file version number (== 0)

7 1 log2(N) (must be between 1 and 63 inclusive)

8 4 r (big-endian integer; must satisfy r * p < 2^30)

12 4 p (big-endian integer; must satisfy r * p < 2^30)

16 32 salt

48 16 first 16 bytes of SHA256(bytes 0 .. 47)

64 32 HMAC-SHA256(bytes 0 .. 63)

96 X data xor AES256-CTR key stream generated with nonce == 0

96+X 32 HMAC-SHA256(bytes 0 .. 96 + (X - 1))



AES256-CTR is computed with a 256-bit AES key key_enc, and HMAC-SHA256 is

computed with a 256-bit key key_hmac, where

scrypt(password, salt, N, r, p, 64) == [key_enc][key_hmac]
Reply
#5
brief update:

based on the above offsets, I parsed the db hashes and reformatted for hashcat.

hashcat accepts input w/o errors, but I am unable to recover known plain text

I think I am still having trouble with parsing the db hash format
Reply
#6
RFC has test vectors (although fewer bytes than the app's key / cipher text)
https://www.rfc-editor.org/rfc/rfc7914
Reply
#7
another reference for key format
https://github.com/chrisveness/scrypt-kdf
Reply
#8
From the above key, it seems pretty clear where to extract N,r,p,salt.

I'm not sure about which bytes to use for the digest portion of the hashcat format however. I've tried:
- the entire key (i.e. all bytes)
- everything after the salt (bytes 49-96)
- the last 32 bytes

To convert from codimd hex bytes, I:
echo <hexbytes> | xxd -r -p | base64

I'm still not able to recover known plain text such as "a", "password", "hashcat" from keys (hashes) generated by codimd.
Reply