mirror of
https://github.com/hashcat/hashcat.git
synced 2024-11-22 08:08:10 +00:00
change hash-signature for 26610 (incompatible with 26600), remove debug print statements in attacks, add comments, add reference data
This commit is contained in:
parent
248c4afc09
commit
5208447e72
@ -335,7 +335,6 @@ KERNEL_FQ void m26610_comp (KERN_ATTR_TMPS_ESALT (pbkdf2_sha256_tmp_t, pbkdf2_sh
|
||||
AES_GCM_Init (ukey, key_len, key, subKey, s_te0, s_te1, s_te2, s_te3, s_te4);
|
||||
|
||||
// iv
|
||||
|
||||
const u32 iv[4] = {
|
||||
esalt_bufs[DIGESTS_OFFSET_HOST].iv_buf[0],
|
||||
esalt_bufs[DIGESTS_OFFSET_HOST].iv_buf[1],
|
||||
@ -350,8 +349,6 @@ KERNEL_FQ void m26610_comp (KERN_ATTR_TMPS_ESALT (pbkdf2_sha256_tmp_t, pbkdf2_sh
|
||||
AES_GCM_Prepare_J0 (iv, iv_len, subKey, J0);
|
||||
|
||||
//ct
|
||||
|
||||
//u32 T[4] = { 0 };
|
||||
u32 ct[4] = {
|
||||
esalt_bufs[DIGESTS_OFFSET_HOST].ct_buf[0],
|
||||
esalt_bufs[DIGESTS_OFFSET_HOST].ct_buf[1],
|
||||
@ -361,21 +358,11 @@ KERNEL_FQ void m26610_comp (KERN_ATTR_TMPS_ESALT (pbkdf2_sha256_tmp_t, pbkdf2_sh
|
||||
|
||||
u32 pt[4] = { 0 };
|
||||
|
||||
//u32 S_len = 16;
|
||||
//u32 aad_buf[4] = { 0 };
|
||||
//u32 aad_len = 0;
|
||||
|
||||
//AES_GCM_GHASH_GLOBAL (subKey, aad_buf, aad_len, esalt_bufs[DIGESTS_OFFSET_HOST].ct_buf, esalt_bufs[DIGESTS_OFFSET_HOST].ct_len, S);
|
||||
|
||||
//AES_GCM_GCTR (key, J0, S, S_len, T, s_te0, s_te1, s_te2, s_te3, s_te4);
|
||||
|
||||
// we try to decrypt the ciphertext
|
||||
AES_GCM_inc32(J0); // the first ctr is used to compute the tag, only the second is used for decryption: https://en.wikipedia.org/wiki/Galois/Counter_Mode#/media/File:GCM-Galois_Counter_Mode_with_IV.svg
|
||||
AES_GCM_GCTR (key, J0, ct, 16, pt, s_te0, s_te1, s_te2, s_te3, s_te4); // decrypt the ciphertext
|
||||
|
||||
|
||||
if ((gid == 0) && (lid == 0)) printf ("pt[0]=%08x\n", pt[0]); // should be 5b7b2274 or [{"type"
|
||||
|
||||
// if ((gid == 0) && (lid == 0)) printf ("pt[0]=%08x\n", pt[0]); // should be 5b7b2274 or [{"type"
|
||||
|
||||
// cast plaintext buffer to byte such that we can do a byte per byte comparison
|
||||
PRIVATE_AS const u32 *u32OutBufPtr = (PRIVATE_AS u32 *) pt;
|
||||
@ -389,11 +376,12 @@ KERNEL_FQ void m26610_comp (KERN_ATTR_TMPS_ESALT (pbkdf2_sha256_tmp_t, pbkdf2_sh
|
||||
for(int i=0;i<16;i++)
|
||||
{
|
||||
if(u8OutBufPtr[i] >=20 && u8OutBufPtr[i] <= 0x7e) {
|
||||
if ((gid == 0) && (lid == 0)) printf("correct ASCII byte[%d]=0x%02x\n", i, u8OutBufPtr[i]);
|
||||
//if ((gid == 0) && (lid == 0)) printf("correct ASCII byte[%d]=0x%02x\n", i, u8OutBufPtr[i]);
|
||||
}
|
||||
else {
|
||||
if ((gid == 0) && (lid == 0)) printf("NOT correct! byte[%d]=0x%02x\n", i, u8OutBufPtr[i]);
|
||||
//if ((gid == 0) && (lid == 0)) printf("NOT correct! byte[%d]=0x%02x\n", i, u8OutBufPtr[i]);
|
||||
correct = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -405,23 +393,17 @@ KERNEL_FQ void m26610_comp (KERN_ATTR_TMPS_ESALT (pbkdf2_sha256_tmp_t, pbkdf2_sh
|
||||
esalt_bufs[DIGESTS_OFFSET_HOST].ct_buf[3],
|
||||
};
|
||||
|
||||
|
||||
if ((gid == 0) && (lid == 0)) printf ("ct[0]=%08x\n", ct[0]);
|
||||
if ((gid == 0) && (lid == 0)) printf ("ct[1]=%08x\n", ct[1]);
|
||||
if ((gid == 0) && (lid == 0)) printf ("ct[2]=%08x\n", ct[2]);
|
||||
if ((gid == 0) && (lid == 0)) printf ("ct[3]=%08x\n", ct[3]);
|
||||
if ((gid == 0) && (lid == 0)) printf("here0\n");
|
||||
//if ((gid == 0) && (lid == 0)) printf ("ct[0]=%08x\n", ct[0]);
|
||||
//if ((gid == 0) && (lid == 0)) printf ("ct[1]=%08x\n", ct[1]);
|
||||
//if ((gid == 0) && (lid == 0)) printf ("ct[2]=%08x\n", ct[2]);
|
||||
//if ((gid == 0) && (lid == 0)) printf ("ct[3]=%08x\n", ct[3]);
|
||||
|
||||
if (correct)
|
||||
{
|
||||
|
||||
if ((gid == 0) && (lid == 0)) printf("here1\n");
|
||||
int digest_pos = find_hash (digest, DIGESTS_CNT, &digests_buf[DIGESTS_OFFSET_HOST]);
|
||||
|
||||
if (digest_pos != -1)
|
||||
{
|
||||
|
||||
if ((gid == 0) && (lid == 0)) printf("here2\n");
|
||||
const u32 final_hash_pos = DIGESTS_OFFSET_HOST + digest_pos;
|
||||
|
||||
if (hc_atomic_inc (&hashes_shown[final_hash_pos]) == 0)
|
||||
|
@ -22,6 +22,7 @@
|
||||
- Added hash-mode: HMAC-RIPEMD160 (key = $salt)
|
||||
- Added hash-mode: bcrypt(sha256($pass))
|
||||
- Added hash-mode: md5(md5($salt).md5(md5($pass)))
|
||||
- Added hash-mode: metamask (26610) with plaintext check instead of checking tag (26600). No longer needs all data in hash.
|
||||
|
||||
##
|
||||
## Performance
|
||||
|
@ -18,7 +18,8 @@ static const u32 DGST_POS2 = 2;
|
||||
static const u32 DGST_POS3 = 3;
|
||||
static const u32 DGST_SIZE = DGST_SIZE_4_4;
|
||||
static const u32 HASH_CATEGORY = HASH_CATEGORY_CRYPTOCURRENCY_WALLET;
|
||||
static const char *HASH_NAME = "MetaMask Wallet short data";
|
||||
// 22610 generates a decryption key based on a password-guess and uses that to AES-GCM decrypt the data decrypts
|
||||
static const char *HASH_NAME = "MetaMask Wallet (short hash, plaintext check)";
|
||||
static const u64 KERN_TYPE = 26610;
|
||||
static const u32 OPTI_TYPE = OPTI_TYPE_ZERO_BYTE
|
||||
| OPTI_TYPE_SLOW_HASH_SIMD_LOOP;
|
||||
@ -26,6 +27,7 @@ static const u64 OPTS_TYPE = OPTS_TYPE_STOCK_MODULE
|
||||
| OPTS_TYPE_PT_GENERATE_LE;
|
||||
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 --shortdata
|
||||
static const char *ST_HASH = "$metamask-short$jfGI3TXguhb8GPnKSXFrMzRk2NCEc131Gt5G3kZr5+s=$h+BoIf2CQ5BEjaIOShFE7g==$R95fzGt4UQ0uwrcrVYnIi4UcSlWn9wlmer+//526ZDwYAp50K82F1u1oacYcdjjhuEvbZnWk/uBG00UkgLLlOw==";
|
||||
|
||||
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; }
|
||||
@ -238,14 +240,6 @@ int module_hash_decode (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSE
|
||||
digest[2] = (metamask->ct_buf[2]);
|
||||
digest[3] = (metamask->ct_buf[3]);
|
||||
|
||||
printf ("ct_buf[0]=%08x\n", metamask->ct_buf[0]);
|
||||
printf ("ct_buf[1]=%08x\n", metamask->ct_buf[1]);
|
||||
printf ("ct_buf[2]=%08x\n", metamask->ct_buf[2]);
|
||||
printf ("ct_buf[3]=%08x\n", metamask->ct_buf[3]);
|
||||
printf ("digest[0]=%08x\n", digest[0]);
|
||||
printf ("digest[1]=%08x\n", digest[1]);
|
||||
printf ("digest[2]=%08x\n", digest[2]);
|
||||
printf ("digest[3]=%08x\n", digest[3]);
|
||||
return (PARSER_OK);
|
||||
}
|
||||
|
||||
|
41
tools/2hashcat_tests/metamask2hashcat-test.py
Normal file
41
tools/2hashcat_tests/metamask2hashcat-test.py
Normal file
@ -0,0 +1,41 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from base64 import b64decode
|
||||
from hashlib import pbkdf2_hmac
|
||||
|
||||
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="}
|
||||
password = "hashcat1"
|
||||
|
||||
salt = b64decode(vault["salt"])
|
||||
key = pbkdf2_hmac("sha256", password.encode(), salt, 10_000)
|
||||
|
||||
iv = b64decode(vault["iv"])
|
||||
payload = b64decode(vault["data"])
|
||||
ciphertext = payload[:-16]
|
||||
print(f"ciphertext.hex()={ciphertext.hex()[0:128]}")
|
||||
tag = payload[-16:]
|
||||
|
||||
cipher = AES.new(key, AES.MODE_GCM, nonce=iv)
|
||||
plaintext = cipher.decrypt(ciphertext)
|
||||
|
||||
print(plaintext.hex()[0:128])
|
||||
print(str(plaintext[0:128]))
|
||||
|
||||
print()
|
||||
try:
|
||||
cipher.verify(tag)
|
||||
print("The message is authentic:", plaintext.decode())
|
||||
except ValueError:
|
||||
print("Key incorrect or message corrupted")
|
||||
print()
|
||||
|
||||
cipher = AES.new(key, AES.MODE_GCM, nonce=iv)
|
||||
plaintext = cipher.decrypt(ciphertext[:32])
|
||||
print("Partially encrypted message (32 bytes):", plaintext.decode())
|
||||
|
||||
cipher = AES.new(key, AES.MODE_GCM, nonce=iv)
|
||||
plaintext = cipher.decrypt(ciphertext[:450])
|
||||
print("Partially encrypted message (450 bytes):", plaintext.decode())
|
1
tools/2hashcat_tests/metamask2hashcat.json
Normal file
1
tools/2hashcat_tests/metamask2hashcat.json
Normal file
@ -0,0 +1 @@
|
||||
{"data":"R95fzGt4UQ0uwrcrVYnIi4UcSlWn9wlmer+//526ZDwYAp50K82F1u1oacYcdjjhuEvbZnWk/uBG00UkgLLlO3WbINljqmu2QWdDEwjTgo/qWR6MU9d/82rxNiONHQE8UrZ8SV+htVr6XIB0ze3aCV0E+fwI93EeP79ZeDxuOEhuHoiYT0bHWMv5nA48AdluG4DbOo7SrDAWBVCBsEdXsOfYsS3/TIh0a/iFCMX4uhxY2824JwcWp4H36SFWyBYMZCJ3/U4DYFbbjWZtGRthoJlIik5BJq4FLu3Y1jEgza0AWlAvu4MKTEqrYSpUIghfxf1a1f+kPvxsHNq0as0kRwCXu09DObbdsiggbmeoBkxMZiFq0d9ar/3Gon0r3hfc3c124Wlivzbzu1JcZ3wURhLSsUS7b5cfG86aXHJkxmQDA5urBz6lw3bsIvlEUB2ErkQy/zD+cPwCG1Rs/WKt7KNh45lppCUkHccbf+xlpdc8OfUwj01Xp7BdH8LMR7Vx1C4hZCvSdtURVl0VaAMxHDX0MjRkwmqS","iv":"h+BoIf2CQ5BEjaIOShFE7g==","salt":"jfGI3TXguhb8GPnKSXFrMzRk2NCEc131Gt5G3kZr5+s="}
|
@ -11,8 +11,9 @@
|
||||
|
||||
import json
|
||||
import argparse
|
||||
import base64
|
||||
|
||||
def metamask_parser(file):
|
||||
def metamask_parser(file, shortdata):
|
||||
try:
|
||||
f = open(file)
|
||||
|
||||
@ -23,6 +24,12 @@ def metamask_parser(file):
|
||||
parser.print_help()
|
||||
exit(1)
|
||||
|
||||
if((len(j['data']) > 3000) or shortdata):
|
||||
print("! Data too long, we limit it to 64 bytes, this hash can only be used with m26610!")
|
||||
data_bin = base64.b64decode(j['data'])
|
||||
j['data'] = base64.b64encode(data_bin[0:64]).decode("ascii")
|
||||
print('$metamask-short$' + j['salt'] + '$' + j['iv'] + '$' + j['data'])
|
||||
else:
|
||||
print('$metamask$' + j['salt'] + '$' + j['iv'] + '$' + j['data'])
|
||||
except ValueError as e:
|
||||
parser.print_help()
|
||||
@ -33,10 +40,12 @@ def metamask_parser(file):
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description="metamask2hashcat.py extraction tool")
|
||||
parser.add_argument('--vault', required=True, help='set metamask vault (json) file from path', type=str)
|
||||
parser.add_argument('--shortdata', help='force short data, can only be used with m26610, ', action='store_true')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.vault:
|
||||
metamask_parser(args.vault)
|
||||
metamask_parser(args.vault, args.shortdata)
|
||||
else:
|
||||
parser.print_help()
|
||||
exit(1)
|
||||
|
Loading…
Reference in New Issue
Block a user