![]() |
Extend ethereum wallet, PBKDF2-HMAC-SHA256 to allow arbitrary cipher length - Printable Version +- hashcat Forum (https://hashcat.net/forum) +-- Forum: Developer (https://hashcat.net/forum/forum-39.html) +--- Forum: hashcat (https://hashcat.net/forum/forum-40.html) +--- Thread: Extend ethereum wallet, PBKDF2-HMAC-SHA256 to allow arbitrary cipher length (/thread-12520.html) |
Extend ethereum wallet, PBKDF2-HMAC-SHA256 to allow arbitrary cipher length - bobby_newport - 03-06-2025 Hi All, I am trying to develop my own module that is very similar to module 15600. It is a crypto wallet that has a keystore very similar to Ethereum Wallet. It uses PBKDF2-HMAC-SHA256, the correct password can be confirmed by comparing a mac to a generated mac which is the keccak hash of the last 16 bytes of the derived key and cipher text. I have tested the logic and it does work. Module 15600 expects the cipher to be 64 characters long, but the wallet I am trying to crack can be much longer. The current cipher text I have is 156 characters long. I have been going at it for several days and struggling. I have also looked at module 16300 for guidance. I am hoping to get some direction on the changes that I need to make. Within the module c file I am replacing this part ethereum_pbkdf2->ciphertext[0] = hex_to_u32 (&ciphertext_pos[ 0]); ethereum_pbkdf2->ciphertext[1] = hex_to_u32 (&ciphertext_pos[ 8]); ethereum_pbkdf2->ciphertext[2] = hex_to_u32 (&ciphertext_pos[16]); ethereum_pbkdf2->ciphertext[3] = hex_to_u32 (&ciphertext_pos[24]); ethereum_pbkdf2->ciphertext[4] = hex_to_u32 (&ciphertext_pos[32]); ethereum_pbkdf2->ciphertext[5] = hex_to_u32 (&ciphertext_pos[40]); ethereum_pbkdf2->ciphertext[6] = hex_to_u32 (&ciphertext_pos[48]); ethereum_pbkdf2->ciphertext[7] = hex_to_u32 (&ciphertext_pos[56]); with this part crypto_pbkdf2->ciphertext[0] = hex_to_u32 (&ciphertext_pos[ 0]); crypto_pbkdf2->ciphertext[1] = hex_to_u32 (&ciphertext_pos[ 8]); crypto_pbkdf2->ciphertext[2] = hex_to_u32 (&ciphertext_pos[16]); crypto_pbkdf2->ciphertext[3] = hex_to_u32 (&ciphertext_pos[24]); crypto_pbkdf2->ciphertext[4] = hex_to_u32 (&ciphertext_pos[32]); crypto_pbkdf2->ciphertext[5] = hex_to_u32 (&ciphertext_pos[40]); crypto_pbkdf2->ciphertext[6] = hex_to_u32 (&ciphertext_pos[48]); crypto_pbkdf2->ciphertext[7] = hex_to_u32 (&ciphertext_pos[56]); crypto_pbkdf2->ciphertext[8] = hex_to_u32 (&ciphertext_pos[64]); crypto_pbkdf2->ciphertext[9] = hex_to_u32 (&ciphertext_pos[72]); crypto_pbkdf2->ciphertext[10] = hex_to_u32 (&ciphertext_pos[80]); crypto_pbkdf2->ciphertext[11] = hex_to_u32 (&ciphertext_pos[88]); crypto_pbkdf2->ciphertext[12] = hex_to_u32 (&ciphertext_pos[96]); crypto_pbkdf2->ciphertext[13] = hex_to_u32 (&ciphertext_pos[104]); crypto_pbkdf2->ciphertext[14] = hex_to_u32 (&ciphertext_pos[112]); crypto_pbkdf2->ciphertext[15] = hex_to_u32 (&ciphertext_pos[120]); crypto_pbkdf2->ciphertext[16] = hex_to_u32 (&ciphertext_pos[128]); crypto_pbkdf2->ciphertext[17] = hex_to_u32 (&ciphertext_pos[136]); crypto_pbkdf2->ciphertext[18] = hex_to_u32 (&ciphertext_pos[144]); crypto_pbkdf2->ciphertext[19] = hex_to_u32 (&ciphertext_pos[152]); With the encoder I have replaced const int line_len = snprintf (line_buf, line_size, "%s*%u*%s*%08x%08x%08x%08x%08x%08x%08x%08x*%08x%08x%08x%08x%08x%08x%08x%08x", SIGNATURE_ETHEREUM_PBKDF2, salt->salt_iter + 1, tmp_salt, byte_swap_32 (ethereum_pbkdf2->ciphertext[0]), byte_swap_32 (ethereum_pbkdf2->ciphertext[1]), byte_swap_32 (ethereum_pbkdf2->ciphertext[2]), byte_swap_32 (ethereum_pbkdf2->ciphertext[3]), byte_swap_32 (ethereum_pbkdf2->ciphertext[4]), byte_swap_32 (ethereum_pbkdf2->ciphertext[5]), byte_swap_32 (ethereum_pbkdf2->ciphertext[6]), byte_swap_32 (ethereum_pbkdf2->ciphertext[7]), byte_swap_32 (digest[0]), byte_swap_32 (digest[1]), byte_swap_32 (digest[2]), byte_swap_32 (digest[3]), byte_swap_32 (digest[4]), byte_swap_32 (digest[5]), byte_swap_32 (digest[6]), byte_swap_32 (digest[7]) ); with this part const int line_len = snprintf (line_buf, line_size, "%s*%u*%s*%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x*%08x%08x%08x%08x%08x%08x%08x%08x", SIGNATURE_CRYPTO_PBKDF2, salt->salt_iter + 1, tmp_salt, byte_swap_32 (crypto_pbkdf2->ciphertext[0]), byte_swap_32 (crypto_pbkdf2->ciphertext[1]), byte_swap_32 (crypto_pbkdf2->ciphertext[2]), byte_swap_32 (crypto_pbkdf2->ciphertext[3]), byte_swap_32 (crypto_pbkdf2->ciphertext[4]), byte_swap_32 (crypto_pbkdf2->ciphertext[5]), byte_swap_32 (crypto_pbkdf2->ciphertext[6]), byte_swap_32 (crypto_pbkdf2->ciphertext[7]), byte_swap_32 (crypto_pbkdf2->ciphertext[8]), byte_swap_32 (crypto_pbkdf2->ciphertext[9]), byte_swap_32 (crypto_pbkdf2->ciphertext[10]), byte_swap_32 (crypto_pbkdf2->ciphertext[11]), byte_swap_32 (crypto_pbkdf2->ciphertext[12]), byte_swap_32 (crypto_pbkdf2->ciphertext[13]), byte_swap_32 (crypto_pbkdf2->ciphertext[14]), byte_swap_32 (crypto_pbkdf2->ciphertext[15]), byte_swap_32 (crypto_pbkdf2->ciphertext[16]), byte_swap_32 (crypto_pbkdf2->ciphertext[17]), byte_swap_32 (crypto_pbkdf2->ciphertext[18]), byte_swap_32 (crypto_pbkdf2->ciphertext[19]), byte_swap_32 (digest[0]), byte_swap_32 (digest[1]), byte_swap_32 (digest[2]), byte_swap_32 (digest[3]), byte_swap_32 (digest[4]), byte_swap_32 (digest[5]), byte_swap_32 (digest[6]), byte_swap_32 (digest[7]) ); In the kernel I have replaced this /** * keccak */ u32 ciphertext[8]; ciphertext[0] = esalt_bufs[DIGESTS_OFFSET_HOST].ciphertext[0]; ciphertext[1] = esalt_bufs[DIGESTS_OFFSET_HOST].ciphertext[1]; ciphertext[2] = esalt_bufs[DIGESTS_OFFSET_HOST].ciphertext[2]; ciphertext[3] = esalt_bufs[DIGESTS_OFFSET_HOST].ciphertext[3]; ciphertext[4] = esalt_bufs[DIGESTS_OFFSET_HOST].ciphertext[4]; ciphertext[5] = esalt_bufs[DIGESTS_OFFSET_HOST].ciphertext[5]; ciphertext[6] = esalt_bufs[DIGESTS_OFFSET_HOST].ciphertext[6]; ciphertext[7] = esalt_bufs[DIGESTS_OFFSET_HOST].ciphertext[7]; u32 key[4]; key[0] = hc_swap32_S (tmps[gid].out[4]); key[1] = hc_swap32_S (tmps[gid].out[5]); key[2] = hc_swap32_S (tmps[gid].out[6]); key[3] = hc_swap32_S (tmps[gid].out[7]); u64 st[25]; st[ 0] = hl32_to_64_S (key[1], key[0]); st[ 1] = hl32_to_64_S (key[3], key[2]); st[ 2] = hl32_to_64_S (ciphertext[1], ciphertext[0]); st[ 3] = hl32_to_64_S (ciphertext[3], ciphertext[2]); st[ 4] = hl32_to_64_S (ciphertext[5], ciphertext[4]); st[ 5] = hl32_to_64_S (ciphertext[7], ciphertext[6]); st[ 6] = 0x01; st[ 7] = 0; st[ 8] = 0; st[ 9] = 0; st[10] = 0; st[11] = 0; st[12] = 0; st[13] = 0; st[14] = 0; st[15] = 0; st[16] = 0; st[17] = 0; st[18] = 0; st[19] = 0; st[20] = 0; st[21] = 0; st[22] = 0; st[23] = 0; st[24] = 0; with u32 ciphertext[20]; ciphertext[0] = esalt_bufs[DIGESTS_OFFSET_HOST].ciphertext[0]; ciphertext[1] = esalt_bufs[DIGESTS_OFFSET_HOST].ciphertext[1]; ciphertext[2] = esalt_bufs[DIGESTS_OFFSET_HOST].ciphertext[2]; ciphertext[3] = esalt_bufs[DIGESTS_OFFSET_HOST].ciphertext[3]; ciphertext[4] = esalt_bufs[DIGESTS_OFFSET_HOST].ciphertext[4]; ciphertext[5] = esalt_bufs[DIGESTS_OFFSET_HOST].ciphertext[5]; ciphertext[6] = esalt_bufs[DIGESTS_OFFSET_HOST].ciphertext[6]; ciphertext[7] = esalt_bufs[DIGESTS_OFFSET_HOST].ciphertext[7]; ciphertext[8] = esalt_bufs[DIGESTS_OFFSET_HOST].ciphertext[8]; ciphertext[9] = esalt_bufs[DIGESTS_OFFSET_HOST].ciphertext[9]; ciphertext[10] = esalt_bufs[DIGESTS_OFFSET_HOST].ciphertext[10]; ciphertext[11] = esalt_bufs[DIGESTS_OFFSET_HOST].ciphertext[11]; ciphertext[12] = esalt_bufs[DIGESTS_OFFSET_HOST].ciphertext[12]; ciphertext[13] = esalt_bufs[DIGESTS_OFFSET_HOST].ciphertext[13]; ciphertext[14] = esalt_bufs[DIGESTS_OFFSET_HOST].ciphertext[14]; ciphertext[15] = esalt_bufs[DIGESTS_OFFSET_HOST].ciphertext[15]; ciphertext[16] = esalt_bufs[DIGESTS_OFFSET_HOST].ciphertext[16]; ciphertext[17] = esalt_bufs[DIGESTS_OFFSET_HOST].ciphertext[17]; ciphertext[18] = esalt_bufs[DIGESTS_OFFSET_HOST].ciphertext[18]; ciphertext[19] = esalt_bufs[DIGESTS_OFFSET_HOST].ciphertext[19]; u32 key[4]; key[0] = hc_swap32_S (tmps[gid].out[4]); key[1] = hc_swap32_S (tmps[gid].out[5]); key[2] = hc_swap32_S (tmps[gid].out[6]); key[3] = hc_swap32_S (tmps[gid].out[7]); u64 st[25]; st[ 0] = hl32_to_64_S (key[1], key[0]); st[ 1] = hl32_to_64_S (key[3], key[2]); st[ 2] = hl32_to_64_S (ciphertext[1], ciphertext[0]); st[ 3] = hl32_to_64_S (ciphertext[3], ciphertext[2]); st[ 4] = hl32_to_64_S (ciphertext[5], ciphertext[4]); st[ 5] = hl32_to_64_S (ciphertext[7], ciphertext[6]); st[ 6] = hl32_to_64_S (ciphertext[9], ciphertext[8]); st[ 7] = hl32_to_64_S (ciphertext[11], ciphertext[10]); st[ 8] = hl32_to_64_S (ciphertext[13], ciphertext[12]); st[ 9] = hl32_to_64_S (ciphertext[15], ciphertext[14]); st[10] = hl32_to_64_S (ciphertext[17], ciphertext[16]); st[11] = hl32_to_64_S (ciphertext[19], ciphertext[18]); st[12] = 0x01; st[13] = 0; st[14] = 0; st[15] = 0; st[16] = 0; st[17] = 0; st[18] = 0; st[19] = 0; st[20] = 0; st[21] = 0; st[22] = 0; st[23] = 0; st[24] = 0; I am clearly missing something as the test fails and when I ignore the test, it doesn't return the true password that is in the list. The error when running the module is * Device #1: ATTENTION! OpenCL kernel self-test failed. Your device driver installation is probably broken. See also: https://hashcat.net/faq/wrongdriver Aborting session due to kernel self-test failure. You can use --self-test-disable to override, but do not report related errors. Module 15600, along with many others work without an issue so I know it is a problem with my code. In an ideal world the module would take a range of cipher lengths, which would open it to many more wallets. Full disclosure, I have minimal understanding of the C language (mainly Python and Java). Any help will be appreciated. RE: Extend ethereum wallet, PBKDF2-HMAC-SHA256 to allow arbitrary cipher length - bobby_newport - 03-07-2025 Ok so, if the cipher text is divisible by 8 it works. So the issue must be the padding in the keccak hash. I still get the self test error, but it finds the password. RE: Extend ethereum wallet, PBKDF2-HMAC-SHA256 to allow arbitrary cipher length - bobby_newport - 03-07-2025 I have managed to get it to work following the update for module 15700 provided by philsmd here https://hashcat.net/forum/archive/index.php?thread-9614.html. I still get the * Device #1: ATTENTION! OpenCL kernel self-test failed unless I use the ST_HASH from module 15600. |