1
mirror of https://github.com/hashcat/hashcat synced 2024-11-28 05:21:38 +01:00

Add IV support to lastpass (-m 6800)

If you are from the past and need the old functionality, just use zeroes for the IV.

For instance, the old example hash would then become:
82dbb8ccc9c7ead8c38a92a6b5740f94:500:pmix@trash-mail.com:00000000000000000000000000000000
This commit is contained in:
Lars Sætaberget 2022-10-19 13:03:34 +02:00 committed by Lars Sætaberget
parent f63ff289f7
commit f40dc401bc
3 changed files with 53 additions and 11 deletions

View File

@ -18,6 +18,11 @@
#define COMPARE_S M2S(INCLUDE_PATH/inc_comp_single.cl) #define COMPARE_S M2S(INCLUDE_PATH/inc_comp_single.cl)
#define COMPARE_M M2S(INCLUDE_PATH/inc_comp_multi.cl) #define COMPARE_M M2S(INCLUDE_PATH/inc_comp_multi.cl)
typedef struct lastpass
{
u32 iv[4];
} lastpass_t;
typedef struct lastpass_tmp typedef struct lastpass_tmp
{ {
u32 ipad[8]; u32 ipad[8];
@ -70,7 +75,7 @@ DECLSPEC void hmac_sha256_run_V (PRIVATE_AS u32x *w0, PRIVATE_AS u32x *w1, PRIVA
sha256_transform_vector (w0, w1, w2, w3, digest); sha256_transform_vector (w0, w1, w2, w3, digest);
} }
KERNEL_FQ void m06800_init (KERN_ATTR_TMPS (lastpass_tmp_t)) KERNEL_FQ void m06800_init (KERN_ATTR_TMPS_ESALT (lastpass_tmp_t, lastpass_t))
{ {
/** /**
* base * base
@ -154,7 +159,7 @@ KERNEL_FQ void m06800_init (KERN_ATTR_TMPS (lastpass_tmp_t))
} }
} }
KERNEL_FQ void m06800_loop (KERN_ATTR_TMPS (lastpass_tmp_t)) KERNEL_FQ void m06800_loop (KERN_ATTR_TMPS_ESALT (lastpass_tmp_t, lastpass_t))
{ {
const u64 gid = get_global_id (0); const u64 gid = get_global_id (0);
@ -260,7 +265,7 @@ KERNEL_FQ void m06800_loop (KERN_ATTR_TMPS (lastpass_tmp_t))
} }
} }
KERNEL_FQ void m06800_comp (KERN_ATTR_TMPS (lastpass_tmp_t)) KERNEL_FQ void m06800_comp (KERN_ATTR_TMPS_ESALT (lastpass_tmp_t, lastpass_t))
{ {
const u64 gid = get_global_id (0); const u64 gid = get_global_id (0);
const u64 lid = get_local_id (0); const u64 lid = get_local_id (0);
@ -367,6 +372,11 @@ KERNEL_FQ void m06800_comp (KERN_ATTR_TMPS (lastpass_tmp_t))
out[2] = hc_swap32_S (out[2]); out[2] = hc_swap32_S (out[2]);
out[3] = hc_swap32_S (out[3]); out[3] = hc_swap32_S (out[3]);
out[0] ^= esalt_bufs[DIGESTS_OFFSET_HOST].iv[0];
out[1] ^= esalt_bufs[DIGESTS_OFFSET_HOST].iv[1];
out[2] ^= esalt_bufs[DIGESTS_OFFSET_HOST].iv[2];
out[3] ^= esalt_bufs[DIGESTS_OFFSET_HOST].iv[3];
truncate_block_4x4_le_S (out, salt_len); truncate_block_4x4_le_S (out, salt_len);
if ((out[0] == salt_buf[0]) if ((out[0] == salt_buf[0])

View File

@ -25,7 +25,7 @@ static const u64 OPTS_TYPE = OPTS_TYPE_STOCK_MODULE
| OPTS_TYPE_PT_GENERATE_LE; | OPTS_TYPE_PT_GENERATE_LE;
static const u32 SALT_TYPE = SALT_TYPE_EMBEDDED; static const u32 SALT_TYPE = SALT_TYPE_EMBEDDED;
static const char *ST_PASS = "hashcat"; static const char *ST_PASS = "hashcat";
static const char *ST_HASH = "82dbb8ccc9c7ead8c38a92a6b5740f94:500:pmix@trash-mail.com"; static const char *ST_HASH = "02eb97e869e0ddc7dc760fc633b4b54d:100100:pmix@trash-mail.com:9b071db7b8e265d4cadd3eb65ac0864a";
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_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; } 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; }
@ -42,6 +42,11 @@ u32 module_salt_type (MAYBE_UNUSED const hashconfig_t *hashconfig,
const char *module_st_hash (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 ST_HASH; } const char *module_st_hash (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 ST_HASH; }
const char *module_st_pass (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 ST_PASS; } const char *module_st_pass (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 ST_PASS; }
typedef struct lastpass
{
u32 iv[4];
} lastpass_t;
typedef struct lastpass_tmp typedef struct lastpass_tmp
{ {
u32 ipad[8]; u32 ipad[8];
@ -52,6 +57,13 @@ typedef struct lastpass_tmp
} lastpass_tmp_t; } lastpass_tmp_t;
u64 module_esalt_size (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra)
{
const u64 esalt_size = (const u64) sizeof (lastpass_t);
return esalt_size;
}
bool module_unstable_warning (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra, MAYBE_UNUSED const hc_device_param_t *device_param) bool module_unstable_warning (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra, MAYBE_UNUSED const hc_device_param_t *device_param)
{ {
// AMD Radeon Pro W5700X Compute Engine; 1.2 (Apr 22 2021 21:54:44); 11.3.1; 20E241 // AMD Radeon Pro W5700X Compute Engine; 1.2 (Apr 22 2021 21:54:44); 11.3.1; 20E241
@ -120,7 +132,7 @@ int module_hash_decode (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSE
hc_token_t token; hc_token_t token;
token.token_cnt = 3; token.token_cnt = 4;
token.len_min[0] = 32; token.len_min[0] = 32;
token.len_max[0] = 64; token.len_max[0] = 64;
@ -138,6 +150,12 @@ int module_hash_decode (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSE
token.sep[2] = ':'; token.sep[2] = ':';
token.attr[2] = TOKEN_ATTR_VERIFY_LENGTH; token.attr[2] = TOKEN_ATTR_VERIFY_LENGTH;
token.len_min[3] = 32;
token.len_max[3] = 32;
token.sep[3] = ':';
token.attr[3] = TOKEN_ATTR_VERIFY_LENGTH
| TOKEN_ATTR_VERIFY_HEX;
const int rc_tokenizer = input_tokenizer ((const u8 *) line_buf, line_len, &token); const int rc_tokenizer = input_tokenizer ((const u8 *) line_buf, line_len, &token);
if (rc_tokenizer != PARSER_OK) return (rc_tokenizer); if (rc_tokenizer != PARSER_OK) return (rc_tokenizer);
@ -165,6 +183,12 @@ int module_hash_decode (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSE
if (parse_rc == false) return (PARSER_SALT_LENGTH); if (parse_rc == false) return (PARSER_SALT_LENGTH);
lastpass_t *lastpass = (lastpass_t *) esalt_buf;
const int iv_size = hex_decode ((const u8 *) token.buf[3], token.len[3], (u8 *) lastpass->iv);
if (iv_size != sizeof (lastpass->iv)) return (PARSER_IV_LENGTH);
return (PARSER_OK); return (PARSER_OK);
} }
@ -172,19 +196,25 @@ int module_hash_encode (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSE
{ {
const u32 *digest = (const u32 *) digest_buf; const u32 *digest = (const u32 *) digest_buf;
const lastpass_t *lastpass = (const lastpass_t *) esalt_buf;
char tmp_salt[SALT_MAX * 2]; char tmp_salt[SALT_MAX * 2];
const int salt_len = generic_salt_encode (hashconfig, (const u8 *) salt->salt_buf, (const int) salt->salt_len, (u8 *) tmp_salt); const int salt_len = generic_salt_encode (hashconfig, (const u8 *) salt->salt_buf, (const int) salt->salt_len, (u8 *) tmp_salt);
tmp_salt[salt_len] = 0; tmp_salt[salt_len] = 0;
return snprintf (line_buf, line_size, "%08x%08x%08x%08x:%u:%s", return snprintf (line_buf, line_size, "%08x%08x%08x%08x:%u:%s:%08x%08x%08x%08x",
digest[0], digest[0],
digest[1], digest[1],
digest[2], digest[2],
digest[3], digest[3],
salt->salt_iter + 1, salt->salt_iter + 1,
tmp_salt); tmp_salt,
byte_swap_32(lastpass->iv[0]),
byte_swap_32(lastpass->iv[1]),
byte_swap_32(lastpass->iv[2]),
byte_swap_32(lastpass->iv[3]));
} }
void module_init (module_ctx_t *module_ctx) void module_init (module_ctx_t *module_ctx)
@ -207,7 +237,7 @@ void module_init (module_ctx_t *module_ctx)
module_ctx->module_dgst_pos3 = module_dgst_pos3; module_ctx->module_dgst_pos3 = module_dgst_pos3;
module_ctx->module_dgst_size = module_dgst_size; module_ctx->module_dgst_size = module_dgst_size;
module_ctx->module_dictstat_disable = MODULE_DEFAULT; module_ctx->module_dictstat_disable = MODULE_DEFAULT;
module_ctx->module_esalt_size = MODULE_DEFAULT; module_ctx->module_esalt_size = module_esalt_size;
module_ctx->module_extra_buffer_size = MODULE_DEFAULT; module_ctx->module_extra_buffer_size = MODULE_DEFAULT;
module_ctx->module_extra_tmp_size = MODULE_DEFAULT; module_ctx->module_extra_tmp_size = MODULE_DEFAULT;
module_ctx->module_extra_tuningdb_block = MODULE_DEFAULT; module_ctx->module_extra_tuningdb_block = MODULE_DEFAULT;

View File

@ -18,9 +18,9 @@ sub module_generate_hash
{ {
my $word = shift; my $word = shift;
my $salt = shift; my $salt = shift;
my $iter = shift // 500; my $iter = shift // 100100;
my $iv = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; my $iv = random_bytes(16);
my $hasher = Crypt::PBKDF2->hasher_from_algorithm ('HMACSHA2', 256); my $hasher = Crypt::PBKDF2->hasher_from_algorithm ('HMACSHA2', 256);
@ -45,7 +45,9 @@ sub module_generate_hash
my $hash_buf = substr (unpack ("H*", $encrypt), 0, 32); my $hash_buf = substr (unpack ("H*", $encrypt), 0, 32);
my $hash = sprintf ("%s:%i:%s", $hash_buf, $iter, $salt); my $iv_buf = unpack("H*", $iv);
my $hash = sprintf ("%s:%i:%s:%s", $hash_buf, $iter, $salt, $iv_buf);
return $hash; return $hash;
} }