static int mp_setup_usr (hashcat_ctx_t *hashcat_ctx, cs_t *mp_sys, cs_t *mp_usr, const char *buf, const u32 userindex) { FILE *fp = fopen (buf, "rb"); if (fp == NULL) // feof() in case if file is empty { const int rc = mp_expand (hashcat_ctx, buf, strlen (buf), mp_sys, mp_usr, userindex, 1); if (rc == -1) return -1; } else { char mp_file[1024]; const size_t nread = hc_fread (mp_file, 1, sizeof (mp_file) - 1, fp); if (!feof (fp)) { event_log_error (hashcat_ctx, "%s: Custom charset file is too large.", buf); fclose (fp); return -1; } fclose (fp); if (nread == 0) { event_log_error (hashcat_ctx, "%s: Custom charset file is empty.", buf); return -1; } mp_file[nread] = 0; const size_t len = superchop_with_length (mp_file, nread); if (len == 0) { event_log_error (hashcat_ctx, "%s: Custom charset file is corrupted.", buf); return -1; } const int rc = mp_expand (hashcat_ctx, mp_file, len, mp_sys, mp_usr, userindex, 0); if (rc == -1) return -1; } return 0; }
static int sp_setup_tbl (hashcat_ctx_t *hashcat_ctx) { folder_config_t *folder_config = hashcat_ctx->folder_config; mask_ctx_t *mask_ctx = hashcat_ctx->mask_ctx; user_options_t *user_options = hashcat_ctx->user_options; char *shared_dir = folder_config->shared_dir; char *hcstat = user_options->markov_hcstat; u32 disable = user_options->markov_disable; u32 classic = user_options->markov_classic; hcstat_table_t *root_table_buf = mask_ctx->root_table_buf; hcstat_table_t *markov_table_buf = mask_ctx->markov_table_buf; /** * Initialize hcstats */ u64 *root_stats_buf = (u64 *) hccalloc (SP_ROOT_CNT, sizeof (u64)); u64 *root_stats_ptr = root_stats_buf; u64 *root_stats_buf_by_pos[SP_PW_MAX]; for (int i = 0; i < SP_PW_MAX; i++) { root_stats_buf_by_pos[i] = root_stats_ptr; root_stats_ptr += CHARSIZ; } u64 *markov_stats_buf = (u64 *) hccalloc (SP_MARKOV_CNT, sizeof (u64)); u64 *markov_stats_ptr = markov_stats_buf; u64 *markov_stats_buf_by_key[SP_PW_MAX][CHARSIZ]; for (int i = 0; i < SP_PW_MAX; i++) { for (int j = 0; j < CHARSIZ; j++) { markov_stats_buf_by_key[i][j] = markov_stats_ptr; markov_stats_ptr += CHARSIZ; } } /** * Load hcstats File */ char hcstat_tmp[256]; if (hcstat == NULL) { snprintf (hcstat_tmp, sizeof (hcstat_tmp), "%s/%s", shared_dir, SP_HCSTAT); hcstat = hcstat_tmp; } struct stat s; if (stat (hcstat, &s) == -1) { event_log_error (hashcat_ctx, "%s: %s", hcstat, strerror (errno)); return -1; } FILE *fd = fopen (hcstat, "rb"); if (fd == NULL) { event_log_error (hashcat_ctx, "%s: %s", hcstat, strerror (errno)); return -1; } u8 *inbuf = (u8 *) hcmalloc (s.st_size); SizeT inlen = (SizeT) hc_fread (inbuf, 1, s.st_size, fd); if (inlen != (SizeT) s.st_size) { event_log_error (hashcat_ctx, "%s: Could not read data.", hcstat); fclose (fd); hcfree (inbuf); return -1; } fclose (fd); u8 *outbuf = (u8 *) hcmalloc (SP_FILESZ); SizeT outlen = SP_FILESZ; const char props = 0x1c; // lzma properties constant, retrieved with 7z2hashcat const SRes res = hc_lzma2_decompress (inbuf, &inlen, outbuf, &outlen, &props); if (res != SZ_OK) { event_log_error (hashcat_ctx, "%s: Could not uncompress data.", hcstat); hcfree (inbuf); hcfree (outbuf); return -1; } if (outlen != SP_FILESZ) { event_log_error (hashcat_ctx, "%s: Could not uncompress data.", hcstat); hcfree (inbuf); hcfree (outbuf); return -1; } u64 *ptr = (u64 *) outbuf; u64 v = *ptr++; u64 z = *ptr++; memcpy (root_stats_buf, ptr, sizeof (u64) * SP_ROOT_CNT); ptr += SP_ROOT_CNT; memcpy (markov_stats_buf, ptr, sizeof (u64) * SP_MARKOV_CNT); // ptr += SP_MARKOV_CNT; hcfree (inbuf); hcfree (outbuf); /** * switch endianess */ v = byte_swap_64 (v); z = byte_swap_64 (z); for (int i = 0; i < SP_ROOT_CNT; i++) root_stats_buf[i] = byte_swap_64 (root_stats_buf[i]); for (int i = 0; i < SP_MARKOV_CNT; i++) markov_stats_buf[i] = byte_swap_64 (markov_stats_buf[i]); /** * verify header */ if (v != SP_VERSION) { event_log_error (hashcat_ctx, "%s: Invalid header", hcstat); return -1; } if (z != 0) { event_log_error (hashcat_ctx, "%s: Invalid header", hcstat); return -1; } /** * Markov modifier of hcstat_table on user request */ if (disable) { memset (root_stats_buf, 0, SP_ROOT_CNT * sizeof (u64)); memset (markov_stats_buf, 0, SP_MARKOV_CNT * sizeof (u64)); } if (classic) { /* Add all stats to first position */ for (int i = 1; i < SP_PW_MAX; i++) { u64 *out = root_stats_buf_by_pos[0]; u64 *in = root_stats_buf_by_pos[i]; for (int j = 0; j < CHARSIZ; j++) { *out++ += *in++; } } for (int i = 1; i < SP_PW_MAX; i++) { u64 *out = markov_stats_buf_by_key[0][0]; u64 *in = markov_stats_buf_by_key[i][0]; for (int j = 0; j < CHARSIZ; j++) { for (int k = 0; k < CHARSIZ; k++) { *out++ += *in++; } } } /* copy them to all pw_positions */ for (int i = 1; i < SP_PW_MAX; i++) { memcpy (root_stats_buf_by_pos[i], root_stats_buf_by_pos[0], CHARSIZ * sizeof (u64)); } for (int i = 1; i < SP_PW_MAX; i++) { memcpy (markov_stats_buf_by_key[i][0], markov_stats_buf_by_key[0][0], CHARSIZ * CHARSIZ * sizeof (u64)); } } /** * Initialize tables */ hcstat_table_t *root_table_ptr = root_table_buf; hcstat_table_t *root_table_buf_by_pos[SP_PW_MAX]; for (int i = 0; i < SP_PW_MAX; i++) { root_table_buf_by_pos[i] = root_table_ptr; root_table_ptr += CHARSIZ; } hcstat_table_t *markov_table_ptr = markov_table_buf; hcstat_table_t *markov_table_buf_by_key[SP_PW_MAX][CHARSIZ]; for (int i = 0; i < SP_PW_MAX; i++) { for (int j = 0; j < CHARSIZ; j++) { markov_table_buf_by_key[i][j] = markov_table_ptr; markov_table_ptr += CHARSIZ; } } /** * Convert hcstat to tables */ for (int i = 0; i < SP_ROOT_CNT; i++) { u32 key = i % CHARSIZ; root_table_buf[i].key = key; root_table_buf[i].val = root_stats_buf[i]; } for (int i = 0; i < SP_MARKOV_CNT; i++) { u32 key = i % CHARSIZ; markov_table_buf[i].key = key; markov_table_buf[i].val = markov_stats_buf[i]; } hcfree (root_stats_buf); hcfree (markov_stats_buf); /** * Finally sort them */ for (int i = 0; i < SP_PW_MAX; i++) { qsort (root_table_buf_by_pos[i], CHARSIZ, sizeof (hcstat_table_t), sp_comp_val); } for (int i = 0; i < SP_PW_MAX; i++) { for (int j = 0; j < CHARSIZ; j++) { qsort (markov_table_buf_by_key[i][j], CHARSIZ, sizeof (hcstat_table_t), sp_comp_val); } } return 0; }
int hashes_init_stage1 (hashcat_ctx_t *hashcat_ctx) { hashconfig_t *hashconfig = hashcat_ctx->hashconfig; hashes_t *hashes = hashcat_ctx->hashes; user_options_t *user_options = hashcat_ctx->user_options; user_options_extra_t *user_options_extra = hashcat_ctx->user_options_extra; /** * load hashes, part I: find input mode, count hashes */ const char *hashfile = hashes->hashfile; const u32 hashlist_mode = hashes->hashlist_mode; u32 hashlist_format = HLFMT_HASHCAT; u64 hashes_avail = 0; if ((user_options->benchmark == false) && (user_options->stdout_flag == false) && (user_options->keyspace == false)) { if (hashlist_mode == HL_MODE_ARG) { if ((hashconfig->hash_mode == 2500) || (hashconfig->hash_mode == 2501)) { struct stat st; if (stat (hashes->hashfile, &st) == -1) { event_log_error (hashcat_ctx, "%s: %s", hashes->hashfile, strerror (errno)); return -1; } // 392 = old hccap_t size if ((st.st_size % 392) == 0) { const int rc = check_old_hccap (hashes->hashfile); if (rc == 1) { event_log_error (hashcat_ctx, "%s: Old hccap format detected! You need to update: https://hashcat.net/q/hccapx", hashes->hashfile); return -1; } } hashes_avail = st.st_size / sizeof (hccapx_t); } else if (hashconfig->hash_mode == 14600) { struct stat st; if (stat (hashes->hashfile, &st) == -1) { event_log_error (hashcat_ctx, "%s: %s", hashes->hashfile, strerror (errno)); return -1; } hashes_avail = LUKS_NUMKEYS; } else { hashes_avail = 1; } } else if (hashlist_mode == HL_MODE_FILE) { FILE *fp = NULL; if ((fp = fopen (hashfile, "rb")) == NULL) { event_log_error (hashcat_ctx, "%s: %s", hashfile, strerror (errno)); return -1; } EVENT_DATA (EVENT_HASHLIST_COUNT_LINES_PRE, hashfile, strlen (hashfile)); hashes_avail = count_lines (fp); EVENT_DATA (EVENT_HASHLIST_COUNT_LINES_POST, hashfile, strlen (hashfile)); rewind (fp); if (hashes_avail == 0) { event_log_error (hashcat_ctx, "hashfile is empty or corrupt."); fclose (fp); return -1; } hashlist_format = hlfmt_detect (hashcat_ctx, fp, 100); // 100 = max numbers to "scan". could be hashes_avail, too if ((user_options->remove == true) && (hashlist_format != HLFMT_HASHCAT)) { event_log_error (hashcat_ctx, "Use of --remove is not supported in native hashfile-format mode."); fclose (fp); return -1; } fclose (fp); } } else { hashes_avail = 1; } if (hashconfig->hash_mode == 3000) hashes_avail *= 2; hashes->hashlist_format = hashlist_format; /** * load hashes, part II: allocate required memory, set pointers */ hash_t *hashes_buf = (hash_t *) hccalloc (hashes_avail, sizeof (hash_t)); void *digests_buf = hccalloc (hashes_avail, hashconfig->dgst_size); salt_t *salts_buf = NULL; void *esalts_buf = NULL; void *hook_salts_buf = NULL; if ((user_options->username == true) || (hashconfig->opts_type & OPTS_TYPE_HASH_COPY) || (hashconfig->opts_type & OPTS_TYPE_HASH_SPLIT)) { u32 hash_pos; for (hash_pos = 0; hash_pos < hashes_avail; hash_pos++) { hashinfo_t *hash_info = (hashinfo_t *) hcmalloc (sizeof (hashinfo_t)); hashes_buf[hash_pos].hash_info = hash_info; if (user_options->username == true) { hash_info->user = (user_t *) hcmalloc (sizeof (user_t)); } if (hashconfig->opts_type & OPTS_TYPE_HASH_COPY) { if (user_options->benchmark == false) { hash_info->orighash = (char *) hcmalloc (256); } } if (hashconfig->opts_type & OPTS_TYPE_HASH_SPLIT) { hash_info->split = (split_t *) hcmalloc (sizeof (split_t)); } } } if (hashconfig->is_salted == true) { salts_buf = (salt_t *) hccalloc (hashes_avail, sizeof (salt_t)); if (hashconfig->esalt_size > 0) { esalts_buf = hccalloc (hashes_avail, hashconfig->esalt_size); } if (hashconfig->hook_salt_size > 0) { hook_salts_buf = (seven_zip_hook_salt_t *) hccalloc (hashes_avail, hashconfig->hook_salt_size); } } else { salts_buf = (salt_t *) hccalloc (1, sizeof (salt_t)); } for (u32 hash_pos = 0; hash_pos < hashes_avail; hash_pos++) { hashes_buf[hash_pos].digest = ((char *) digests_buf) + (hash_pos * hashconfig->dgst_size); if (hashconfig->is_salted == true) { hashes_buf[hash_pos].salt = &salts_buf[hash_pos]; if (hashconfig->esalt_size > 0) { hashes_buf[hash_pos].esalt = ((char *) esalts_buf) + (hash_pos * hashconfig->esalt_size); } if (hashconfig->hook_salt_size > 0) { hashes_buf[hash_pos].hook_salt = ((char *) hook_salts_buf) + (hash_pos * hashconfig->hook_salt_size); } } else { hashes_buf[hash_pos].salt = &salts_buf[0]; } } hashes->hashes_buf = hashes_buf; hashes->digests_buf = digests_buf; hashes->salts_buf = salts_buf; hashes->esalts_buf = esalts_buf; hashes->hook_salts_buf = hook_salts_buf; /** * load hashes, part III: parse hashes or generate them if benchmark */ u32 hashes_cnt = 0; if (user_options->benchmark == true) { hashconfig_benchmark_defaults (hashcat_ctx, hashes_buf[0].salt, hashes_buf[0].esalt, hashes_buf[0].hook_salt); hashes->hashfile = "-"; hashes_cnt = 1; } else if (user_options->example_hashes == true) { } else if (user_options->keyspace == true) { } else if (user_options->stdout_flag == true) { } else if (user_options->opencl_info == true) { } else { if (hashes_avail == 0) { // ??? } else if (hashlist_mode == HL_MODE_ARG) { char *input_buf = user_options_extra->hc_hash; size_t input_len = strlen (input_buf); char *hash_buf = NULL; size_t hash_len = 0; hlfmt_hash (hashcat_ctx, hashlist_format, input_buf, input_len, &hash_buf, &hash_len); bool hash_fmt_error = 0; if (hash_len < 1) hash_fmt_error = 1; if (hash_buf == NULL) hash_fmt_error = 1; if (hash_fmt_error) { event_log_warning (hashcat_ctx, "Failed to parse hashes using the '%s' format.", strhlfmt (hashlist_format)); } else { if (hashconfig->opts_type & OPTS_TYPE_HASH_COPY) { hashinfo_t *hash_info_tmp = hashes_buf[hashes_cnt].hash_info; hash_info_tmp->orighash = hcstrdup (hash_buf); } if (hashconfig->is_salted == true) { memset (hashes_buf[0].salt, 0, sizeof (salt_t)); } if (hashconfig->esalt_size > 0) { memset (hashes_buf[0].esalt, 0, hashconfig->esalt_size); } if (hashconfig->hook_salt_size > 0) { memset (hashes_buf[0].hook_salt, 0, hashconfig->hook_salt_size); } int parser_status = PARSER_OK; if ((hashconfig->hash_mode == 2500) || (hashconfig->hash_mode == 2501)) { hashes->hashlist_mode = HL_MODE_FILE; FILE *fp = fopen (hash_buf, "rb"); if (fp == NULL) { event_log_error (hashcat_ctx, "%s: %s", hash_buf, strerror (errno)); return -1; } char *in = (char *) hcmalloc (sizeof (hccapx_t)); while (!feof (fp)) { const size_t nread = hc_fread (in, sizeof (hccapx_t), 1, fp); if (nread == 0) break; if (hashes_avail == hashes_cnt) { event_log_warning (hashcat_ctx, "Hashfile '%s': File changed during runtime. Skipping new data.", hash_buf); break; } if (hashconfig->is_salted == true) { memset (hashes_buf[hashes_cnt].salt, 0, sizeof (salt_t)); } if (hashconfig->esalt_size > 0) { memset (hashes_buf[hashes_cnt].esalt, 0, hashconfig->esalt_size); if ((user_options->hash_mode == 2500) || (user_options->hash_mode == 2501)) { wpa_t *wpa = (wpa_t *) hashes_buf[hashes_cnt].esalt; if (user_options->hccapx_message_pair_chgd == true) { wpa->message_pair_chgd = (int) user_options->hccapx_message_pair_chgd; wpa->message_pair = (u8) user_options->hccapx_message_pair; } wpa->nonce_error_corrections = user_options->nonce_error_corrections; } } if (hashconfig->hook_salt_size > 0) { memset (hashes_buf[hashes_cnt].hook_salt, 0, hashconfig->hook_salt_size); } parser_status = hashconfig->parse_func ((u8 *) in, sizeof (hccapx_t), &hashes_buf[hashes_cnt], hashconfig); if (parser_status != PARSER_OK) { event_log_warning (hashcat_ctx, "Hashfile '%s': %s", hash_buf, strparser (parser_status)); continue; } hashes_cnt++; } hcfree (in); fclose (fp); } else if (hashconfig->hash_mode == 3000) { if (hash_len == 32) { parser_status = hashconfig->parse_func ((u8 *) hash_buf, 16, &hashes_buf[hashes_cnt], hashconfig); if (parser_status == PARSER_OK) { hashes_buf[hashes_cnt].hash_info->split->split_group = 0; hashes_buf[hashes_cnt].hash_info->split->split_origin = SPLIT_ORIGIN_LEFT; hashes_cnt++; } else { event_log_warning (hashcat_ctx, "Hash '%s': %s", input_buf, strparser (parser_status)); } parser_status = hashconfig->parse_func ((u8 *) hash_buf + 16, 16, &hashes_buf[hashes_cnt], hashconfig); if (parser_status == PARSER_OK) { hashes_buf[hashes_cnt].hash_info->split->split_group = 0; hashes_buf[hashes_cnt].hash_info->split->split_origin = SPLIT_ORIGIN_RIGHT; hashes_cnt++; } else { event_log_warning (hashcat_ctx, "Hash '%s': %s", input_buf, strparser (parser_status)); } } else { parser_status = hashconfig->parse_func ((u8 *) hash_buf, (u32) hash_len, &hashes_buf[hashes_cnt], hashconfig); if (parser_status == PARSER_OK) { hashes_buf[hashes_cnt].hash_info->split->split_group = 0; hashes_buf[hashes_cnt].hash_info->split->split_origin = SPLIT_ORIGIN_NONE; hashes_cnt++; } else { event_log_warning (hashcat_ctx, "Hash '%s': %s", input_buf, strparser (parser_status)); } } } else if (hashconfig->hash_mode == 14600) { hashes->hashlist_mode = HL_MODE_FILE; for (int keyslot_idx = 0; keyslot_idx < LUKS_NUMKEYS; keyslot_idx++) { parser_status = luks_parse_hash ((u8 *) hash_buf, (u32) hash_len, &hashes_buf[hashes_cnt], hashconfig, keyslot_idx); if (parser_status != PARSER_OK) { if (parser_status != PARSER_LUKS_KEY_DISABLED) { event_log_warning (hashcat_ctx, "Hashfile '%s': %s", hash_buf, strparser (parser_status)); } continue; } hashes_cnt++; } } else { parser_status = hashconfig->parse_func ((u8 *) hash_buf, (u32) hash_len, &hashes_buf[hashes_cnt], hashconfig); if (parser_status == PARSER_OK) { hashes_cnt++; } else { event_log_warning (hashcat_ctx, "Hash '%s': %s", input_buf, strparser (parser_status)); } } } } else if (hashlist_mode == HL_MODE_FILE) { FILE *fp; if ((fp = fopen (hashfile, "rb")) == NULL) { event_log_error (hashcat_ctx, "%s: %s", hashfile, strerror (errno)); return -1; } u32 line_num = 0; char *line_buf = (char *) hcmalloc (HCBUFSIZ_LARGE); time_t prev = 0; time_t now = 0; while (!feof (fp)) { line_num++; const size_t line_len = fgetl (fp, line_buf); if (line_len == 0) continue; if (hashes_avail == hashes_cnt) { event_log_warning (hashcat_ctx, "Hashfile '%s' on line %u: File changed during runtime. Skipping new data.", hashes->hashfile, line_num); break; } char *hash_buf = NULL; size_t hash_len = 0; hlfmt_hash (hashcat_ctx, hashlist_format, line_buf, line_len, &hash_buf, &hash_len); bool hash_fmt_error = 0; if (hash_len < 1) hash_fmt_error = 1; if (hash_buf == NULL) hash_fmt_error = 1; if (hash_fmt_error) { event_log_warning (hashcat_ctx, "Failed to parse hashes using the '%s' format.", strhlfmt (hashlist_format)); continue; } if (user_options->username == true) { char *user_buf = NULL; size_t user_len = 0; hlfmt_user (hashcat_ctx, hashlist_format, line_buf, line_len, &user_buf, &user_len); // special case: // both hash_t need to have the username info if the pwdump format is used (i.e. we have 2 hashes for 3000, both with same user) u32 hashes_per_user = 1; if (hashconfig->hash_mode == 3000) // the following conditions should be true if (hashlist_format == HLFMT_PWDUMP) { if (hash_len == 32) { hashes_per_user = 2; } } for (u32 i = 0; i < hashes_per_user; i++) { user_t **user = &hashes_buf[hashes_cnt + i].hash_info->user; *user = (user_t *) hcmalloc (sizeof (user_t)); user_t *user_ptr = *user; if (user_buf != NULL) { user_ptr->user_name = hcstrdup (user_buf); } else { user_ptr->user_name = hcstrdup (""); } user_ptr->user_len = (u32) user_len; } } if (hashconfig->opts_type & OPTS_TYPE_HASH_COPY) { hashinfo_t *hash_info_tmp = hashes_buf[hashes_cnt].hash_info; hash_info_tmp->orighash = hcstrdup (hash_buf); } if (hashconfig->is_salted == true) { memset (hashes_buf[hashes_cnt].salt, 0, sizeof (salt_t)); } if (hashconfig->esalt_size > 0) { memset (hashes_buf[hashes_cnt].esalt, 0, hashconfig->esalt_size); } if (hashconfig->hook_salt_size > 0) { memset (hashes_buf[hashes_cnt].hook_salt, 0, hashconfig->hook_salt_size); } if (hashconfig->hash_mode == 3000) { if (hash_len == 32) { int parser_status = hashconfig->parse_func ((u8 *) hash_buf, 16, &hashes_buf[hashes_cnt], hashconfig); if (parser_status < PARSER_GLOBAL_ZERO) { char *tmp_line_buf; hc_asprintf (&tmp_line_buf, "%s", line_buf); compress_terminal_line_length (tmp_line_buf, 38, 32); event_log_warning (hashcat_ctx, "Hashfile '%s' on line %u (%s): %s", hashes->hashfile, line_num, tmp_line_buf, strparser (parser_status)); hcfree (tmp_line_buf); continue; } hashes_buf[hashes_cnt].hash_info->split->split_group = line_num; hashes_buf[hashes_cnt].hash_info->split->split_origin = SPLIT_ORIGIN_LEFT; hashes_cnt++; parser_status = hashconfig->parse_func ((u8 *) hash_buf + 16, 16, &hashes_buf[hashes_cnt], hashconfig); if (parser_status < PARSER_GLOBAL_ZERO) { char *tmp_line_buf; hc_asprintf (&tmp_line_buf, "%s", line_buf); compress_terminal_line_length (tmp_line_buf, 38, 32); event_log_warning (hashcat_ctx, "Hashfile '%s' on line %u (%s): %s", hashes->hashfile, line_num, tmp_line_buf, strparser (parser_status)); hcfree (tmp_line_buf); continue; } hashes_buf[hashes_cnt].hash_info->split->split_group = line_num; hashes_buf[hashes_cnt].hash_info->split->split_origin = SPLIT_ORIGIN_RIGHT; hashes_cnt++; } else { int parser_status = hashconfig->parse_func ((u8 *) hash_buf, (u32) hash_len, &hashes_buf[hashes_cnt], hashconfig); if (parser_status < PARSER_GLOBAL_ZERO) { char *tmp_line_buf; hc_asprintf (&tmp_line_buf, "%s", line_buf); compress_terminal_line_length (tmp_line_buf, 38, 32); event_log_warning (hashcat_ctx, "Hashfile '%s' on line %u (%s): %s", hashes->hashfile, line_num, tmp_line_buf, strparser (parser_status)); hcfree (tmp_line_buf); continue; } hashes_buf[hashes_cnt].hash_info->split->split_group = line_num; hashes_buf[hashes_cnt].hash_info->split->split_origin = SPLIT_ORIGIN_NONE; hashes_cnt++; } } else { int parser_status = hashconfig->parse_func ((u8 *) hash_buf, (u32) hash_len, &hashes_buf[hashes_cnt], hashconfig); if (parser_status < PARSER_GLOBAL_ZERO) { char *tmp_line_buf; hc_asprintf (&tmp_line_buf, "%s", line_buf); compress_terminal_line_length (tmp_line_buf, 38, 32); event_log_warning (hashcat_ctx, "Hashfile '%s' on line %u (%s): %s", hashes->hashfile, line_num, tmp_line_buf, strparser (parser_status)); hcfree (tmp_line_buf); continue; } hashes_cnt++; } time (&now); if ((now - prev) == 0) continue; time (&prev); hashlist_parse_t hashlist_parse; hashlist_parse.hashes_cnt = hashes_cnt; hashlist_parse.hashes_avail = hashes_avail; EVENT_DATA (EVENT_HASHLIST_PARSE_HASH, &hashlist_parse, sizeof (hashlist_parse_t)); } hashlist_parse_t hashlist_parse; hashlist_parse.hashes_cnt = hashes_cnt; hashlist_parse.hashes_avail = hashes_avail; EVENT_DATA (EVENT_HASHLIST_PARSE_HASH, &hashlist_parse, sizeof (hashlist_parse_t)); hcfree (line_buf); fclose (fp); } } hashes->hashes_cnt = hashes_cnt; if (hashes_cnt) { EVENT (EVENT_HASHLIST_SORT_HASH_PRE); if (hashconfig->is_salted == true) { hc_qsort_r (hashes_buf, hashes_cnt, sizeof (hash_t), sort_by_hash, (void *) hashconfig); } else { hc_qsort_r (hashes_buf, hashes_cnt, sizeof (hash_t), sort_by_hash_no_salt, (void *) hashconfig); } EVENT (EVENT_HASHLIST_SORT_HASH_POST); } if (hashconfig->hash_mode == 3000) { // update split split_neighbor after sorting // see https://github.com/hashcat/hashcat/issues/1034 for good examples for testing for (u32 i = 0; i < hashes_cnt; i++) { split_t *split1 = hashes_buf[i].hash_info->split; if (split1->split_origin != SPLIT_ORIGIN_LEFT) continue; for (u32 j = 0; j < hashes_cnt; j++) { split_t *split2 = hashes_buf[j].hash_info->split; if (split2->split_origin != SPLIT_ORIGIN_RIGHT) continue; if (split1->split_group != split2->split_group) continue; split1->split_neighbor = j; split2->split_neighbor = i; break; } } } return 0; }
int module_hash_binary_parse (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra, hashes_t *hashes) { // note: if module_hash_binary_parse exists, then module_hash_decode is not called FILE *fp = fopen (hashes->hashfile, "rb"); if (fp == NULL) return (PARSER_HASH_FILE); #define TC_HEADER_SIZE 512 char *in = (char *) hcmalloc (TC_HEADER_SIZE); const size_t n = hc_fread (in, 1, TC_HEADER_SIZE, fp); fclose (fp); if (n != TC_HEADER_SIZE) return (PARSER_TC_FILE_SIZE); hash_t *hashes_buf = hashes->hashes_buf; hash_t *hash = &hashes_buf[0]; const int parser_status = module_hash_decode (hashconfig, hash->digest, hash->salt, hash->esalt, hash->hook_salt, hash->hash_info, in, TC_HEADER_SIZE); if (parser_status != PARSER_OK) return 0; hcfree (in); // keyfiles tc_t *tc = (tc_t *) hash->esalt; if (user_options->truecrypt_keyfiles) { char *keyfiles = hcstrdup (user_options->truecrypt_keyfiles); char *saveptr = NULL; char *keyfile = strtok_r (keyfiles, ",", &saveptr); while (keyfile) { if (hc_path_read (keyfile)) { cpu_crc32 (keyfile, (u8 *) tc->keyfile_buf); } keyfile = strtok_r ((char *) NULL, ",", &saveptr); } free (keyfiles); } // keyboard layout mapping if (user_options->keyboard_layout_mapping) { if (hc_path_read (user_options->keyboard_layout_mapping)) { initialize_keyboard_layout_mapping (user_options->keyboard_layout_mapping, tc->keyboard_layout_mapping_buf, &tc->keyboard_layout_mapping_cnt); } } return 1; }
void dictstat_read (hashcat_ctx_t *hashcat_ctx) { hashconfig_t *hashconfig = hashcat_ctx->hashconfig; dictstat_ctx_t *dictstat_ctx = hashcat_ctx->dictstat_ctx; if (dictstat_ctx->enabled == false) return; if (hashconfig->dictstat_disable == true) return; FILE *fp = fopen (dictstat_ctx->filename, "rb"); if (fp == NULL) { // first run, file does not exist, do not error out return; } // parse header u64 v; u64 z; const size_t nread1 = hc_fread (&v, sizeof (u64), 1, fp); const size_t nread2 = hc_fread (&z, sizeof (u64), 1, fp); if ((nread1 != 1) || (nread2 != 1)) { event_log_error (hashcat_ctx, "%s: Invalid header", dictstat_ctx->filename); fclose (fp); return; } v = byte_swap_64 (v); z = byte_swap_64 (z); if ((v & 0xffffffffffffff00) != (DICTSTAT_VERSION & 0xffffffffffffff00)) { event_log_error (hashcat_ctx, "%s: Invalid header, ignoring content", dictstat_ctx->filename); fclose (fp); return; } if (z != 0) { event_log_error (hashcat_ctx, "%s: Invalid header, ignoring content", dictstat_ctx->filename); fclose (fp); return; } if ((v & 0xff) < (DICTSTAT_VERSION & 0xff)) { event_log_warning (hashcat_ctx, "%s: Outdated header version, ignoring content", dictstat_ctx->filename); fclose (fp); return; } // parse data while (!feof (fp)) { dictstat_t d; const size_t nread = hc_fread (&d, sizeof (dictstat_t), 1, fp); if (nread == 0) continue; lsearch (&d, dictstat_ctx->base, &dictstat_ctx->cnt, sizeof (dictstat_t), sort_by_dictstat); if (dictstat_ctx->cnt == MAX_DICTSTAT) { event_log_error (hashcat_ctx, "There are too many entries in the %s database. You have to remove/rename it.", dictstat_ctx->filename); break; } } fclose (fp); }