1
0
mirror of https://github.com/hashcat/hashcat.git synced 2024-11-22 08:08:10 +00:00

New format -m 13400, Keepass 1 (AES/Twofish) and Keepass 2 (AES)

This commit is contained in:
Fist0urs 2016-04-02 14:36:02 +02:00
parent d0e7ee6824
commit 52b17a602f
12 changed files with 2712 additions and 10 deletions

1963
OpenCL/m13400.cl Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1375,6 +1375,8 @@ typedef struct
u32 digest_buf[4];
#elif defined _AXCRYPT_
u32 digest_buf[4];
#elif defined _KEEPASS_
u32 digest_buf[4];
#endif
} digest_t;
@ -1590,6 +1592,25 @@ typedef struct
} oldoffice34_t;
typedef struct
{
u32 version;
u32 algorithm;
u32 final_random_seed[8];
u32 transf_random_seed[8];
u32 enc_iv[4];
u32 contents_hash[8];
/* specific to version 1 */
u32 contents_len;
u32 contents[12500];
/* specific to version 2 */
u32 expected_bytes[8];
} keepass_t;
typedef struct
{
u32 digest[4];
@ -1913,6 +1934,12 @@ typedef struct
} axcrypt_tmp_t;
typedef struct
{
u32 tmp_digest[8];
} keepass_tmp_t;
typedef struct
{
u32 Kc[16];

View File

@ -27,6 +27,11 @@ Type.: Feature
File.: Kernel
Desc.: Added new hash mode -m 13300 = AxCrypt in memory SHA1
Type.: Feature
File.: Kernel
Desc.: Added new hash mode -m 13400 = Keepass 1 (AES/Twofish) and Keepass 2 (AES)
Issue: 92
Type.: Feature
File.: Kernel
Desc.: Extended support from 14 to 255 functions calls per rule on GPU

View File

@ -206,6 +206,7 @@ NVidia users require ForceWare 346.59 or later (recommended 358.09 or later)
- Lastpass
- Password Safe v2
- Password Safe v3
- Keepass 1 (AES/Twofish) and Keepass 2 (AES)
- eCryptfs
- Android FDE <= 4.3
- Android FDE (Samsung DEK)

View File

@ -71,7 +71,7 @@
#define SHA1C03 0xca62c1d6u
#endif
#if defined _SHA256_ || defined _PDF17L8_ || defined _SEVEN_ZIP_ || defined _ANDROIDFDE_ || defined _CLOUDKEY_ || defined _SCRYPT_ || defined _PBKDF2_SHA256_ || defined _SHA256_SHA1_ || defined _MS_DRSR_ || defined _ANDROIDFDE_SAMSUNG_ || defined _RAR5_
#if defined _SHA256_ || defined _PDF17L8_ || defined _SEVEN_ZIP_ || defined _ANDROIDFDE_ || defined _CLOUDKEY_ || defined _SCRYPT_ || defined _PBKDF2_SHA256_ || defined _SHA256_SHA1_ || defined _MS_DRSR_ || defined _ANDROIDFDE_SAMSUNG_ || defined _RAR5_ || defined _KEEPASS_
/**
* SHA256 Constants
*/

View File

@ -186,7 +186,7 @@
}
#endif
#if defined _SHA256_ || defined _PDF17L8_ || defined _SEVEN_ZIP_ || defined _ANDROIDFDE_ || defined _CLOUDKEY_ || defined _SCRYPT_ || defined _PBKDF2_SHA256_ || defined _SHA256_SHA1_ || defined _MS_DRSR_ || defined _ANDROIDFDE_SAMSUNG_ || defined _RAR5_
#if defined _SHA256_ || defined _PDF17L8_ || defined _SEVEN_ZIP_ || defined _ANDROIDFDE_ || defined _CLOUDKEY_ || defined _SCRYPT_ || defined _PBKDF2_SHA256_ || defined _SHA256_SHA1_ || defined _MS_DRSR_ || defined _ANDROIDFDE_SAMSUNG_ || defined _RAR5_ || defined _KEEPASS_
#define SHIFT_RIGHT_32(x,n) ((x) >> (n))

View File

@ -344,6 +344,7 @@ extern hc_thread_mutex_t mux_display;
#define HT_13100 "Kerberos 5 TGS-REP etype 23"
#define HT_13200 "AxCrypt"
#define HT_13300 "AxCrypt in memory SHA1"
#define HT_13400 "Keepass 1 (AES/Twofish) and Keepass 2 (AES)"
#define HT_00011 "Joomla < 2.5.18"
#define HT_00012 "PostgreSQL"
@ -683,6 +684,8 @@ extern hc_thread_mutex_t mux_display;
#define DISPLAY_LEN_MAX_13200 1 + 7 + 1 + 1 + 1 + 1 + 50 + 1 + 32 + 1 + 48 + 1 + 20480
#define DISPLAY_LEN_MIN_13300 1 + 12 + 1 + 32
#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_MAX_13400 1 + 7 + 1 + 1 + 10 + 1 + 3 + 1 + 64 + 1 + 64 + 1 + 32 + 1 + 64 + 1 + 4 + 1 + 100000
#define DISPLAY_LEN_MIN_11 32 + 1 + 16
#define DISPLAY_LEN_MAX_11 32 + 1 + 32
@ -945,6 +948,7 @@ extern hc_thread_mutex_t mux_display;
#define KERN_TYPE_KRB5TGS 13100
#define KERN_TYPE_AXCRYPT 13200
#define KERN_TYPE_SHA1_AXCRYPT 13300
#define KERN_TYPE_KEEPASS 13400
/**
* signatures
@ -1017,6 +1021,7 @@ extern hc_thread_mutex_t mux_display;
#define SIGNATURE_KRB5TGS "$krb5tgs$23"
#define SIGNATURE_AXCRYPT "$axcrypt$*1"
#define SIGNATURE_AXCRYPT_SHA1 "$axcrypt_sha1"
#define SIGNATURE_KEEPASS "$keepass$"
/**
* Default iteration numbers
@ -1069,6 +1074,7 @@ extern hc_thread_mutex_t mux_display;
#define ROUNDS_ANDROIDFDE_SAMSUNG 4096
#define ROUNDS_RAR5 (1 << 15)
#define ROUNDS_AXCRYPT 10000
#define ROUNDS_KEEPASS 6000
/**
* salt types
@ -1580,6 +1586,7 @@ int ms_drsr_parse_hash (char *input_buf, uint input_len, hash_t *hash
int androidfde_samsung_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf);
int axcrypt_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf);
int sha1axcrypt_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf);
int keepass_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf);
void load_kernel (const char *kernel_file, int num_devices, size_t *kernel_lengths, const u8 **kernel_sources);
void writeProgramBin (char *dst, u8 *binary, size_t binary_size);

View File

@ -136,6 +136,25 @@ typedef struct
} krb5tgs_t;
typedef struct
{
u32 version;
u32 algorithm;
u32 final_random_seed[8];
u32 transf_random_seed[8];
u32 enc_iv[4];
u32 contents_hash[8];
/* specific to version 1 */
u32 contents_len;
u32 contents[12500];
/* specific to version 2 */
u32 expected_bytes[8];
} keepass_t;
typedef struct
{
uint salt_buf[16];
@ -596,6 +615,12 @@ typedef struct
} axcrypt_tmp_t;
typedef struct
{
u32 tmp_digest[8];
} keepass_tmp_t;
typedef struct
{
u32 random[2];

View File

@ -148,7 +148,7 @@ double TARGET_MS_PROFILE[3] = { 8, 16, 96 };
#define MAX_DICTSTAT 10000
#define NUM_DEFAULT_BENCHMARK_ALGORITHMS 133
#define NUM_DEFAULT_BENCHMARK_ALGORITHMS 134
#define global_free(attr) \
{ \
@ -298,7 +298,8 @@ static uint default_benchmark_algorithms[NUM_DEFAULT_BENCHMARK_ALGORITHMS] =
6600,
8200,
11300,
12700
12700,
13400
};
/**
@ -742,6 +743,7 @@ const char *USAGE_BIG[] =
" 8200 = 1Password, cloudkeychain",
" 11300 = Bitcoin/Litecoin wallet.dat",
" 12700 = Blockchain, My Wallet",
" 13400 = Keepass 1 (AES/Twofish) and Keepass 2 (AES)"
"",
NULL
};
@ -5978,7 +5980,7 @@ int main (int argc, char **argv)
return (-1);
}
if (hash_mode_chgd && hash_mode > 13300) // just added to remove compiler warnings for hash_mode_chgd
if (hash_mode_chgd && hash_mode > 13400) // just added to remove compiler warnings for hash_mode_chgd
{
log_error ("ERROR: Invalid hash-type specified");
@ -10264,6 +10266,21 @@ int main (int argc, char **argv)
dgst_pos3 = 2;
break;
case 13400: hash_type = HASH_TYPE_AES;
salt_type = SALT_TYPE_EMBEDDED;
attack_exec = ATTACK_EXEC_OUTSIDE_KERNEL;
opts_type = OPTS_TYPE_PT_GENERATE_LE;
kern_type = KERN_TYPE_KEEPASS;
dgst_size = DGST_SIZE_4_4;
parse_func = keepass_parse_hash;
sort_by_digest = sort_by_digest_4_4;
opti_type = OPTI_TYPE_ZERO_BYTE;
dgst_pos0 = 0;
dgst_pos1 = 1;
dgst_pos2 = 2;
dgst_pos3 = 3;
break;
default: usage_mini_print (PROGNAME); return (-1);
}
@ -10368,6 +10385,7 @@ int main (int argc, char **argv)
case 12100: esalt_size = sizeof (pbkdf2_sha512_t); break;
case 13000: esalt_size = sizeof (rar5_t); break;
case 13100: esalt_size = sizeof (krb5tgs_t); break;
case 13400: esalt_size = sizeof (keepass_t); break;
}
data.esalt_size = esalt_size;
@ -11454,6 +11472,7 @@ int main (int argc, char **argv)
((seven_zip_t *) hashes_buf[0].esalt)->data_len = 112;
((seven_zip_t *) hashes_buf[0].esalt)->unpack_size = 112;
break;
case 13400: ((keepass_t *) hashes_buf[0].esalt)->version = 2;
}
}
@ -11627,6 +11646,8 @@ int main (int argc, char **argv)
break;
case 13200: hashes_buf[0].salt->salt_iter = ROUNDS_AXCRYPT;
break;
case 13400: hashes_buf[0].salt->salt_iter = ROUNDS_KEEPASS;
break;
}
hashes_cnt = 1;
@ -13733,6 +13754,7 @@ int main (int argc, char **argv)
case 12900: size_tmps = kernel_power_max * sizeof (pbkdf2_sha256_tmp_t); break;
case 13000: size_tmps = kernel_power_max * sizeof (pbkdf2_sha256_tmp_t); break;
case 13200: size_tmps = kernel_power_max * sizeof (axcrypt_tmp_t); break;
case 13400: size_tmps = kernel_power_max * sizeof (keepass_tmp_t); break;
};
// size_hooks

View File

@ -5851,6 +5851,7 @@ char *strhashtype (const uint hash_mode)
case 13100: return ((char *) HT_13100); break;
case 13200: return ((char *) HT_13200); break;
case 13300: return ((char *) HT_13300); break;
case 13400: return ((char *) HT_13400); break;
}
return ((char *) "Unknown");
@ -8348,6 +8349,120 @@ void ascii_digest (char *out_buf, uint salt_pos, uint digest_pos)
digest_buf[2],
digest_buf[3]);
}
else if (hash_mode == 13400)
{
keepass_t *keepasss = (keepass_t *) data.esalts_buf;
keepass_t *keepass = &keepasss[salt_pos];
u32 version = (u32) keepass->version;
u32 rounds = salt.salt_iter;
u32 algorithm = (u32) keepass->algorithm;
u32 *ptr_final_random_seed = (u32 *) keepass->final_random_seed ;
u32 *ptr_transf_random_seed = (u32 *) keepass->transf_random_seed ;
u32 *ptr_enc_iv = (u32 *) keepass->enc_iv ;
u32 *ptr_contents_hash = (u32 *) keepass->contents_hash ;
/* specific to version 1 */
u32 contents_len;
u32 *ptr_contents;
/* specific to version 2 */
u32 expected_bytes_len;
u32 *ptr_expected_bytes;
u32 final_random_seed_len;
u32 transf_random_seed_len;
u32 enc_iv_len;
u32 contents_hash_len;
transf_random_seed_len = 8;
enc_iv_len = 4;
contents_hash_len = 8;
final_random_seed_len = 8;
if (version == 1)
final_random_seed_len = 4;
snprintf (out_buf, len-1, "%s*%d*%d*%d",
SIGNATURE_KEEPASS,
version,
rounds,
algorithm);
char *ptr_data = out_buf;
ptr_data += strlen(out_buf);
*ptr_data = '*';
ptr_data++;
for (uint i = 0; i < final_random_seed_len; i++, ptr_data += 8)
sprintf (ptr_data, "%08x", ptr_final_random_seed[i]);
*ptr_data = '*';
ptr_data++;
for (uint i = 0; i < transf_random_seed_len; i++, ptr_data += 8)
sprintf (ptr_data, "%08x", ptr_transf_random_seed[i]);
*ptr_data = '*';
ptr_data++;
for (uint i = 0; i < enc_iv_len; i++, ptr_data += 8)
sprintf (ptr_data, "%08x", ptr_enc_iv[i]);
*ptr_data = '*';
ptr_data++;
if (version == 1)
{
contents_len = (u32) keepass->contents_len;
ptr_contents = (u32 *) keepass->contents;
for (uint i = 0; i < contents_hash_len; i++, ptr_data += 8)
sprintf (ptr_data, "%08x", ptr_contents_hash[i]);
*ptr_data = '*';
ptr_data++;
/* inline flag */
*ptr_data = '1';
ptr_data++;
*ptr_data = '*';
ptr_data++;
char ptr_contents_len[10] = { 0 };
sprintf ((char*) ptr_contents_len, "%d", contents_len);
sprintf (ptr_data, "%d", contents_len);
ptr_data += strlen(ptr_contents_len);
*ptr_data = '*';
ptr_data++;
for (uint i = 0; i < contents_len / 4; i++, ptr_data += 8)
sprintf (ptr_data, "%08x", ptr_contents[i]);
}
else if (version == 2)
{
expected_bytes_len = 8;
ptr_expected_bytes = (u32 *) keepass->expected_bytes ;
for (uint i = 0; i < expected_bytes_len; i++, ptr_data += 8)
sprintf (ptr_data, "%08x", ptr_expected_bytes[i]);
*ptr_data = '*';
ptr_data++;
for (uint i = 0; i < contents_hash_len; i++, ptr_data += 8)
sprintf (ptr_data, "%08x", ptr_contents_hash[i]);
}
}
else
{
if (hash_type == HASH_TYPE_MD4)
@ -19011,6 +19126,241 @@ int axcrypt_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
return (PARSER_OK);
}
int keepass_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
{
if ((input_len < DISPLAY_LEN_MIN_13400) || (input_len > DISPLAY_LEN_MAX_13400)) return (PARSER_GLOBAL_LENGTH);
if (memcmp (SIGNATURE_KEEPASS, input_buf, 9)) return (PARSER_SIGNATURE_UNMATCHED);
u32 *digest = (u32 *) hash_buf->digest;
salt_t *salt = hash_buf->salt;
keepass_t *keepass = (keepass_t *) hash_buf->esalt;
/**
* parse line
*/
char *version_pos;
char *rounds_pos;
char *algorithm_pos;
char *final_random_seed_pos;
u32 final_random_seed_len;
char *transf_random_seed_pos;
u32 transf_random_seed_len;
char *enc_iv_pos;
u32 enc_iv_len;
/* specific to version 1 */
char *contents_len_pos;
u32 contents_len;
char *contents_pos;
/* specific to version 2 */
char *expected_bytes_pos;
u32 expected_bytes_len;
char *contents_hash_pos;
u32 contents_hash_len;
version_pos = input_buf + 8 + 1 + 1;
keepass->version = atoi (version_pos);
rounds_pos = strchr (version_pos, '*');
rounds_pos++;
if (rounds_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
salt->salt_iter = (atoi (rounds_pos));
algorithm_pos = strchr (rounds_pos, '*');
algorithm_pos++;
if (algorithm_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
keepass->algorithm = atoi (algorithm_pos);
final_random_seed_pos = strchr (algorithm_pos, '*');
final_random_seed_pos++;
if (final_random_seed_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
keepass->final_random_seed[0] = hex_to_u32 ((const u8 *) &final_random_seed_pos[ 0]);
keepass->final_random_seed[1] = hex_to_u32 ((const u8 *) &final_random_seed_pos[ 8]);
keepass->final_random_seed[2] = hex_to_u32 ((const u8 *) &final_random_seed_pos[16]);
keepass->final_random_seed[3] = hex_to_u32 ((const u8 *) &final_random_seed_pos[24]);
if (keepass->version == 2)
{
keepass->final_random_seed[4] = hex_to_u32 ((const u8 *) &final_random_seed_pos[32]);
keepass->final_random_seed[5] = hex_to_u32 ((const u8 *) &final_random_seed_pos[40]);
keepass->final_random_seed[6] = hex_to_u32 ((const u8 *) &final_random_seed_pos[48]);
keepass->final_random_seed[7] = hex_to_u32 ((const u8 *) &final_random_seed_pos[56]);
}
transf_random_seed_pos = strchr (final_random_seed_pos, '*');
final_random_seed_len = transf_random_seed_pos - final_random_seed_pos;
if (keepass->version == 1 && final_random_seed_len != 32) return (PARSER_SALT_LENGTH);
if (keepass->version == 2 && final_random_seed_len != 64) return (PARSER_SALT_LENGTH);
transf_random_seed_pos++;
if (transf_random_seed_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
keepass->transf_random_seed[0] = hex_to_u32 ((const u8 *) &transf_random_seed_pos[ 0]);
keepass->transf_random_seed[1] = hex_to_u32 ((const u8 *) &transf_random_seed_pos[ 8]);
keepass->transf_random_seed[2] = hex_to_u32 ((const u8 *) &transf_random_seed_pos[16]);
keepass->transf_random_seed[3] = hex_to_u32 ((const u8 *) &transf_random_seed_pos[24]);
keepass->transf_random_seed[4] = hex_to_u32 ((const u8 *) &transf_random_seed_pos[32]);
keepass->transf_random_seed[5] = hex_to_u32 ((const u8 *) &transf_random_seed_pos[40]);
keepass->transf_random_seed[6] = hex_to_u32 ((const u8 *) &transf_random_seed_pos[48]);
keepass->transf_random_seed[7] = hex_to_u32 ((const u8 *) &transf_random_seed_pos[56]);
enc_iv_pos = strchr (transf_random_seed_pos, '*');
transf_random_seed_len = enc_iv_pos - transf_random_seed_pos;
if (transf_random_seed_len != 64) return (PARSER_SALT_LENGTH);
enc_iv_pos++;
if (enc_iv_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
keepass->enc_iv[0] = hex_to_u32 ((const u8 *) &enc_iv_pos[ 0]);
keepass->enc_iv[1] = hex_to_u32 ((const u8 *) &enc_iv_pos[ 8]);
keepass->enc_iv[2] = hex_to_u32 ((const u8 *) &enc_iv_pos[16]);
keepass->enc_iv[3] = hex_to_u32 ((const u8 *) &enc_iv_pos[24]);
if (keepass->version == 1)
{
contents_hash_pos = strchr (enc_iv_pos, '*');
enc_iv_len = contents_hash_pos - enc_iv_pos;
if (enc_iv_len != 32) return (PARSER_SALT_LENGTH);
contents_hash_pos++;
if (contents_hash_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
keepass->contents_hash[0] = hex_to_u32 ((const u8 *) &contents_hash_pos[ 0]);
keepass->contents_hash[1] = hex_to_u32 ((const u8 *) &contents_hash_pos[ 8]);
keepass->contents_hash[2] = hex_to_u32 ((const u8 *) &contents_hash_pos[16]);
keepass->contents_hash[3] = hex_to_u32 ((const u8 *) &contents_hash_pos[24]);
keepass->contents_hash[4] = hex_to_u32 ((const u8 *) &contents_hash_pos[32]);
keepass->contents_hash[5] = hex_to_u32 ((const u8 *) &contents_hash_pos[40]);
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]);
/* get length of contents following */
char *inline_flag_pos = strchr (contents_hash_pos, '*');
contents_hash_len = inline_flag_pos - contents_hash_pos;
if (contents_hash_len != 64) return (PARSER_SALT_LENGTH);
inline_flag_pos++;
u32 inline_flag = atoi (inline_flag_pos);
if (inline_flag != 1) return (PARSER_SALT_LENGTH);
contents_len_pos = strchr (inline_flag_pos, '*');
contents_len_pos++;
contents_len = atoi (contents_len_pos);
if (contents_len > 50000) return (PARSER_SALT_LENGTH);
contents_pos = strchr (contents_len_pos, '*');
contents_pos++;
u32 i;
keepass->contents_len = contents_len;
contents_len = contents_len / 4;
u32 real_contents_len = input_len - (contents_pos - input_buf);
if (real_contents_len != keepass->contents_len * 2) return (PARSER_SALT_LENGTH);
for (i = 0; i < contents_len; i++)
keepass->contents[i] = hex_to_u32 ((const u8 *) &contents_pos[i * 8]);
}
else if (keepass->version == 2)
{
expected_bytes_pos = strchr (enc_iv_pos, '*');
enc_iv_len = expected_bytes_pos - enc_iv_pos;
if (enc_iv_len != 32) return (PARSER_SALT_LENGTH);
expected_bytes_pos++;
if (expected_bytes_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
keepass->expected_bytes[0] = hex_to_u32 ((const u8 *) &expected_bytes_pos[ 0]);
keepass->expected_bytes[1] = hex_to_u32 ((const u8 *) &expected_bytes_pos[ 8]);
keepass->expected_bytes[2] = hex_to_u32 ((const u8 *) &expected_bytes_pos[16]);
keepass->expected_bytes[3] = hex_to_u32 ((const u8 *) &expected_bytes_pos[24]);
keepass->expected_bytes[4] = hex_to_u32 ((const u8 *) &expected_bytes_pos[32]);
keepass->expected_bytes[5] = hex_to_u32 ((const u8 *) &expected_bytes_pos[40]);
keepass->expected_bytes[6] = hex_to_u32 ((const u8 *) &expected_bytes_pos[48]);
keepass->expected_bytes[7] = hex_to_u32 ((const u8 *) &expected_bytes_pos[56]);
contents_hash_pos = strchr (expected_bytes_pos, '*');
expected_bytes_len = contents_hash_pos - expected_bytes_pos;
if (expected_bytes_len != 64) return (PARSER_SALT_LENGTH);
contents_hash_pos++;
if (contents_hash_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
keepass->contents_hash[0] = hex_to_u32 ((const u8 *) &contents_hash_pos[ 0]);
keepass->contents_hash[1] = hex_to_u32 ((const u8 *) &contents_hash_pos[ 8]);
keepass->contents_hash[2] = hex_to_u32 ((const u8 *) &contents_hash_pos[16]);
keepass->contents_hash[3] = hex_to_u32 ((const u8 *) &contents_hash_pos[24]);
keepass->contents_hash[4] = hex_to_u32 ((const u8 *) &contents_hash_pos[32]);
keepass->contents_hash[5] = hex_to_u32 ((const u8 *) &contents_hash_pos[40]);
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]);
contents_hash_len = input_len - (int) (contents_hash_pos - input_buf);
if (contents_hash_len != 64) return (PARSER_SALT_LENGTH);
}
digest[0] = keepass->enc_iv[0];
digest[1] = keepass->enc_iv[1];
digest[2] = keepass->enc_iv[2];
digest[3] = keepass->enc_iv[3];
salt->salt_buf[0] = keepass->transf_random_seed[0];
salt->salt_buf[1] = keepass->transf_random_seed[1];
salt->salt_buf[2] = keepass->transf_random_seed[2];
salt->salt_buf[3] = keepass->transf_random_seed[3];
salt->salt_buf[4] = keepass->transf_random_seed[4];
salt->salt_buf[5] = keepass->transf_random_seed[5];
salt->salt_buf[6] = keepass->transf_random_seed[6];
salt->salt_buf[7] = keepass->transf_random_seed[7];
return (PARSER_OK);
}
int cf10_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
{
if ((input_len < DISPLAY_LEN_MIN_12600) || (input_len > DISPLAY_LEN_MAX_12600)) return (PARSER_GLOBAL_LENGTH);

View File

@ -26,6 +26,7 @@ use Crypt::Digest::Whirlpool qw (whirlpool_hex);
use Crypt::RC4;
use Crypt::ScryptKDF qw (scrypt_hash scrypt_b64);
use Crypt::Rijndael;
use Crypt::Twofish;
use Crypt::Mode::ECB;
use Crypt::UnixCrypt_XS qw (crypt_rounds fold_password base64_to_int24 block_to_base64 int24_to_base64);
use MIME::Base64;
@ -44,7 +45,7 @@ my $hashcat = "./oclHashcat";
my $MAX_LEN = 55;
my @modes = (0, 10, 11, 12, 20, 21, 22, 23, 30, 40, 50, 60, 100, 101, 110, 111, 112, 120, 121, 122, 130, 131, 132, 140, 141, 150, 160, 190, 200, 300, 400, 500, 900, 1000, 1100, 1400, 1410, 1420, 1430, 1440, 1441, 1450, 1460, 1500, 1600, 1700, 1710, 1711, 1720, 1730, 1740, 1722, 1731, 1750, 1760, 1800, 2100, 2400, 2410, 2500, 2600, 2611, 2612, 2711, 2811, 3000, 3100, 3200, 3710, 3711, 3300, 3500, 3610, 3720, 3800, 3910, 4010, 4110, 4210, 4300, 4400, 4500, 4600, 4700, 4800, 4900, 5000, 5100, 5300, 5400, 5500, 5600, 5700, 5800, 6000, 6100, 6300, 6400, 6500, 6600, 6700, 6800, 6900, 7100, 7200, 7300, 7400, 7500, 7600, 7700, 7800, 7900, 8000, 8100, 8200, 8300, 8400, 8500, 8600, 8700, 8900, 9100, 9200, 9300, 9400, 9500, 9600, 9700, 9800, 9900, 10000, 10100, 10200, 10300, 10400, 10500, 10600, 10700, 10800, 10900, 11000, 11100, 11200, 11300, 11400, 11500, 11600, 11900, 12000, 12100, 12200, 12300, 12400, 12600, 12700, 12800, 12900, 13000, 13100, 13200, 13300);
my @modes = (0, 10, 11, 12, 20, 21, 22, 23, 30, 40, 50, 60, 100, 101, 110, 111, 112, 120, 121, 122, 130, 131, 132, 140, 141, 150, 160, 190, 200, 300, 400, 500, 900, 1000, 1100, 1400, 1410, 1420, 1430, 1440, 1441, 1450, 1460, 1500, 1600, 1700, 1710, 1711, 1720, 1730, 1740, 1722, 1731, 1750, 1760, 1800, 2100, 2400, 2410, 2500, 2600, 2611, 2612, 2711, 2811, 3000, 3100, 3200, 3710, 3711, 3300, 3500, 3610, 3720, 3800, 3910, 4010, 4110, 4210, 4300, 4400, 4500, 4600, 4700, 4800, 4900, 5000, 5100, 5300, 5400, 5500, 5600, 5700, 5800, 6000, 6100, 6300, 6400, 6500, 6600, 6700, 6800, 6900, 7100, 7200, 7300, 7400, 7500, 7600, 7700, 7800, 7900, 8000, 8100, 8200, 8300, 8400, 8500, 8600, 8700, 8900, 9100, 9200, 9300, 9400, 9500, 9600, 9700, 9800, 9900, 10000, 10100, 10200, 10300, 10400, 10500, 10600, 10700, 10800, 10900, 11000, 11100, 11200, 11300, 11400, 11500, 11600, 11900, 12000, 12100, 12200, 12300, 12400, 12600, 12700, 12800, 12900, 13000, 13100, 13200, 13300, 13400);
my %is_unicode = map { $_ => 1 } qw(30 40 130 131 132 133 140 141 1000 1100 1430 1440 1441 1730 1740 1731 5500 5600 8000 9400 9500 9600 9700 9800);
my %less_fifteen = map { $_ => 1 } qw(500 1600 1800 2400 2410 3200 6300 7400 10500 10700);
@ -2231,7 +2232,7 @@ sub verify
$spn = substr ($spn, 0, length ($spn) - 1);
my $checksum = shift @data;
my $edata2 = shift @data;
next unless ($signature eq "krb5tgs");
next unless (length ($checksum) == 32);
next unless (length ($edata2) >= 64);
@ -2288,6 +2289,70 @@ sub verify
next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
}
elsif ($mode == 13400)
{
($hash_in, $word) = split ":", $line;
next unless defined $hash_in;
next unless defined $word;
my @data = split ('\*', $hash_in);
next unless (scalar @data == 9 || scalar @data == 11);
my $signature = shift @data;
next unless ($signature eq '$keepass$');
my $version = shift @data;
next unless ($version == 1 || $version == 2);
my $iteration = shift @data;
my $algorithm = shift @data;
my $final_random_seed = shift @data;
if ($version == 1)
{
next unless (length ($final_random_seed) == 32);
}
elsif ($version == 2)
{
next unless (length ($final_random_seed) == 64);
}
my $transf_random_seed = shift @data;
next unless (length ($transf_random_seed) == 64);
my $enc_iv = shift @data;
next unless (length ($enc_iv) == 32);
if ($version == 1)
{
my $contents_hash = shift @data;
next unless (length ($contents_hash) == 64);
my $inline_flags = shift @data;
next unless ($inline_flags == 1);
my $contents_len = shift @data;
my $contents = shift @data;
next unless (length ($contents) == $contents_len * 2);
}
elsif ($version == 2)
{
my $expected_bytes = shift @data;
next unless (length ($expected_bytes) == 64);
my $contents_hash = shift @data;
next unless (length ($contents_hash) == 64);
}
$salt = substr ($hash_in, length ("*keepass*") + 1, length ($hash_in));
next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
}
else
{
print "ERROR: hash mode is not supported\n";
@ -2586,6 +2651,14 @@ sub verify
return unless (substr ($line, 0, $len) eq $hash_out);
}
elsif ($mode == 13400)
{
$hash_out = gen_hash ($mode, $word, $salt);
$len = length $hash_out;
return unless (substr ($line, 0, $len) eq $hash_out);
}
else
{
$hash_out = gen_hash ($mode, $word, $salt, $iter);
@ -3018,6 +3091,12 @@ sub passthrough
$tmp_hash = gen_hash ($mode, $word_buf, $salt_buf);
}
elsif ($mode == 13400)
{
$salt_buf = get_random_keepass_salt ();
$tmp_hash = gen_hash ($mode, $word_buf, $salt_buf);
}
else
{
print "ERROR: Unsupported hash type\n";
@ -3773,6 +3852,20 @@ sub single
}
}
}
elsif ($mode == 13400)
{
for (my $i = 1; $i < 16; $i++)
{
if ($len != 0)
{
rnd ($mode, $len, 16);
}
else
{
rnd ($mode, $i, 16);
}
}
}
}
}
@ -6845,6 +6938,130 @@ END_CODE
$tmp_hash = sprintf ('$axcrypt_sha1$%s', substr ($hash_buf, 0, 32));
}
elsif ($mode == 13400)
{
my @salt_arr = split ('\*', $salt_buf);
my $version = $salt_arr[0];
my $iteration = $salt_arr[1];
my $algorithm = $salt_arr[2];
my $final_random_seed = $salt_arr[3];
my $transf_random_seed = $salt_arr[4];
my $enc_iv = $salt_arr[5];
my $contents_hash;
# specific to version 1
my $inline_flag;
my $contents_len;
my $contents;
# specific to version 2
my $expected_bytes;
$final_random_seed = pack ("H*", $final_random_seed);
$transf_random_seed = pack ("H*", $transf_random_seed);
$enc_iv = pack ("H*", $enc_iv);
my $intermediate_hash = sha256 ($word_buf);
if ($version == 1)
{
$contents_hash = $salt_arr[6];
$contents_hash = pack ("H*", $contents_hash);
$inline_flag = $salt_arr[7];
$contents_len = $salt_arr[8];
$contents = $salt_arr[9];
$contents = pack ("H*", $contents);
}
elsif ($version == 2)
{
$intermediate_hash = sha256 ($intermediate_hash);
}
my $aes = Crypt::Mode::ECB->new ('AES', 1);
for (my $j = 0; $j < $iteration; $j++)
{
$intermediate_hash = $aes->encrypt ($intermediate_hash, $transf_random_seed);
$intermediate_hash = substr ($intermediate_hash, 0, 32);
}
$intermediate_hash = sha256 ($intermediate_hash);
my $final_key = sha256 ($final_random_seed . $intermediate_hash);
my $final_algorithm;
if ($version == 1 && $algorithm == 1)
{
$final_algorithm = "Crypt::Twofish";
}
else
{
$final_algorithm = "Crypt::Rijndael";
}
my $cipher = Crypt::CBC->new ({
key => $final_key,
cipher => $final_algorithm,
iv => $enc_iv,
literal_key => 1,
header => "none",
keysize => 32
});
if ($version == 1)
{
$contents_hash = sha256 ($contents);
$contents = $cipher->encrypt($contents);
$tmp_hash = sprintf ('$keepass$*%d*%d*%d*%s*%s*%s*%s*%d*%d*%s',
$version,
$iteration,
$algorithm,
unpack ("H*", $final_random_seed),
unpack ("H*", $transf_random_seed),
unpack ("H*", $enc_iv),
unpack ("H*", $contents_hash),
$inline_flag,
$contents_len,
unpack ("H*", $contents));
}
if ($version == 2)
{
$expected_bytes = $salt_arr[6];
$contents_hash = $salt_arr[7];
$contents_hash = pack ("H*", $contents_hash);
$expected_bytes = $cipher->decrypt($contents_hash);
$tmp_hash = sprintf ('$keepass$*%d*%d*%d*%s*%s*%s*%s*%s',
$version,
$iteration,
$algorithm,
unpack ("H*", $final_random_seed),
unpack ("H*", $transf_random_seed),
unpack ("H*", $enc_iv),
unpack ("H*", $expected_bytes),
unpack ("H*", $contents_hash));
}
}
return ($tmp_hash);
}
@ -6946,6 +7163,10 @@ sub rnd
{
$salt_buf = get_random_axcrypt_salt ();
}
elsif ($mode == 13400)
{
$salt_buf = get_random_keepass_salt ();
}
else
{
my @salt_arr;
@ -8229,7 +8450,7 @@ sub get_random_kerberos5_tgs_salt
sub get_random_axcrypt_salt
{
my $mysalt = randbytes (16);
$mysalt = unpack ("H*", $mysalt);
my $iteration = get_random_num (6, 100000);
@ -8239,6 +8460,87 @@ sub get_random_axcrypt_salt
return $salt_buf;
}
sub get_random_keepass_salt
{
my $version = 1;# get_random_num (1, 3);
my $algorithm;
my $iteration;
my $final_random_seed;
if ($version == 1)
{
$algorithm = 1;#get_random_num (0, 2);
$iteration = get_random_num (50000, 100000);
$final_random_seed = randbytes (16);
$final_random_seed = unpack ("H*", $final_random_seed);
}
elsif ($version == 2)
{
$algorithm = 0;
$iteration = get_random_num (6000, 100000);
$final_random_seed = randbytes (32);
$final_random_seed = unpack ("H*", $final_random_seed);
}
my $transf_random_seed = randbytes (32);
$transf_random_seed = unpack ("H*", $transf_random_seed);
my $enc_iv = randbytes (16);
$enc_iv = unpack ("H*", $enc_iv);
my $contents_hash = randbytes (32);
$contents_hash = unpack ("H*", $contents_hash);
my $inline_flag = 1;
my $contents_len = get_random_num (128, 500);
my $contents = randbytes ($contents_len);
$contents_len += 16 - $contents_len % 16;
$contents = unpack ("H*", $contents);
my $salt_buf;
if ($version == 1)
{
$salt_buf = $version . '*' .
$iteration . '*' .
$algorithm . '*' .
$final_random_seed . '*' .
$transf_random_seed . '*' .
$enc_iv . '*' .
$contents_hash . '*' .
$inline_flag . '*' .
$contents_len . '*' .
$contents;
}
elsif ($version == 2)
{
$contents = randbytes (32);
$contents = unpack ("H*", $contents);
$salt_buf = $version . '*' .
$iteration . '*' .
$algorithm . '*' .
$final_random_seed . '*' .
$transf_random_seed . '*' .
$enc_iv . '*' .
$contents_hash . '*' .
$contents;
}
return $salt_buf;
}
sub get_random_md5chap_salt
{
my $salt_buf = shift;

View File

@ -10,7 +10,7 @@
# missing hash types: 5200,6211,6221,6231,6241,6251,6261,6271,6281
HASH_TYPES="0 10 11 12 20 21 22 23 30 40 50 60 100 101 110 111 112 120 121 122 130 131 132 133 140 141 150 160 190 200 300 400 500 900 1000 1100 1400 1410 1420 1430 1440 1441 1450 1460 1500 1600 1700 1710 1711 1720 1722 1730 1731 1740 1750 1760 1800 2100 2400 2410 2500 2600 2611 2612 2711 2811 3000 3100 3200 3710 3711 3800 4300 4400 4500 4700 4800 4900 5000 5100 5300 5400 5500 5600 5700 5800 6000 6100 6300 6400 6500 6600 6700 6800 6900 7100 7200 7300 7400 7500 7600 7700 7800 7900 8000 8100 8200 8300 8400 8500 8600 8700 8900 9100 9200 9300 9400 9500 9600 9700 9800 9900 10000 10100 10200 10300 10400 10500 10600 10700 10800 10900 11000 11100 11200 11300 11400 11500 11600 11900 12000 12100 12200 12300 12400 12600 12800 12900 13000 13100 13200 13300"
HASH_TYPES="0 10 11 12 20 21 22 23 30 40 50 60 100 101 110 111 112 120 121 122 130 131 132 133 140 141 150 160 190 200 300 400 500 900 1000 1100 1400 1410 1420 1430 1440 1441 1450 1460 1500 1600 1700 1710 1711 1720 1722 1730 1731 1740 1750 1760 1800 2100 2400 2410 2500 2600 2611 2612 2711 2811 3000 3100 3200 3710 3711 3800 4300 4400 4500 4700 4800 4900 5000 5100 5300 5400 5500 5600 5700 5800 6000 6100 6300 6400 6500 6600 6700 6800 6900 7100 7200 7300 7400 7500 7600 7700 7800 7900 8000 8100 8200 8300 8400 8500 8600 8700 8900 9100 9200 9300 9400 9500 9600 9700 9800 9900 10000 10100 10200 10300 10400 10500 10600 10700 10800 10900 11000 11100 11200 11300 11400 11500 11600 11900 12000 12100 12200 12300 12400 12600 12800 12900 13000 13100 13200 13300 13400"
#ATTACK_MODES="0 1 3 6 7"
ATTACK_MODES="0 1 3 7"
@ -23,7 +23,7 @@ HASHFILE_ONLY="2500"
NEVER_CRACK="11600"
SLOW_ALGOS="400 500 501 1600 1800 2100 2500 3200 5200 5800 6211 6221 6231 6241 6251 6261 6271 6281 6300 6400 6500 6600 6700 6800 7100 7200 7400 7900 8200 8800 8900 9000 9100 9200 9300 9400 9500 9600 10000 10300 10500 10700 10900 11300 11600 11900 12000 12100 12200 12300 12400 12500 12800 12900 13000 13200"
SLOW_ALGOS="400 500 501 1600 1800 2100 2500 3200 5200 5800 6211 6221 6231 6241 6251 6261 6271 6281 6300 6400 6500 6600 6700 6800 7100 7200 7400 7900 8200 8800 8900 9000 9100 9200 9300 9400 9500 9600 10000 10300 10500 10700 10900 11300 11600 11900 12000 12100 12200 12300 12400 12500 12800 12900 13000 13200 13400"
OPTS="--quiet --force --potfile-disable --runtime 200 --gpu-temp-disable --weak-hash-threshold=0 -u 1024 -n 128"