mirror of
https://github.com/hashcat/hashcat.git
synced 2024-11-26 01:50:10 +00:00
Added support of keyfiles within Keepass 1.x and Keepass 2.x
This commit is contained in:
parent
5f05fbf103
commit
34b8d89422
@ -1168,7 +1168,7 @@ __kernel void m13400_init (__global pw_t *pws, __global kernel_rule_t *rules_buf
|
|||||||
|
|
||||||
sha256_transform (w0, w1, w2, w3, digest);
|
sha256_transform (w0, w1, w2, w3, digest);
|
||||||
|
|
||||||
if (esalt_bufs[salt_pos].version == 2)
|
if (esalt_bufs[salt_pos].version == 2 && esalt_bufs[salt_pos].keyfile_len == 0)
|
||||||
{
|
{
|
||||||
w0[0] = digest[0];
|
w0[0] = digest[0];
|
||||||
w0[1] = digest[1];
|
w0[1] = digest[1];
|
||||||
@ -1202,6 +1202,62 @@ __kernel void m13400_init (__global pw_t *pws, __global kernel_rule_t *rules_buf
|
|||||||
sha256_transform (w0, w1, w2, w3, digest);
|
sha256_transform (w0, w1, w2, w3, digest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (esalt_bufs[salt_pos].keyfile_len != 0)
|
||||||
|
{
|
||||||
|
w0[0] = digest[0];
|
||||||
|
w0[1] = digest[1];
|
||||||
|
w0[2] = digest[2];
|
||||||
|
w0[3] = digest[3];
|
||||||
|
|
||||||
|
w1[0] = digest[4];
|
||||||
|
w1[1] = digest[5];
|
||||||
|
w1[2] = digest[6];
|
||||||
|
w1[3] = digest[7];
|
||||||
|
|
||||||
|
w2[0] = esalt_bufs[salt_pos].keyfile[0];
|
||||||
|
w2[1] = esalt_bufs[salt_pos].keyfile[1];
|
||||||
|
w2[2] = esalt_bufs[salt_pos].keyfile[2];
|
||||||
|
w2[3] = esalt_bufs[salt_pos].keyfile[3];
|
||||||
|
|
||||||
|
w3[0] = esalt_bufs[salt_pos].keyfile[4];
|
||||||
|
w3[1] = esalt_bufs[salt_pos].keyfile[5];
|
||||||
|
w3[3] = esalt_bufs[salt_pos].keyfile[7];
|
||||||
|
w3[2] = esalt_bufs[salt_pos].keyfile[6];
|
||||||
|
|
||||||
|
digest[0] = SHA256M_A;
|
||||||
|
digest[1] = SHA256M_B;
|
||||||
|
digest[2] = SHA256M_C;
|
||||||
|
digest[3] = SHA256M_D;
|
||||||
|
digest[4] = SHA256M_E;
|
||||||
|
digest[5] = SHA256M_F;
|
||||||
|
digest[6] = SHA256M_G;
|
||||||
|
digest[7] = SHA256M_H;
|
||||||
|
|
||||||
|
sha256_transform (w0, w1, w2, w3, digest);
|
||||||
|
|
||||||
|
w0[0] = 0x80000000;
|
||||||
|
w0[1] = 0;
|
||||||
|
w0[2] = 0;
|
||||||
|
w0[3] = 0;
|
||||||
|
|
||||||
|
w1[0] = 0;
|
||||||
|
w1[1] = 0;
|
||||||
|
w1[2] = 0;
|
||||||
|
w1[3] = 0;
|
||||||
|
|
||||||
|
w2[0] = 0;
|
||||||
|
w2[1] = 0;
|
||||||
|
w2[2] = 0;
|
||||||
|
w2[3] = 0;
|
||||||
|
|
||||||
|
w3[0] = 0;
|
||||||
|
w3[1] = 0;
|
||||||
|
w3[2] = 0;
|
||||||
|
w3[3] = 64 * 8;
|
||||||
|
|
||||||
|
sha256_transform (w0, w1, w2, w3, digest);
|
||||||
|
}
|
||||||
|
|
||||||
tmps[gid].tmp_digest[0] = digest[0];
|
tmps[gid].tmp_digest[0] = digest[0];
|
||||||
tmps[gid].tmp_digest[1] = digest[1];
|
tmps[gid].tmp_digest[1] = digest[1];
|
||||||
tmps[gid].tmp_digest[2] = digest[2];
|
tmps[gid].tmp_digest[2] = digest[2];
|
||||||
@ -1420,7 +1476,7 @@ __kernel void m13400_comp (__global pw_t *pws, __global kernel_rule_t *rules_buf
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* merkle-demgard implementation */
|
/* merkle-damgard implementation */
|
||||||
u32 final_random_seed[8];
|
u32 final_random_seed[8];
|
||||||
|
|
||||||
final_random_seed[0] = esalt_bufs[salt_pos].final_random_seed[0];
|
final_random_seed[0] = esalt_bufs[salt_pos].final_random_seed[0];
|
||||||
|
@ -1597,6 +1597,10 @@ typedef struct
|
|||||||
u32 version;
|
u32 version;
|
||||||
u32 algorithm;
|
u32 algorithm;
|
||||||
|
|
||||||
|
/* key-file handling */
|
||||||
|
u32 keyfile_len;
|
||||||
|
u32 keyfile[8];
|
||||||
|
|
||||||
u32 final_random_seed[8];
|
u32 final_random_seed[8];
|
||||||
u32 transf_random_seed[8];
|
u32 transf_random_seed[8];
|
||||||
u32 enc_iv[4];
|
u32 enc_iv[4];
|
||||||
|
@ -688,7 +688,7 @@ extern hc_thread_mutex_t mux_display;
|
|||||||
#define DISPLAY_LEN_MIN_13300 1 + 12 + 1 + 32
|
#define DISPLAY_LEN_MIN_13300 1 + 12 + 1 + 32
|
||||||
#define DISPLAY_LEN_MAX_13300 1 + 12 + 1 + 40
|
#define DISPLAY_LEN_MAX_13300 1 + 12 + 1 + 40
|
||||||
#define DISPLAY_LEN_MIN_13400 1 + 7 + 1 + 1 + 1 + 1 + 1 + 1 + 32 + 1 + 64 + 1 + 32 + 1 + 64 + 1 + 1 + 1 + 1
|
#define DISPLAY_LEN_MIN_13400 1 + 7 + 1 + 1 + 1 + 1 + 1 + 1 + 32 + 1 + 64 + 1 + 32 + 1 + 64 + 1 + 1 + 1 + 1
|
||||||
#define DISPLAY_LEN_MAX_13400 1 + 7 + 1 + 1 + 10 + 1 + 3 + 1 + 64 + 1 + 64 + 1 + 32 + 1 + 64 + 1 + 4 + 1 + 100000
|
#define DISPLAY_LEN_MAX_13400 1 + 7 + 1 + 1 + 10 + 1 + 3 + 1 + 64 + 1 + 64 + 1 + 32 + 1 + 64 + 1 + 4 + 1 + 100000 + 1 + 2 + 1 + 64
|
||||||
|
|
||||||
#define DISPLAY_LEN_MIN_11 32 + 1 + 16
|
#define DISPLAY_LEN_MIN_11 32 + 1 + 16
|
||||||
#define DISPLAY_LEN_MAX_11 32 + 1 + 32
|
#define DISPLAY_LEN_MAX_11 32 + 1 + 32
|
||||||
|
@ -141,6 +141,10 @@ typedef struct
|
|||||||
u32 version;
|
u32 version;
|
||||||
u32 algorithm;
|
u32 algorithm;
|
||||||
|
|
||||||
|
/* key-file handling */
|
||||||
|
u32 keyfile_len;
|
||||||
|
u32 keyfile[8];
|
||||||
|
|
||||||
u32 final_random_seed[8];
|
u32 final_random_seed[8];
|
||||||
u32 transf_random_seed[8];
|
u32 transf_random_seed[8];
|
||||||
u32 enc_iv[4];
|
u32 enc_iv[4];
|
||||||
|
112
src/shared.c
112
src/shared.c
@ -6185,7 +6185,7 @@ void ascii_digest (char *out_buf, uint salt_pos, uint digest_pos)
|
|||||||
}
|
}
|
||||||
else if (hash_mode == 23)
|
else if (hash_mode == 23)
|
||||||
{
|
{
|
||||||
// do not show the \nskyper\n part in output
|
// do not show the skyper part in output
|
||||||
|
|
||||||
char *salt_buf_ptr = (char *) salt.salt_buf;
|
char *salt_buf_ptr = (char *) salt.salt_buf;
|
||||||
|
|
||||||
@ -8355,14 +8355,16 @@ void ascii_digest (char *out_buf, uint salt_pos, uint digest_pos)
|
|||||||
|
|
||||||
keepass_t *keepass = &keepasss[salt_pos];
|
keepass_t *keepass = &keepasss[salt_pos];
|
||||||
|
|
||||||
u32 version = (u32) keepass->version;
|
u32 version = (u32) keepass->version;
|
||||||
u32 rounds = salt.salt_iter;
|
u32 rounds = salt.salt_iter;
|
||||||
u32 algorithm = (u32) keepass->algorithm;
|
u32 algorithm = (u32) keepass->algorithm;
|
||||||
|
u32 keyfile_len = (u32) keepass->keyfile_len;
|
||||||
|
|
||||||
u32 *ptr_final_random_seed = (u32 *) keepass->final_random_seed ;
|
u32 *ptr_final_random_seed = (u32 *) keepass->final_random_seed ;
|
||||||
u32 *ptr_transf_random_seed = (u32 *) keepass->transf_random_seed ;
|
u32 *ptr_transf_random_seed = (u32 *) keepass->transf_random_seed ;
|
||||||
u32 *ptr_enc_iv = (u32 *) keepass->enc_iv ;
|
u32 *ptr_enc_iv = (u32 *) keepass->enc_iv ;
|
||||||
u32 *ptr_contents_hash = (u32 *) keepass->contents_hash ;
|
u32 *ptr_contents_hash = (u32 *) keepass->contents_hash ;
|
||||||
|
u32 *ptr_keyfile = (u32 *) keepass->keyfile ;
|
||||||
|
|
||||||
/* specific to version 1 */
|
/* specific to version 1 */
|
||||||
u32 contents_len;
|
u32 contents_len;
|
||||||
@ -8423,25 +8425,25 @@ void ascii_digest (char *out_buf, uint salt_pos, uint digest_pos)
|
|||||||
|
|
||||||
for (uint i = 0; i < contents_hash_len; i++, ptr_data += 8)
|
for (uint i = 0; i < contents_hash_len; i++, ptr_data += 8)
|
||||||
sprintf (ptr_data, "%08x", ptr_contents_hash[i]);
|
sprintf (ptr_data, "%08x", ptr_contents_hash[i]);
|
||||||
|
|
||||||
*ptr_data = '*';
|
*ptr_data = '*';
|
||||||
ptr_data++;
|
ptr_data++;
|
||||||
|
|
||||||
/* inline flag */
|
/* inline flag */
|
||||||
*ptr_data = '1';
|
*ptr_data = '1';
|
||||||
ptr_data++;
|
ptr_data++;
|
||||||
|
|
||||||
*ptr_data = '*';
|
*ptr_data = '*';
|
||||||
ptr_data++;
|
ptr_data++;
|
||||||
|
|
||||||
char ptr_contents_len[10] = { 0 };
|
char ptr_contents_len[10] = { 0 };
|
||||||
|
|
||||||
sprintf ((char*) ptr_contents_len, "%d", contents_len);
|
sprintf ((char*) ptr_contents_len, "%d", contents_len);
|
||||||
|
|
||||||
sprintf (ptr_data, "%d", contents_len);
|
sprintf (ptr_data, "%d", contents_len);
|
||||||
|
|
||||||
ptr_data += strlen(ptr_contents_len);
|
ptr_data += strlen(ptr_contents_len);
|
||||||
|
|
||||||
*ptr_data = '*';
|
*ptr_data = '*';
|
||||||
ptr_data++;
|
ptr_data++;
|
||||||
|
|
||||||
@ -8452,7 +8454,7 @@ void ascii_digest (char *out_buf, uint salt_pos, uint digest_pos)
|
|||||||
{
|
{
|
||||||
expected_bytes_len = 8;
|
expected_bytes_len = 8;
|
||||||
ptr_expected_bytes = (u32 *) keepass->expected_bytes ;
|
ptr_expected_bytes = (u32 *) keepass->expected_bytes ;
|
||||||
|
|
||||||
for (uint i = 0; i < expected_bytes_len; i++, ptr_data += 8)
|
for (uint i = 0; i < expected_bytes_len; i++, ptr_data += 8)
|
||||||
sprintf (ptr_data, "%08x", ptr_expected_bytes[i]);
|
sprintf (ptr_data, "%08x", ptr_expected_bytes[i]);
|
||||||
|
|
||||||
@ -8462,6 +8464,28 @@ void ascii_digest (char *out_buf, uint salt_pos, uint digest_pos)
|
|||||||
for (uint i = 0; i < contents_hash_len; i++, ptr_data += 8)
|
for (uint i = 0; i < contents_hash_len; i++, ptr_data += 8)
|
||||||
sprintf (ptr_data, "%08x", ptr_contents_hash[i]);
|
sprintf (ptr_data, "%08x", ptr_contents_hash[i]);
|
||||||
}
|
}
|
||||||
|
if (keyfile_len)
|
||||||
|
{
|
||||||
|
*ptr_data = '*';
|
||||||
|
ptr_data++;
|
||||||
|
|
||||||
|
/* inline flag */
|
||||||
|
*ptr_data = '1';
|
||||||
|
ptr_data++;
|
||||||
|
|
||||||
|
*ptr_data = '*';
|
||||||
|
ptr_data++;
|
||||||
|
|
||||||
|
sprintf (ptr_data, "%d", keyfile_len);
|
||||||
|
|
||||||
|
ptr_data += 2;
|
||||||
|
|
||||||
|
*ptr_data = '*';
|
||||||
|
ptr_data++;
|
||||||
|
|
||||||
|
for (uint i = 0; i < 8; i++, ptr_data += 8)
|
||||||
|
sprintf (ptr_data, "%08x", ptr_keyfile[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -19163,6 +19187,13 @@ int keepass_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|||||||
char *enc_iv_pos;
|
char *enc_iv_pos;
|
||||||
u32 enc_iv_len;
|
u32 enc_iv_len;
|
||||||
|
|
||||||
|
/* default is no keyfile provided */
|
||||||
|
char *keyfile_len_pos;
|
||||||
|
u32 keyfile_len = 0;
|
||||||
|
u32 is_keyfile_present = 0;
|
||||||
|
char *keyfile_inline_pos;
|
||||||
|
char *keyfile_pos;
|
||||||
|
|
||||||
/* specific to version 1 */
|
/* specific to version 1 */
|
||||||
char *contents_len_pos;
|
char *contents_len_pos;
|
||||||
u32 contents_len;
|
u32 contents_len;
|
||||||
@ -19307,10 +19338,21 @@ int keepass_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|||||||
|
|
||||||
contents_len = contents_len / 4;
|
contents_len = contents_len / 4;
|
||||||
|
|
||||||
u32 real_contents_len = input_len - (contents_pos - input_buf);
|
keyfile_inline_pos = strchr (contents_pos, '*');
|
||||||
|
|
||||||
|
u32 real_contents_len;
|
||||||
|
|
||||||
|
if (keyfile_inline_pos == NULL)
|
||||||
|
real_contents_len = input_len - (contents_pos - input_buf);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
real_contents_len = keyfile_inline_pos - contents_pos;
|
||||||
|
keyfile_inline_pos++;
|
||||||
|
is_keyfile_present = 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (real_contents_len != keepass->contents_len * 2) return (PARSER_SALT_LENGTH);
|
if (real_contents_len != keepass->contents_len * 2) return (PARSER_SALT_LENGTH);
|
||||||
|
|
||||||
for (i = 0; i < contents_len; i++)
|
for (i = 0; i < contents_len; i++)
|
||||||
keepass->contents[i] = hex_to_u32 ((const u8 *) &contents_pos[i * 8]);
|
keepass->contents[i] = hex_to_u32 ((const u8 *) &contents_pos[i * 8]);
|
||||||
}
|
}
|
||||||
@ -19354,11 +19396,51 @@ int keepass_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|||||||
keepass->contents_hash[6] = hex_to_u32 ((const u8 *) &contents_hash_pos[48]);
|
keepass->contents_hash[6] = hex_to_u32 ((const u8 *) &contents_hash_pos[48]);
|
||||||
keepass->contents_hash[7] = hex_to_u32 ((const u8 *) &contents_hash_pos[56]);
|
keepass->contents_hash[7] = hex_to_u32 ((const u8 *) &contents_hash_pos[56]);
|
||||||
|
|
||||||
contents_hash_len = input_len - (int) (contents_hash_pos - input_buf);
|
keyfile_inline_pos = strchr (contents_hash_pos, '*');
|
||||||
|
|
||||||
|
if (keyfile_inline_pos == NULL)
|
||||||
|
contents_hash_len = input_len - (int) (contents_hash_pos - input_buf);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
contents_hash_len = keyfile_inline_pos - contents_hash_pos;
|
||||||
|
keyfile_inline_pos++;
|
||||||
|
is_keyfile_present = 1;
|
||||||
|
}
|
||||||
if (contents_hash_len != 64) return (PARSER_SALT_LENGTH);
|
if (contents_hash_len != 64) return (PARSER_SALT_LENGTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_keyfile_present != 0)
|
||||||
|
{
|
||||||
|
keyfile_len_pos = strchr (keyfile_inline_pos, '*');
|
||||||
|
|
||||||
|
keyfile_len_pos++;
|
||||||
|
|
||||||
|
keyfile_len = atoi (keyfile_len_pos);
|
||||||
|
|
||||||
|
keepass->keyfile_len = keyfile_len;
|
||||||
|
|
||||||
|
if (keyfile_len != 64) return (PARSER_SALT_LENGTH);
|
||||||
|
|
||||||
|
keyfile_pos = strchr (keyfile_len_pos, '*');
|
||||||
|
|
||||||
|
if (keyfile_pos == NULL) return (PARSER_SALT_LENGTH);
|
||||||
|
|
||||||
|
keyfile_pos++;
|
||||||
|
|
||||||
|
u32 real_keyfile_len = input_len - (keyfile_pos - input_buf);
|
||||||
|
|
||||||
|
if (real_keyfile_len != 64) return (PARSER_SALT_LENGTH);
|
||||||
|
|
||||||
|
keepass->keyfile[0] = hex_to_u32 ((const u8 *) &keyfile_pos[ 0]);
|
||||||
|
keepass->keyfile[1] = hex_to_u32 ((const u8 *) &keyfile_pos[ 8]);
|
||||||
|
keepass->keyfile[2] = hex_to_u32 ((const u8 *) &keyfile_pos[16]);
|
||||||
|
keepass->keyfile[3] = hex_to_u32 ((const u8 *) &keyfile_pos[24]);
|
||||||
|
keepass->keyfile[4] = hex_to_u32 ((const u8 *) &keyfile_pos[32]);
|
||||||
|
keepass->keyfile[5] = hex_to_u32 ((const u8 *) &keyfile_pos[40]);
|
||||||
|
keepass->keyfile[6] = hex_to_u32 ((const u8 *) &keyfile_pos[48]);
|
||||||
|
keepass->keyfile[7] = hex_to_u32 ((const u8 *) &keyfile_pos[56]);
|
||||||
|
}
|
||||||
|
|
||||||
digest[0] = keepass->enc_iv[0];
|
digest[0] = keepass->enc_iv[0];
|
||||||
digest[1] = keepass->enc_iv[1];
|
digest[1] = keepass->enc_iv[1];
|
||||||
digest[2] = keepass->enc_iv[2];
|
digest[2] = keepass->enc_iv[2];
|
||||||
|
133
tools/test.pl
133
tools/test.pl
@ -2232,7 +2232,7 @@ sub verify
|
|||||||
$spn = substr ($spn, 0, length ($spn) - 1);
|
$spn = substr ($spn, 0, length ($spn) - 1);
|
||||||
my $checksum = shift @data;
|
my $checksum = shift @data;
|
||||||
my $edata2 = shift @data;
|
my $edata2 = shift @data;
|
||||||
|
|
||||||
next unless ($signature eq "krb5tgs");
|
next unless ($signature eq "krb5tgs");
|
||||||
next unless (length ($checksum) == 32);
|
next unless (length ($checksum) == 32);
|
||||||
next unless (length ($edata2) >= 64);
|
next unless (length ($edata2) >= 64);
|
||||||
@ -2298,20 +2298,23 @@ sub verify
|
|||||||
|
|
||||||
my @data = split ('\*', $hash_in);
|
my @data = split ('\*', $hash_in);
|
||||||
|
|
||||||
next unless (scalar @data == 9 || scalar @data == 11);
|
next unless (scalar @data == 9
|
||||||
|
|| scalar @data == 11
|
||||||
|
|| scalar @data == 12
|
||||||
|
|| scalar @data == 14);
|
||||||
|
|
||||||
my $signature = shift @data;
|
my $signature = shift @data;
|
||||||
next unless ($signature eq '$keepass$');
|
next unless ($signature eq '$keepass$');
|
||||||
|
|
||||||
my $version = shift @data;
|
my $version = shift @data;
|
||||||
next unless ($version == 1 || $version == 2);
|
next unless ($version == 1 || $version == 2);
|
||||||
|
|
||||||
my $iteration = shift @data;
|
my $iteration = shift @data;
|
||||||
|
|
||||||
my $algorithm = shift @data;
|
my $algorithm = shift @data;
|
||||||
|
|
||||||
my $final_random_seed = shift @data;
|
my $final_random_seed = shift @data;
|
||||||
|
|
||||||
if ($version == 1)
|
if ($version == 1)
|
||||||
{
|
{
|
||||||
next unless (length ($final_random_seed) == 32);
|
next unless (length ($final_random_seed) == 32);
|
||||||
@ -2320,7 +2323,7 @@ sub verify
|
|||||||
{
|
{
|
||||||
next unless (length ($final_random_seed) == 64);
|
next unless (length ($final_random_seed) == 64);
|
||||||
}
|
}
|
||||||
|
|
||||||
my $transf_random_seed = shift @data;
|
my $transf_random_seed = shift @data;
|
||||||
next unless (length ($transf_random_seed) == 64);
|
next unless (length ($transf_random_seed) == 64);
|
||||||
|
|
||||||
@ -2336,7 +2339,7 @@ sub verify
|
|||||||
next unless ($inline_flags == 1);
|
next unless ($inline_flags == 1);
|
||||||
|
|
||||||
my $contents_len = shift @data;
|
my $contents_len = shift @data;
|
||||||
|
|
||||||
my $contents = shift @data;
|
my $contents = shift @data;
|
||||||
next unless (length ($contents) == $contents_len * 2);
|
next unless (length ($contents) == $contents_len * 2);
|
||||||
}
|
}
|
||||||
@ -2344,11 +2347,23 @@ sub verify
|
|||||||
{
|
{
|
||||||
my $expected_bytes = shift @data;
|
my $expected_bytes = shift @data;
|
||||||
next unless (length ($expected_bytes) == 64);
|
next unless (length ($expected_bytes) == 64);
|
||||||
|
|
||||||
my $contents_hash = shift @data;
|
my $contents_hash = shift @data;
|
||||||
next unless (length ($contents_hash) == 64);
|
next unless (length ($contents_hash) == 64);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (scalar @data == 12 || scalar @data == 14)
|
||||||
|
{
|
||||||
|
my $inline_flags = shift @data;
|
||||||
|
next unless ($inline_flags == 1);
|
||||||
|
|
||||||
|
my $keyfile_len = shift @data;
|
||||||
|
next unless ($keyfile_len == 64);
|
||||||
|
|
||||||
|
my $keyfile = shift @data;
|
||||||
|
next unless (length ($keyfile) == $keyfile_len);
|
||||||
|
}
|
||||||
|
|
||||||
$salt = substr ($hash_in, length ("*keepass*") + 1, length ($hash_in));
|
$salt = substr ($hash_in, length ("*keepass*") + 1, length ($hash_in));
|
||||||
|
|
||||||
next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
|
next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
|
||||||
@ -2656,7 +2671,7 @@ sub verify
|
|||||||
$hash_out = gen_hash ($mode, $word, $salt);
|
$hash_out = gen_hash ($mode, $word, $salt);
|
||||||
|
|
||||||
$len = length $hash_out;
|
$len = length $hash_out;
|
||||||
|
|
||||||
return unless (substr ($line, 0, $len) eq $hash_out);
|
return unless (substr ($line, 0, $len) eq $hash_out);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -6950,9 +6965,9 @@ END_CODE
|
|||||||
my $algorithm = $salt_arr[2];
|
my $algorithm = $salt_arr[2];
|
||||||
|
|
||||||
my $final_random_seed = $salt_arr[3];
|
my $final_random_seed = $salt_arr[3];
|
||||||
|
|
||||||
my $transf_random_seed = $salt_arr[4];
|
my $transf_random_seed = $salt_arr[4];
|
||||||
|
|
||||||
my $enc_iv = $salt_arr[5];
|
my $enc_iv = $salt_arr[5];
|
||||||
|
|
||||||
my $contents_hash;
|
my $contents_hash;
|
||||||
@ -6965,6 +6980,12 @@ END_CODE
|
|||||||
# specific to version 2
|
# specific to version 2
|
||||||
my $expected_bytes;
|
my $expected_bytes;
|
||||||
|
|
||||||
|
# specific to keyfile handling
|
||||||
|
my $inline_keyfile_flag;
|
||||||
|
my $keyfile_len;
|
||||||
|
my $keyfile_content;
|
||||||
|
my $keyfile_attributes = "";
|
||||||
|
|
||||||
$final_random_seed = pack ("H*", $final_random_seed);
|
$final_random_seed = pack ("H*", $final_random_seed);
|
||||||
|
|
||||||
$transf_random_seed = pack ("H*", $transf_random_seed);
|
$transf_random_seed = pack ("H*", $transf_random_seed);
|
||||||
@ -6972,21 +6993,56 @@ END_CODE
|
|||||||
$enc_iv = pack ("H*", $enc_iv);
|
$enc_iv = pack ("H*", $enc_iv);
|
||||||
|
|
||||||
my $intermediate_hash = sha256 ($word_buf);
|
my $intermediate_hash = sha256 ($word_buf);
|
||||||
|
|
||||||
if ($version == 1)
|
if ($version == 1)
|
||||||
{
|
{
|
||||||
$contents_hash = $salt_arr[6];
|
$contents_hash = $salt_arr[6];
|
||||||
$contents_hash = pack ("H*", $contents_hash);
|
$contents_hash = pack ("H*", $contents_hash);
|
||||||
|
|
||||||
$inline_flag = $salt_arr[7];
|
$inline_flag = $salt_arr[7];
|
||||||
|
|
||||||
$contents_len = $salt_arr[8];
|
$contents_len = $salt_arr[8];
|
||||||
|
|
||||||
$contents = $salt_arr[9];
|
$contents = $salt_arr[9];
|
||||||
$contents = pack ("H*", $contents);
|
$contents = pack ("H*", $contents);
|
||||||
|
|
||||||
|
# keyfile handling
|
||||||
|
if (scalar @salt_arr == 13)
|
||||||
|
{
|
||||||
|
$inline_keyfile_flag = $salt_arr[10];
|
||||||
|
|
||||||
|
$keyfile_len = $salt_arr[11];
|
||||||
|
|
||||||
|
$keyfile_content = $salt_arr[12];
|
||||||
|
|
||||||
|
$keyfile_attributes = $keyfile_attributes
|
||||||
|
. "*" . $inline_keyfile_flag
|
||||||
|
. "*" . $keyfile_len
|
||||||
|
. "*" . $keyfile_content;
|
||||||
|
|
||||||
|
$intermediate_hash = $intermediate_hash . pack ("H*", $keyfile_content);
|
||||||
|
$intermediate_hash = sha256 ($intermediate_hash);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
elsif ($version == 2)
|
elsif ($version == 2)
|
||||||
{
|
{
|
||||||
|
# keyfile handling
|
||||||
|
if (scalar @salt_arr == 11)
|
||||||
|
{
|
||||||
|
$inline_keyfile_flag = $salt_arr[8];
|
||||||
|
|
||||||
|
$keyfile_len = $salt_arr[9];
|
||||||
|
|
||||||
|
$keyfile_content = $salt_arr[10];
|
||||||
|
|
||||||
|
$intermediate_hash = $intermediate_hash . pack ("H*", $keyfile_content);
|
||||||
|
|
||||||
|
$keyfile_attributes = $keyfile_attributes
|
||||||
|
. "*" . $inline_keyfile_flag
|
||||||
|
. "*" . $keyfile_len
|
||||||
|
. "*" . $keyfile_content;
|
||||||
|
|
||||||
|
}
|
||||||
$intermediate_hash = sha256 ($intermediate_hash);
|
$intermediate_hash = sha256 ($intermediate_hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6998,11 +7054,11 @@ END_CODE
|
|||||||
|
|
||||||
$intermediate_hash = substr ($intermediate_hash, 0, 32);
|
$intermediate_hash = substr ($intermediate_hash, 0, 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
$intermediate_hash = sha256 ($intermediate_hash);
|
$intermediate_hash = sha256 ($intermediate_hash);
|
||||||
|
|
||||||
my $final_key = sha256 ($final_random_seed . $intermediate_hash);
|
my $final_key = sha256 ($final_random_seed . $intermediate_hash);
|
||||||
|
|
||||||
my $final_algorithm;
|
my $final_algorithm;
|
||||||
|
|
||||||
if ($version == 1 && $algorithm == 1)
|
if ($version == 1 && $algorithm == 1)
|
||||||
@ -7022,14 +7078,14 @@ END_CODE
|
|||||||
header => "none",
|
header => "none",
|
||||||
keysize => 32
|
keysize => 32
|
||||||
});
|
});
|
||||||
|
|
||||||
if ($version == 1)
|
if ($version == 1)
|
||||||
{
|
{
|
||||||
$contents_hash = sha256 ($contents);
|
$contents_hash = sha256 ($contents);
|
||||||
|
|
||||||
$contents = $cipher->encrypt($contents);
|
$contents = $cipher->encrypt($contents);
|
||||||
|
|
||||||
$tmp_hash = sprintf ('$keepass$*%d*%d*%d*%s*%s*%s*%s*%d*%d*%s',
|
$tmp_hash = sprintf ('$keepass$*%d*%d*%d*%s*%s*%s*%s*%d*%d*%s%s',
|
||||||
$version,
|
$version,
|
||||||
$iteration,
|
$iteration,
|
||||||
$algorithm,
|
$algorithm,
|
||||||
@ -7039,18 +7095,19 @@ END_CODE
|
|||||||
unpack ("H*", $contents_hash),
|
unpack ("H*", $contents_hash),
|
||||||
$inline_flag,
|
$inline_flag,
|
||||||
$contents_len,
|
$contents_len,
|
||||||
unpack ("H*", $contents));
|
unpack ("H*", $contents),
|
||||||
|
$keyfile_attributes);
|
||||||
}
|
}
|
||||||
if ($version == 2)
|
if ($version == 2)
|
||||||
{
|
{
|
||||||
$expected_bytes = $salt_arr[6];
|
$expected_bytes = $salt_arr[6];
|
||||||
|
|
||||||
$contents_hash = $salt_arr[7];
|
$contents_hash = $salt_arr[7];
|
||||||
$contents_hash = pack ("H*", $contents_hash);
|
$contents_hash = pack ("H*", $contents_hash);
|
||||||
|
|
||||||
$expected_bytes = $cipher->decrypt($contents_hash);
|
$expected_bytes = $cipher->decrypt($contents_hash);
|
||||||
|
|
||||||
$tmp_hash = sprintf ('$keepass$*%d*%d*%d*%s*%s*%s*%s*%s',
|
$tmp_hash = sprintf ('$keepass$*%d*%d*%d*%s*%s*%s*%s*%s%s',
|
||||||
$version,
|
$version,
|
||||||
$iteration,
|
$iteration,
|
||||||
$algorithm,
|
$algorithm,
|
||||||
@ -7058,7 +7115,8 @@ END_CODE
|
|||||||
unpack ("H*", $transf_random_seed),
|
unpack ("H*", $transf_random_seed),
|
||||||
unpack ("H*", $enc_iv),
|
unpack ("H*", $enc_iv),
|
||||||
unpack ("H*", $expected_bytes),
|
unpack ("H*", $expected_bytes),
|
||||||
unpack ("H*", $contents_hash));
|
unpack ("H*", $contents_hash),
|
||||||
|
$keyfile_attributes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8510,6 +8568,17 @@ sub get_random_keepass_salt
|
|||||||
|
|
||||||
my $salt_buf;
|
my $salt_buf;
|
||||||
|
|
||||||
|
my $is_keyfile = get_random_num (0, 2);
|
||||||
|
|
||||||
|
my $keyfile_attributes = "";
|
||||||
|
|
||||||
|
if ($is_keyfile == 1)
|
||||||
|
{
|
||||||
|
$keyfile_attributes = $keyfile_attributes
|
||||||
|
. "1*64*"
|
||||||
|
. unpack ("H*", randbytes (32));
|
||||||
|
}
|
||||||
|
|
||||||
if ($version == 1)
|
if ($version == 1)
|
||||||
{
|
{
|
||||||
$salt_buf = $version . '*' .
|
$salt_buf = $version . '*' .
|
||||||
@ -8521,13 +8590,14 @@ sub get_random_keepass_salt
|
|||||||
$contents_hash . '*' .
|
$contents_hash . '*' .
|
||||||
$inline_flag . '*' .
|
$inline_flag . '*' .
|
||||||
$contents_len . '*' .
|
$contents_len . '*' .
|
||||||
$contents;
|
$contents . '*' .
|
||||||
|
$keyfile_attributes;
|
||||||
}
|
}
|
||||||
elsif ($version == 2)
|
elsif ($version == 2)
|
||||||
{
|
{
|
||||||
$contents = randbytes (32);
|
$contents = randbytes (32);
|
||||||
$contents = unpack ("H*", $contents);
|
$contents = unpack ("H*", $contents);
|
||||||
|
|
||||||
$salt_buf = $version . '*' .
|
$salt_buf = $version . '*' .
|
||||||
$iteration . '*' .
|
$iteration . '*' .
|
||||||
$algorithm . '*' .
|
$algorithm . '*' .
|
||||||
@ -8535,7 +8605,8 @@ sub get_random_keepass_salt
|
|||||||
$transf_random_seed . '*' .
|
$transf_random_seed . '*' .
|
||||||
$enc_iv . '*' .
|
$enc_iv . '*' .
|
||||||
$contents_hash . '*' .
|
$contents_hash . '*' .
|
||||||
$contents;
|
$contents . '*' .
|
||||||
|
$keyfile_attributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $salt_buf;
|
return $salt_buf;
|
||||||
|
Loading…
Reference in New Issue
Block a user