diff --git a/src/modules/module_26600.c b/src/modules/module_26600.c index 4f6d0de3b..c40347f67 100644 --- a/src/modules/module_26600.c +++ b/src/modules/module_26600.c @@ -27,7 +27,7 @@ static const u64 OPTS_TYPE = OPTS_TYPE_STOCK_MODULE static const u32 SALT_TYPE = SALT_TYPE_EMBEDDED; static const char *ST_PASS = "hashcat1"; // hash generated using with python3 tools/metamask2hashcat.py --vault tools/2hashcat_tests/metamask2hashcat.json -static const char *ST_HASH = "$metamask$jfGI3TXguhb8GPnKSXFrMzRk2NCEc131Gt5G3kZr5+s=$h+BoIf2CQ5BEjaIOShFE7g==$R95fzGt4UQ0uwrcrVYnIi4UcSlWn9wlmer+//526ZDwYAp50K82F1u1oacYcdjjhuEvbZnWk/uBG00UkgLLlO3WbINljqmu2QWdDEwjTgo/qWR6MU9d/82rxNiONHQE8UrZ8SV+htVr6XIB0ze3aCV0E+fwI93EeP79ZeDxuOEhuHoiYT0bHWMv5nA48AdluG4DbOo7SrDAWBVCBsEdXsOfYsS3/TIh0a/iFCMX4uhxY2824JwcWp4H36SFWyBYMZCJ3/U4DYFbbjWZtGRthoJlIik5BJq4FLu3Y1jEgza0AWlAvu4MKTEqrYSpUIghfxf1a1f+kPvxsHNq0as0kRwCXu09DObbdsiggbmeoBkxMZiFq0d9ar/3Gon0r3hfc3c124Wlivzbzu1JcZ3wURhLSsUS7b5cfG86aXHJkxmQDA5urBz6lw3bsIvlEUB2ErkQy/zD+cPwCG1Rs/WKt7KNh45lppCUkHccbf+xlpdc8OfUwj01Xp7BdH8LMR7Vx1C4hZCvSdtURVl0VaAMxHDX0MjRkwmqS"; +static const char *ST_HASH = "$metamask$jReEwKFNQ5y3hfwOSQtTALWcKtlB26y5Tu1mk7LkJA8=$600000$3M/kKrGbjM/I00+RjQ9KUw==$l4UkKy22JQqCpKVqMPI99fHAyekOMgjw2lsCcA6a0oy9UHn0kXczWuqZ/aw809INGF9Ib1k/bYZQU0wtIEST/9cucpMaU7RYbp2CnjB4KzQrMU0tiK8oneVMJKBQdRL7An8S9huUq3Mu3MA1hyD7Nhi1WIIDpBPSlRa9q7waYA1m3IFKi7SgoeNeqy8GA3QeEJdimN0VgD+CCYyvHltPYqQ9BxY9cgMY+cD3FWrMe2vddBV/ylNYOXjYwaKtQWhRPwkkMj3/TR5jW2wKb3VGX8aH+M6dxO5iAsRWdKrNVg+bPQ9+8k4FUDWcmefBySd9zIyrVTsfrRYGfaPRSkUBcEOOFPpnWZdLlamuOr3MwPSjOKUi6XIzVCoO71AWM3lSntIJKOf50/2ybhlX2DKpIb0HBc6Rf+eAI0bALZ2mnq/ATviRb6aKongmk6chlbnmZdroE5ylze3TgAl1F+GleVwuL76XWacj6ft2HyVAkzkJFTn+LY7+9TinImAPXElZ67wOJn12ip03ZQOWgfehwIhcs9wVPo07e73lHvEVIE1sPuxcZqNMzc5WzR6elhCSEavv4UzCVYpJfB+nbcLvF4nME85Gls9nRSMItDRlkDrGR5dbJuJMENLpEvMgirDPYffbnKrFz7r4p7J0kchmanCWhIVnegIRGu6IDIzBjkbtZ7WfksH3TV5Q0G0rEQ=="; u32 module_attack_exec (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return ATTACK_EXEC; } u32 module_dgst_pos0 (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return DGST_POS0; } @@ -134,43 +134,50 @@ int module_hash_decode (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSE memset (&token, 0, sizeof (hc_token_t)); - token.token_cnt = 4; + token.token_cnt = 5; token.signatures_cnt = 1; token.signatures_buf[0] = SIGNATURE_METAMASK_WALLET; - token.len[0] = 10; + token.len[0] = 10; // signature token.attr[0] = TOKEN_ATTR_FIXED_LENGTH | TOKEN_ATTR_VERIFY_SIGNATURE; - token.sep[1] = '$'; + token.sep[1] = '$'; // salt token.len[1] = 44; token.attr[1] = TOKEN_ATTR_FIXED_LENGTH | TOKEN_ATTR_VERIFY_BASE64A; + + token.sep[2] = '$'; // iterations + token.len_min[2] = 0; + token.len_max[2] = 10; + token.attr[2] = TOKEN_ATTR_VERIFY_LENGTH + | TOKEN_ATTR_OPTIONAL_ROUNDS; - token.sep[2] = '$'; - token.len[2] = 24; - token.attr[2] = TOKEN_ATTR_FIXED_LENGTH + token.sep[3] = '$'; // iv + token.len[3] = 24; + token.attr[3] = TOKEN_ATTR_FIXED_LENGTH | TOKEN_ATTR_VERIFY_BASE64A; - token.sep[3] = '$'; - token.len_min[3] = 64; - token.len_max[3] = CT_MAX_LEN_BASE64; - token.attr[3] = TOKEN_ATTR_VERIFY_LENGTH + token.sep[4] = '$'; // cipher + token.len_min[4] = 64; + token.len_max[4] = CT_MAX_LEN_BASE64; + token.attr[4] = TOKEN_ATTR_VERIFY_LENGTH | TOKEN_ATTR_VERIFY_BASE64A; const int rc_tokenizer = input_tokenizer ((const u8 *) line_buf, line_len, &token); + // printf("\n\nSalt: %.*s\n", token.len[1], token.buf[1]); + // printf("Iteration: %.*s\n", token.len[2], token.buf[2]); + // printf("IV: %.*s\n", token.len[3], token.buf[3]); + // printf("Ciphertext: %.*s\n", token.len[4], token.buf[4]); + if (rc_tokenizer != PARSER_OK) return (rc_tokenizer); u8 tmp_buf[CT_MAX_LEN_BASE64] = { 0 }; size_t tmp_len = 0; - // iter - - salt->salt_iter = 10000 - 1; - // salt const u8 *salt_pos = token.buf[1]; @@ -195,10 +202,16 @@ int module_hash_decode (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSE metamask->salt_buf[6] = salt->salt_buf[6]; metamask->salt_buf[7] = salt->salt_buf[7]; + + // iter + const u8 *iter_pos = token.buf[2]; + u32 iterations = hc_strtoul ((const char *) iter_pos, NULL, 10); + salt->salt_iter = iterations - 1; + // iv - const u8 *iv_pos = token.buf[2]; - const int iv_len = token.len[2]; + const u8 *iv_pos = token.buf[3]; + const int iv_len = token.len[3]; memset (tmp_buf, 0, sizeof (tmp_buf)); @@ -217,8 +230,8 @@ int module_hash_decode (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSE // ciphertext - const u8 *ct_pos = token.buf[3]; - const int ct_len = token.len[3]; + const u8 *ct_pos = token.buf[4]; + const int ct_len = token.len[4]; memset (tmp_buf, 0, sizeof (tmp_buf)); diff --git a/tools/2hashcat_tests/metamask2hashcat-test.py b/tools/2hashcat_tests/metamask2hashcat-test.py index 7c4ea1ba7..53bcadd02 100755 --- a/tools/2hashcat_tests/metamask2hashcat-test.py +++ b/tools/2hashcat_tests/metamask2hashcat-test.py @@ -2,15 +2,21 @@ from base64 import b64decode from hashlib import pbkdf2_hmac - +import json from Crypto.Cipher import AES -#TODO perhaps load the vault from tools/2hashcat_tests/metamask2hashcat.json similar as in tools/metamask2hashcat.py -vault = {"data":"R95fzGt4UQ0uwrcrVYnIi4UcSlWn9wlmer+//526ZDwYAp50K82F1u1oacYcdjjhuEvbZnWk/uBG00UkgLLlO3WbINljqmu2QWdDEwjTgo/qWR6MU9d/82rxNiONHQE8UrZ8SV+htVr6XIB0ze3aCV0E+fwI93EeP79ZeDxuOEhuHoiYT0bHWMv5nA48AdluG4DbOo7SrDAWBVCBsEdXsOfYsS3/TIh0a/iFCMX4uhxY2824JwcWp4H36SFWyBYMZCJ3/U4DYFbbjWZtGRthoJlIik5BJq4FLu3Y1jEgza0AWlAvu4MKTEqrYSpUIghfxf1a1f+kPvxsHNq0as0kRwCXu09DObbdsiggbmeoBkxMZiFq0d9ar/3Gon0r3hfc3c124Wlivzbzu1JcZ3wURhLSsUS7b5cfG86aXHJkxmQDA5urBz6lw3bsIvlEUB2ErkQy/zD+cPwCG1Rs/WKt7KNh45lppCUkHccbf+xlpdc8OfUwj01Xp7BdH8LMR7Vx1C4hZCvSdtURVl0VaAMxHDX0MjRkwmqS","iv":"h+BoIf2CQ5BEjaIOShFE7g==","salt":"jfGI3TXguhb8GPnKSXFrMzRk2NCEc131Gt5G3kZr5+s="} +import os + +current_path = os.path.dirname(__file__) +file_path = os.path.join(current_path, "metamask2hashcat.json") +with open(file_path, "r") as file: + vault = json.load(file) + password = "hashcat1" salt = b64decode(vault["salt"]) -key = pbkdf2_hmac("sha256", password.encode(), salt, 10_000) +iter = vault["keyMetadata"]["params"]["iterations"] +key = pbkdf2_hmac("sha256", password.encode(), salt, iter) iv = b64decode(vault["iv"]) payload = b64decode(vault["data"]) diff --git a/tools/2hashcat_tests/metamask2hashcat.json b/tools/2hashcat_tests/metamask2hashcat.json index 08274a2c4..434bdf50d 100644 --- a/tools/2hashcat_tests/metamask2hashcat.json +++ b/tools/2hashcat_tests/metamask2hashcat.json @@ -1 +1 @@ -{"data":"R95fzGt4UQ0uwrcrVYnIi4UcSlWn9wlmer+//526ZDwYAp50K82F1u1oacYcdjjhuEvbZnWk/uBG00UkgLLlO3WbINljqmu2QWdDEwjTgo/qWR6MU9d/82rxNiONHQE8UrZ8SV+htVr6XIB0ze3aCV0E+fwI93EeP79ZeDxuOEhuHoiYT0bHWMv5nA48AdluG4DbOo7SrDAWBVCBsEdXsOfYsS3/TIh0a/iFCMX4uhxY2824JwcWp4H36SFWyBYMZCJ3/U4DYFbbjWZtGRthoJlIik5BJq4FLu3Y1jEgza0AWlAvu4MKTEqrYSpUIghfxf1a1f+kPvxsHNq0as0kRwCXu09DObbdsiggbmeoBkxMZiFq0d9ar/3Gon0r3hfc3c124Wlivzbzu1JcZ3wURhLSsUS7b5cfG86aXHJkxmQDA5urBz6lw3bsIvlEUB2ErkQy/zD+cPwCG1Rs/WKt7KNh45lppCUkHccbf+xlpdc8OfUwj01Xp7BdH8LMR7Vx1C4hZCvSdtURVl0VaAMxHDX0MjRkwmqS","iv":"h+BoIf2CQ5BEjaIOShFE7g==","salt":"jfGI3TXguhb8GPnKSXFrMzRk2NCEc131Gt5G3kZr5+s="} \ No newline at end of file +{"data":"0MByYgMFk6V4dYZC/N1SxxbMeWPXEtVktMlM4t2gIg0mblM4HGbawHggj4cvwsLRmtIM3nT6f8KcceGhDHJJGB1iWmpVeC4HhA+QR75MdbyR4fhZ9AyvDoSQ0K1m7ckziRWExQG0s9xj4x+0x3k45UDYziKMTXWgrD3SwkkP5asMOOITcdR0rdlmndAIcBz+IBf3zs76EEpsUJx6dhHqRUxAgfH4WRLRq/h2/LyhfnKvhmH+RYz6MZ/sa5P+fcCgZCtOTOdbu8LdJBHsXewUY43d2ti+QfrGmvXCP0ZHj97XWTWCdTwTuDIx/nXPXWhQzVXKVlKarQ5YvmauCWG3QJrYDa3sTduVMuFRwS/+1pIID+ybhrQft2EVRxBVkqcBu/gCCHeM7oOwTEw+UEv5GgduZ5iwFD/KMGRUlh9igoumtzsMIY6BOOQzQBbg5WREQA2Gbh4W+DEK6M2TxJeCg6BkVgT4QuXxgvJK7YFXNsEYNFh/LZ9FOosbx+TXiMJuJrr+czTmzA==","iv":"3/XB0MgtPNz8yFQ0GhkRZQ==","keyMetadata":{"algorithm":"PBKDF2","params":{"iterations":600000}},"salt":"jReEwKFNQ5y3hfwOSQtTALWcKtlB26y5Tu1mk7LkJA8="} \ No newline at end of file diff --git a/tools/metamask2hashcat.py b/tools/metamask2hashcat.py index a2aa99774..6b8522418 100755 --- a/tools/metamask2hashcat.py +++ b/tools/metamask2hashcat.py @@ -52,6 +52,10 @@ def metamask_parser(file, shortdata): exit(1) if isMobile is False: + try: + iter_count = j['keyMetadata']['params']['iterations'] + except KeyError: + iter_count = 10_000 if((len(j['data']) > 3000) or shortdata): data_bin = base64.b64decode(j['data']) @@ -60,9 +64,9 @@ def metamask_parser(file, shortdata): # Still the pbkdf 10k iter will be taking the most time by far probably. j['data'] = base64.b64encode(data_bin[0:64]).decode("ascii") - print('$metamask-short$' + j['salt'] + '$' + j['iv'] + '$' + j['data']) + print(f'$metamask-short${j["salt"]}${iter_count}${j["iv"]}${j["data"]}') else: - print('$metamask$' + j['salt'] + '$' + j['iv'] + '$' + j['data']) + print(f'$metamask${j["salt"]}${iter_count}${j["iv"]}${j["data"]}') else: @@ -71,7 +75,7 @@ def metamask_parser(file, shortdata): cipher_bin = base64.b64decode(j['cipher']) j['cipher'] = base64.b64encode(cipher_bin[:32]).decode("ascii") - print('$metamaskMobile$' + j['salt'] + '$' + j['iv'] + '$' + j['cipher']) + print(f'$metamaskMobile${j["salt"]}${iter_count}${j["iv"]}${j["cipher"]}') except ValueError as e: parser.print_help()