int potfile_handle_show (hashcat_ctx_t *hashcat_ctx) { hashconfig_t *hashconfig = hashcat_ctx->hashconfig; hashes_t *hashes = hashcat_ctx->hashes; potfile_ctx_t *potfile_ctx = hashcat_ctx->potfile_ctx; hash_t *hashes_buf = hashes->hashes_buf; u32 salts_cnt = hashes->salts_cnt; salt_t *salts_buf = hashes->salts_buf; if (hashconfig->hash_mode == 3000) { for (u32 salt_idx = 0; salt_idx < salts_cnt; salt_idx++) { salt_t *salt_buf = salts_buf + salt_idx; u32 digests_cnt = salt_buf->digests_cnt; for (u32 digest_idx = 0; digest_idx < digests_cnt; digest_idx++) { const u32 hashes_idx = salt_buf->digests_offset + digest_idx; u32 *digests_shown = hashes->digests_shown; hash_t *hash1 = &hashes_buf[hashes_idx]; hash_t *hash2 = NULL; int split_neighbor = -1; // find out if at least one of the parts has been cracked if (hash1->hash_info->split->split_origin == SPLIT_ORIGIN_LEFT) { split_neighbor = hash1->hash_info->split->split_neighbor; hash2 = &hashes_buf[split_neighbor]; if ((digests_shown[hashes_idx] == 0) && (digests_shown[split_neighbor] == 0)) continue; } else if (hash1->hash_info->split->split_origin == SPLIT_ORIGIN_NONE) { if (digests_shown[hashes_idx] == 0) continue; } else { // SPLIT_ORIGIN_RIGHT are not handled this way continue; } u8 *out_buf = potfile_ctx->out_buf; out_buf[0] = 0; ascii_digest (hashcat_ctx, (char *) out_buf + 0, HCBUFSIZ_LARGE - 0, salt_idx, digest_idx); if (hash2) { ascii_digest (hashcat_ctx, (char *) out_buf + 16, HCBUFSIZ_LARGE - 16, salt_idx, split_neighbor); } // user unsigned char *username = NULL; u32 user_len = 0; user_t *user = hash1->hash_info->user; if (user) { username = (unsigned char *) (user->user_name); user_len = user->user_len; username[user_len] = 0; } u8 *tmp_buf = potfile_ctx->tmp_buf; tmp_buf[0] = 0; u8 mixed_buf[20] = { 0 }; u8 mixed_len = 0; if (digests_shown[hashes_idx] == 1) { memcpy (mixed_buf + mixed_len, hash1->pw_buf, hash1->pw_len); mixed_len += hash1->pw_len; } else { memcpy (mixed_buf + mixed_len, LM_MASKED_PLAIN, strlen (LM_MASKED_PLAIN)); mixed_len += strlen (LM_MASKED_PLAIN); } if (hash2) { if (digests_shown[split_neighbor] == 1) { memcpy (mixed_buf + mixed_len, hash2->pw_buf, hash2->pw_len); mixed_len += hash2->pw_len; } else { memcpy (mixed_buf + mixed_len, LM_MASKED_PLAIN, strlen (LM_MASKED_PLAIN)); mixed_len += strlen (LM_MASKED_PLAIN); } } const int tmp_len = outfile_write (hashcat_ctx, (char *) out_buf, (u8 *) mixed_buf, mixed_len, 0, username, user_len, (char *) tmp_buf); EVENT_DATA (EVENT_POTFILE_HASH_SHOW, tmp_buf, tmp_len); } } } else { for (u32 salt_idx = 0; salt_idx < salts_cnt; salt_idx++) { salt_t *salt_buf = salts_buf + salt_idx; u32 digests_cnt = salt_buf->digests_cnt; for (u32 digest_idx = 0; digest_idx < digests_cnt; digest_idx++) { const u32 hashes_idx = salt_buf->digests_offset + digest_idx; u32 *digests_shown = hashes->digests_shown; if (digests_shown[hashes_idx] == 0) continue; hash_t *hash = &hashes_buf[hashes_idx]; u8 *out_buf = potfile_ctx->out_buf; out_buf[0] = 0; ascii_digest (hashcat_ctx, (char *) out_buf, HCBUFSIZ_LARGE, salt_idx, digest_idx); // user unsigned char *username = NULL; u32 user_len = 0; if (hash->hash_info != NULL) { user_t *user = hash->hash_info->user; if (user) { username = (unsigned char *) (user->user_name); user_len = user->user_len; username[user_len] = 0; } } u8 *tmp_buf = potfile_ctx->tmp_buf; tmp_buf[0] = 0; // special case for collider modes: we do not use the $HEX[] format within the hash itself // therefore we need to convert the $HEX[] password into hexadecimal (without "$HEX[" and "]") bool is_collider_hex_password = false; if ((hashconfig->hash_mode == 9710) || (hashconfig->hash_mode == 9810) || (hashconfig->hash_mode == 10410)) { if (is_hexify ((u8 *) hash->pw_buf, hash->pw_len) == true) { is_collider_hex_password = true; } } int tmp_len = 0; if (is_collider_hex_password == true) { u8 pass_unhexified[HCBUFSIZ_TINY] = { 0 }; u32 pass_unhexified_len = 0; pass_unhexified_len = exec_unhexify ((u8 *) hash->pw_buf, hash->pw_len, pass_unhexified, sizeof (pass_unhexified)); tmp_len = outfile_write (hashcat_ctx, (char *) out_buf, pass_unhexified, pass_unhexified_len, 0, username, user_len, (char *) tmp_buf); } else { tmp_len = outfile_write (hashcat_ctx, (char *) out_buf, (u8 *) hash->pw_buf, hash->pw_len, 0, username, user_len, (char *) tmp_buf); } EVENT_DATA (EVENT_POTFILE_HASH_SHOW, tmp_buf, tmp_len); } } } return 0; }
int potfile_handle_left (hashcat_ctx_t *hashcat_ctx) { hashconfig_t *hashconfig = hashcat_ctx->hashconfig; hashes_t *hashes = hashcat_ctx->hashes; potfile_ctx_t *potfile_ctx = hashcat_ctx->potfile_ctx; hash_t *hashes_buf = hashes->hashes_buf; u32 salts_cnt = hashes->salts_cnt; salt_t *salts_buf = hashes->salts_buf; if (hashconfig->hash_mode == 3000) { for (u32 salt_idx = 0; salt_idx < salts_cnt; salt_idx++) { salt_t *salt_buf = salts_buf + salt_idx; u32 digests_cnt = salt_buf->digests_cnt; for (u32 digest_idx = 0; digest_idx < digests_cnt; digest_idx++) { const u32 hashes_idx = salt_buf->digests_offset + digest_idx; u32 *digests_shown = hashes->digests_shown; hash_t *hash1 = &hashes_buf[hashes_idx]; hash_t *hash2 = NULL; int split_neighbor = -1; // find out if at least one of the parts has been cracked if (hash1->hash_info->split->split_origin == SPLIT_ORIGIN_LEFT) { split_neighbor = hash1->hash_info->split->split_neighbor; hash2 = &hashes_buf[split_neighbor]; if ((digests_shown[hashes_idx] == 1) && (digests_shown[split_neighbor] == 1)) continue; } else if (hash1->hash_info->split->split_origin == SPLIT_ORIGIN_NONE) { if (digests_shown[hashes_idx] == 1) continue; } else { // SPLIT_ORIGIN_RIGHT are not handled this way continue; } u8 *out_buf = potfile_ctx->out_buf; out_buf[0] = 0; ascii_digest (hashcat_ctx, (char *) out_buf + 0, HCBUFSIZ_LARGE - 0, salt_idx, digest_idx); if (hash2) { ascii_digest (hashcat_ctx, (char *) out_buf + 16, HCBUFSIZ_LARGE - 16, salt_idx, split_neighbor); } // user unsigned char *username = NULL; u32 user_len = 0; user_t *user = hash1->hash_info->user; if (user) { username = (unsigned char *) (user->user_name); user_len = user->user_len; username[user_len] = 0; } u8 *tmp_buf = potfile_ctx->tmp_buf; tmp_buf[0] = 0; const int tmp_len = outfile_write (hashcat_ctx, (char *) out_buf, NULL, 0, 0, username, user_len, (char *) tmp_buf); EVENT_DATA (EVENT_POTFILE_HASH_LEFT, tmp_buf, tmp_len); } } } else { for (u32 salt_idx = 0; salt_idx < salts_cnt; salt_idx++) { salt_t *salt_buf = salts_buf + salt_idx; u32 digests_cnt = salt_buf->digests_cnt; for (u32 digest_idx = 0; digest_idx < digests_cnt; digest_idx++) { const u32 hashes_idx = salt_buf->digests_offset + digest_idx; u32 *digests_shown = hashes->digests_shown; if (digests_shown[hashes_idx] == 1) continue; u8 *out_buf = potfile_ctx->out_buf; out_buf[0] = 0; ascii_digest (hashcat_ctx, (char *) out_buf, HCBUFSIZ_LARGE, salt_idx, digest_idx); hash_t *hash = &hashes_buf[hashes_idx]; // user unsigned char *username = NULL; u32 user_len = 0; if (hash->hash_info != NULL) { user_t *user = hash->hash_info->user; if (user) { username = (unsigned char *) (user->user_name); user_len = user->user_len; username[user_len] = 0; } } u8 *tmp_buf = potfile_ctx->tmp_buf; tmp_buf[0] = 0; const int tmp_len = outfile_write (hashcat_ctx, (char *) out_buf, NULL, 0, 0, username, user_len, (char *) tmp_buf); EVENT_DATA (EVENT_POTFILE_HASH_LEFT, tmp_buf, tmp_len); } } } return 0; }
void check_hash (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, plain_t *plain) { debugfile_ctx_t *debugfile_ctx = hashcat_ctx->debugfile_ctx; loopback_ctx_t *loopback_ctx = hashcat_ctx->loopback_ctx; hashes_t *hashes = hashcat_ctx->hashes; const u32 salt_pos = plain->salt_pos; const u32 digest_pos = plain->digest_pos; // relative // hash u8 *out_buf = hashes->out_buf; out_buf[0] = 0; ascii_digest (hashcat_ctx, (char *) out_buf, HCBUFSIZ_LARGE, salt_pos, digest_pos); // plain u32 plain_buf[64] = { 0 }; u8 *plain_ptr = (u8 *) plain_buf; int plain_len = 0; build_plain (hashcat_ctx, device_param, plain, plain_buf, &plain_len); // crackpos u64 crackpos = 0; build_crackpos (hashcat_ctx, device_param, plain, &crackpos); // debug u8 debug_rule_buf[RP_PASSWORD_SIZE] = { 0 }; int debug_rule_len = 0; // -1 error u8 debug_plain_ptr[RP_PASSWORD_SIZE] = { 0 }; int debug_plain_len = 0; build_debugdata (hashcat_ctx, device_param, plain, debug_rule_buf, &debug_rule_len, debug_plain_ptr, &debug_plain_len); // no need for locking, we're in a mutex protected function potfile_write_append (hashcat_ctx, (char *) out_buf, plain_ptr, plain_len); // outfile, can be either to file or stdout // if an error occurs opening the file, send to stdout as fallback // the fp gets opened for each cracked hash so that the user can modify (move) the outfile while hashcat runs outfile_write_open (hashcat_ctx); u8 *tmp_buf = hashes->tmp_buf; tmp_buf[0] = 0; const int tmp_len = outfile_write (hashcat_ctx, (char *) out_buf, plain_ptr, plain_len, crackpos, NULL, 0, (char *) tmp_buf); outfile_write_close (hashcat_ctx); EVENT_DATA (EVENT_CRACKER_HASH_CRACKED, tmp_buf, tmp_len); // if enabled, update also the loopback file if (loopback_ctx->fp != NULL) { loopback_write_append (hashcat_ctx, plain_ptr, plain_len); } // if enabled, update also the (rule) debug file if (debugfile_ctx->fp != NULL) { // the next check implies that: // - (user_options->attack_mode == ATTACK_MODE_STRAIGHT) // - debug_mode > 0 if ((debug_plain_len > 0) || (debug_rule_len > 0)) { debugfile_write_append (hashcat_ctx, debug_rule_buf, debug_rule_len, plain_ptr, plain_len, debug_plain_ptr, debug_plain_len); } } }