2016-09-09 21:17:43 +00:00
|
|
|
/**
|
2016-09-11 20:20:15 +00:00
|
|
|
* Author......: See docs/credits.txt
|
2016-09-09 21:17:43 +00:00
|
|
|
* License.....: MIT
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "common.h"
|
|
|
|
#include "types.h"
|
2016-09-10 10:16:16 +00:00
|
|
|
#include "convert.h"
|
2016-09-09 21:17:43 +00:00
|
|
|
#include "memory.h"
|
2016-10-09 20:41:55 +00:00
|
|
|
#include "event.h"
|
2016-09-10 09:32:26 +00:00
|
|
|
#include "interface.h"
|
|
|
|
#include "filehandling.h"
|
2017-01-03 18:21:27 +00:00
|
|
|
#include "loopback.h"
|
2016-09-10 15:35:58 +00:00
|
|
|
#include "outfile.h"
|
2016-09-09 21:17:43 +00:00
|
|
|
#include "potfile.h"
|
2016-11-05 10:33:29 +00:00
|
|
|
#include "locking.h"
|
2016-11-16 09:22:57 +00:00
|
|
|
#include "shared.h"
|
2016-10-01 08:47:03 +00:00
|
|
|
|
2016-09-10 09:32:26 +00:00
|
|
|
// get rid of this later
|
2016-09-30 20:52:44 +00:00
|
|
|
int sort_by_hash (const void *v1, const void *v2, void *v3);
|
|
|
|
int sort_by_hash_no_salt (const void *v1, const void *v2, void *v3);
|
2016-09-10 09:32:26 +00:00
|
|
|
// get rid of this later
|
2016-09-09 21:17:43 +00:00
|
|
|
|
2016-09-10 10:16:16 +00:00
|
|
|
int sort_by_hash_t_salt (const void *v1, const void *v2)
|
|
|
|
{
|
|
|
|
const hash_t *h1 = (const hash_t *) v1;
|
|
|
|
const hash_t *h2 = (const hash_t *) v2;
|
|
|
|
|
|
|
|
const salt_t *s1 = h1->salt;
|
|
|
|
const salt_t *s2 = h2->salt;
|
|
|
|
|
|
|
|
// testphase: this should work
|
2016-10-04 04:35:49 +00:00
|
|
|
u32 n = 16;
|
2016-09-10 10:16:16 +00:00
|
|
|
|
|
|
|
while (n--)
|
|
|
|
{
|
|
|
|
if (s1->salt_buf[n] > s2->salt_buf[n]) return ( 1);
|
|
|
|
if (s1->salt_buf[n] < s2->salt_buf[n]) return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* original code, seems buggy since salt_len can be very big (had a case with 131 len)
|
2016-10-04 04:35:49 +00:00
|
|
|
also it thinks salt_buf[x] is a char but its a u32 so salt_len should be / 4
|
2016-09-10 10:16:16 +00:00
|
|
|
if (s1->salt_len > s2->salt_len) return ( 1);
|
|
|
|
if (s1->salt_len < s2->salt_len) return -1;
|
|
|
|
|
2016-10-04 04:35:49 +00:00
|
|
|
u32 n = s1->salt_len;
|
2016-09-10 10:16:16 +00:00
|
|
|
|
|
|
|
while (n--)
|
|
|
|
{
|
|
|
|
if (s1->salt_buf[n] > s2->salt_buf[n]) return ( 1);
|
|
|
|
if (s1->salt_buf[n] < s2->salt_buf[n]) return -1;
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int sort_by_hash_t_salt_hccap (const void *v1, const void *v2)
|
|
|
|
{
|
|
|
|
const hash_t *h1 = (const hash_t *) v1;
|
|
|
|
const hash_t *h2 = (const hash_t *) v2;
|
|
|
|
|
|
|
|
const salt_t *s1 = h1->salt;
|
|
|
|
const salt_t *s2 = h2->salt;
|
|
|
|
|
|
|
|
// last 2: salt_buf[10] and salt_buf[11] contain the digest (skip them)
|
|
|
|
|
2016-10-04 04:35:49 +00:00
|
|
|
u32 n = 9; // 9 * 4 = 36 bytes (max length of ESSID)
|
2016-09-10 10:16:16 +00:00
|
|
|
|
|
|
|
while (n--)
|
|
|
|
{
|
|
|
|
if (s1->salt_buf[n] > s2->salt_buf[n]) return ( 1);
|
|
|
|
if (s1->salt_buf[n] < s2->salt_buf[n]) return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-10-06 15:26:15 +00:00
|
|
|
int potfile_init (hashcat_ctx_t *hashcat_ctx)
|
2016-10-06 13:40:27 +00:00
|
|
|
{
|
|
|
|
folder_config_t *folder_config = hashcat_ctx->folder_config;
|
|
|
|
potfile_ctx_t *potfile_ctx = hashcat_ctx->potfile_ctx;
|
|
|
|
user_options_t *user_options = hashcat_ctx->user_options;
|
|
|
|
|
|
|
|
potfile_ctx->enabled = false;
|
|
|
|
|
2016-10-06 15:26:15 +00:00
|
|
|
if (user_options->benchmark == true) return 0;
|
|
|
|
if (user_options->keyspace == true) return 0;
|
|
|
|
if (user_options->opencl_info == true) return 0;
|
|
|
|
if (user_options->stdout_flag == true) return 0;
|
2016-10-14 19:38:52 +00:00
|
|
|
if (user_options->speed_only == true) return 0;
|
2016-12-09 22:44:43 +00:00
|
|
|
if (user_options->progress_only == true) return 0;
|
2016-10-06 15:26:15 +00:00
|
|
|
if (user_options->usage == true) return 0;
|
|
|
|
if (user_options->version == true) return 0;
|
|
|
|
if (user_options->potfile_disable == true) return 0;
|
2016-10-06 13:40:27 +00:00
|
|
|
|
|
|
|
potfile_ctx->enabled = true;
|
|
|
|
|
|
|
|
if (user_options->potfile_path == NULL)
|
|
|
|
{
|
|
|
|
potfile_ctx->fp = NULL;
|
|
|
|
|
2016-12-23 23:40:40 +00:00
|
|
|
hc_asprintf (&potfile_ctx->filename, "%s/hashcat.potfile", folder_config->profile_dir);
|
2016-10-06 13:40:27 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-11-20 21:54:52 +00:00
|
|
|
potfile_ctx->filename = hcstrdup (user_options->potfile_path);
|
2016-10-06 13:40:27 +00:00
|
|
|
potfile_ctx->fp = NULL;
|
|
|
|
}
|
|
|
|
|
2016-10-06 15:26:15 +00:00
|
|
|
const int rc = potfile_write_open (hashcat_ctx);
|
|
|
|
|
|
|
|
if (rc == -1) return -1;
|
|
|
|
|
|
|
|
potfile_write_close (hashcat_ctx);
|
|
|
|
|
2016-10-30 21:47:48 +00:00
|
|
|
// starting from here, we should allocate some scratch buffer for later use
|
|
|
|
|
2016-11-20 21:54:52 +00:00
|
|
|
u8 *out_buf = (u8 *) hcmalloc (HCBUFSIZ_LARGE);
|
2016-10-30 21:47:48 +00:00
|
|
|
|
|
|
|
potfile_ctx->out_buf = out_buf;
|
|
|
|
|
|
|
|
// we need two buffers in parallel
|
|
|
|
|
2016-11-20 21:54:52 +00:00
|
|
|
u8 *tmp_buf = (u8 *) hcmalloc (HCBUFSIZ_LARGE);
|
2016-10-30 21:47:48 +00:00
|
|
|
|
|
|
|
potfile_ctx->tmp_buf = tmp_buf;
|
|
|
|
|
2016-12-31 12:52:35 +00:00
|
|
|
// old potfile detection
|
|
|
|
|
|
|
|
if (user_options->potfile_path == NULL)
|
|
|
|
{
|
|
|
|
char *potfile_old;
|
|
|
|
|
|
|
|
hc_asprintf (&potfile_old, "%s/hashcat.pot", folder_config->profile_dir);
|
|
|
|
|
|
|
|
hc_stat_t st;
|
|
|
|
|
|
|
|
if (hc_stat (potfile_old, &st) == 0)
|
|
|
|
{
|
|
|
|
event_log_warning (hashcat_ctx, "Old potfile detected: %s", potfile_old);
|
|
|
|
event_log_warning (hashcat_ctx, "New potfile is: %s ", potfile_ctx->filename);
|
|
|
|
event_log_warning (hashcat_ctx, "");
|
|
|
|
}
|
|
|
|
|
|
|
|
hcfree (potfile_old);
|
|
|
|
}
|
|
|
|
|
2016-10-06 15:26:15 +00:00
|
|
|
return 0;
|
2016-10-06 13:40:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void potfile_destroy (hashcat_ctx_t *hashcat_ctx)
|
2016-09-10 13:17:23 +00:00
|
|
|
{
|
2016-10-06 13:40:27 +00:00
|
|
|
potfile_ctx_t *potfile_ctx = hashcat_ctx->potfile_ctx;
|
|
|
|
|
|
|
|
if (potfile_ctx->enabled == false) return;
|
|
|
|
|
2016-10-30 21:47:48 +00:00
|
|
|
hcfree (potfile_ctx->out_buf);
|
|
|
|
hcfree (potfile_ctx->tmp_buf);
|
|
|
|
|
2016-10-06 13:40:27 +00:00
|
|
|
memset (potfile_ctx, 0, sizeof (potfile_ctx_t));
|
|
|
|
}
|
|
|
|
|
|
|
|
int potfile_read_open (hashcat_ctx_t *hashcat_ctx)
|
|
|
|
{
|
|
|
|
potfile_ctx_t *potfile_ctx = hashcat_ctx->potfile_ctx;
|
|
|
|
|
2016-09-30 10:37:29 +00:00
|
|
|
if (potfile_ctx->enabled == false) return 0;
|
2016-09-14 17:46:31 +00:00
|
|
|
|
2016-09-10 13:17:23 +00:00
|
|
|
potfile_ctx->fp = fopen (potfile_ctx->filename, "rb");
|
|
|
|
|
|
|
|
if (potfile_ctx->fp == NULL)
|
|
|
|
{
|
2016-12-03 05:26:10 +00:00
|
|
|
event_log_error (hashcat_ctx, "%s: %m", potfile_ctx->filename);
|
2016-09-10 13:17:23 +00:00
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-10-18 18:42:34 +00:00
|
|
|
void potfile_read_close (hashcat_ctx_t *hashcat_ctx)
|
|
|
|
{
|
|
|
|
potfile_ctx_t *potfile_ctx = hashcat_ctx->potfile_ctx;
|
|
|
|
|
|
|
|
if (potfile_ctx->enabled == false) return;
|
|
|
|
|
|
|
|
if (potfile_ctx->fp == NULL) return;
|
|
|
|
|
|
|
|
fclose (potfile_ctx->fp);
|
|
|
|
}
|
|
|
|
|
2016-10-06 13:40:27 +00:00
|
|
|
int potfile_write_open (hashcat_ctx_t *hashcat_ctx)
|
2016-09-10 13:17:23 +00:00
|
|
|
{
|
2016-10-06 13:40:27 +00:00
|
|
|
potfile_ctx_t *potfile_ctx = hashcat_ctx->potfile_ctx;
|
|
|
|
|
2016-09-30 10:37:29 +00:00
|
|
|
if (potfile_ctx->enabled == false) return 0;
|
2016-09-14 17:46:31 +00:00
|
|
|
|
2016-11-20 22:15:54 +00:00
|
|
|
FILE *fp = fopen (potfile_ctx->filename, "ab");
|
2016-09-10 13:17:23 +00:00
|
|
|
|
2016-11-20 22:15:54 +00:00
|
|
|
if (fp == NULL)
|
2016-09-10 13:17:23 +00:00
|
|
|
{
|
2016-12-03 05:26:10 +00:00
|
|
|
event_log_error (hashcat_ctx, "%s: %m", potfile_ctx->filename);
|
2016-09-10 13:17:23 +00:00
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2016-11-20 22:15:54 +00:00
|
|
|
potfile_ctx->fp = fp;
|
|
|
|
|
2016-09-10 13:17:23 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-10-06 13:40:27 +00:00
|
|
|
void potfile_write_close (hashcat_ctx_t *hashcat_ctx)
|
2016-09-10 13:17:23 +00:00
|
|
|
{
|
2016-10-06 13:40:27 +00:00
|
|
|
potfile_ctx_t *potfile_ctx = hashcat_ctx->potfile_ctx;
|
|
|
|
|
2016-09-30 10:37:29 +00:00
|
|
|
if (potfile_ctx->enabled == false) return;
|
2016-09-14 17:46:31 +00:00
|
|
|
|
2016-09-10 13:17:23 +00:00
|
|
|
fclose (potfile_ctx->fp);
|
|
|
|
}
|
|
|
|
|
2016-10-06 13:40:27 +00:00
|
|
|
void potfile_write_append (hashcat_ctx_t *hashcat_ctx, const char *out_buf, u8 *plain_ptr, unsigned int plain_len)
|
2016-09-10 13:17:23 +00:00
|
|
|
{
|
2016-11-05 13:46:00 +00:00
|
|
|
const hashconfig_t *hashconfig = hashcat_ctx->hashconfig;
|
2016-11-04 21:12:25 +00:00
|
|
|
const potfile_ctx_t *potfile_ctx = hashcat_ctx->potfile_ctx;
|
|
|
|
const user_options_t *user_options = hashcat_ctx->user_options;
|
2016-10-06 13:40:27 +00:00
|
|
|
|
2016-09-30 10:37:29 +00:00
|
|
|
if (potfile_ctx->enabled == false) return;
|
2016-09-14 17:46:31 +00:00
|
|
|
|
2016-10-30 21:47:48 +00:00
|
|
|
u8 *tmp_buf = potfile_ctx->tmp_buf;
|
2016-10-12 12:38:33 +00:00
|
|
|
|
|
|
|
int tmp_len = 0;
|
|
|
|
|
|
|
|
if (1)
|
|
|
|
{
|
|
|
|
const size_t out_len = strlen (out_buf);
|
|
|
|
|
|
|
|
memcpy (tmp_buf + tmp_len, out_buf, out_len);
|
|
|
|
|
|
|
|
tmp_len += out_len;
|
|
|
|
|
2016-12-09 13:54:13 +00:00
|
|
|
tmp_buf[tmp_len] = hashconfig->separator;
|
2016-10-12 12:38:33 +00:00
|
|
|
|
|
|
|
tmp_len += 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (1)
|
|
|
|
{
|
2016-11-19 14:08:22 +00:00
|
|
|
const bool always_ascii = (hashconfig->hash_type & OPTS_TYPE_PT_ALWAYS_ASCII) ? true : false;
|
2016-11-05 12:27:08 +00:00
|
|
|
|
2016-12-09 13:54:13 +00:00
|
|
|
if ((user_options->outfile_autohex == true) && (need_hexify (plain_ptr, plain_len, hashconfig->separator, always_ascii) == true))
|
2016-10-12 12:38:33 +00:00
|
|
|
{
|
|
|
|
tmp_buf[tmp_len++] = '$';
|
|
|
|
tmp_buf[tmp_len++] = 'H';
|
|
|
|
tmp_buf[tmp_len++] = 'E';
|
|
|
|
tmp_buf[tmp_len++] = 'X';
|
|
|
|
tmp_buf[tmp_len++] = '[';
|
|
|
|
|
|
|
|
exec_hexify ((const u8 *) plain_ptr, plain_len, (u8 *) tmp_buf + tmp_len);
|
|
|
|
|
|
|
|
tmp_len += plain_len * 2;
|
2016-09-10 13:17:23 +00:00
|
|
|
|
2016-10-12 12:38:33 +00:00
|
|
|
tmp_buf[tmp_len++] = ']';
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
memcpy (tmp_buf + tmp_len, plain_ptr, plain_len);
|
|
|
|
|
|
|
|
tmp_len += plain_len;
|
|
|
|
}
|
|
|
|
}
|
2016-09-10 13:17:23 +00:00
|
|
|
|
2016-10-12 12:38:33 +00:00
|
|
|
tmp_buf[tmp_len] = 0;
|
2016-09-10 13:17:23 +00:00
|
|
|
|
2016-12-02 10:18:55 +00:00
|
|
|
lock_file (potfile_ctx->fp);
|
|
|
|
|
2016-10-25 10:40:47 +00:00
|
|
|
fprintf (potfile_ctx->fp, "%s" EOL, tmp_buf);
|
2016-11-05 10:33:29 +00:00
|
|
|
|
2016-11-19 14:13:54 +00:00
|
|
|
fflush (potfile_ctx->fp);
|
2016-12-02 10:18:55 +00:00
|
|
|
|
|
|
|
unlock_file (potfile_ctx->fp);
|
2016-09-10 13:17:23 +00:00
|
|
|
}
|
|
|
|
|
2016-10-13 08:07:04 +00:00
|
|
|
int potfile_remove_parse (hashcat_ctx_t *hashcat_ctx)
|
2016-09-10 10:16:16 +00:00
|
|
|
{
|
2017-01-03 18:21:27 +00:00
|
|
|
const hashconfig_t *hashconfig = hashcat_ctx->hashconfig;
|
|
|
|
const hashes_t *hashes = hashcat_ctx->hashes;
|
|
|
|
const loopback_ctx_t *loopback_ctx = hashcat_ctx->loopback_ctx;
|
|
|
|
const potfile_ctx_t *potfile_ctx = hashcat_ctx->potfile_ctx;
|
2016-10-06 13:40:27 +00:00
|
|
|
|
2016-10-13 08:07:04 +00:00
|
|
|
if (potfile_ctx->enabled == false) return 0;
|
2016-09-14 17:46:31 +00:00
|
|
|
|
2016-09-16 15:01:18 +00:00
|
|
|
hash_t *hashes_buf = hashes->hashes_buf;
|
2016-10-07 19:47:11 +00:00
|
|
|
u32 hashes_cnt = hashes->hashes_cnt;
|
2016-09-16 15:01:18 +00:00
|
|
|
|
2016-09-10 10:16:16 +00:00
|
|
|
// no solution for these special hash types (for instane because they use hashfile in output etc)
|
|
|
|
|
2016-10-13 08:07:04 +00:00
|
|
|
if (hashconfig->hash_mode == 5200) return 0;
|
2016-10-07 19:47:11 +00:00
|
|
|
if ((hashconfig->hash_mode >= 6200)
|
2016-10-13 08:07:04 +00:00
|
|
|
&& (hashconfig->hash_mode <= 6299)) return 0;
|
|
|
|
if (hashconfig->hash_mode == 9000) return 0;
|
2016-10-07 19:47:11 +00:00
|
|
|
if ((hashconfig->hash_mode >= 13700)
|
2016-10-13 08:07:04 +00:00
|
|
|
&& (hashconfig->hash_mode <= 13799)) return 0;
|
2016-09-10 10:16:16 +00:00
|
|
|
|
|
|
|
hash_t hash_buf;
|
|
|
|
|
2016-11-20 21:54:52 +00:00
|
|
|
hash_buf.digest = hcmalloc (hashconfig->dgst_size);
|
2016-09-10 10:16:16 +00:00
|
|
|
hash_buf.salt = NULL;
|
|
|
|
hash_buf.esalt = NULL;
|
|
|
|
hash_buf.hash_info = NULL;
|
|
|
|
hash_buf.cracked = 0;
|
|
|
|
|
|
|
|
if (hashconfig->is_salted)
|
|
|
|
{
|
2016-11-20 21:54:52 +00:00
|
|
|
hash_buf.salt = (salt_t *) hcmalloc (sizeof (salt_t));
|
2016-09-10 10:16:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (hashconfig->esalt_size)
|
|
|
|
{
|
2016-11-20 21:54:52 +00:00
|
|
|
hash_buf.esalt = hcmalloc (hashconfig->esalt_size);
|
2016-09-10 10:16:16 +00:00
|
|
|
}
|
|
|
|
|
2016-11-29 19:37:29 +00:00
|
|
|
// this is usually detected by weak-hash-check
|
|
|
|
// but not if bitslice
|
|
|
|
|
|
|
|
if (hashconfig->hash_mode == 3000)
|
|
|
|
{
|
|
|
|
int parser_status = hashconfig->parse_func ((u8 *) LM_WEAK_HASH, 16, &hash_buf, hashconfig);
|
|
|
|
|
|
|
|
if (parser_status == PARSER_OK)
|
|
|
|
{
|
|
|
|
hash_t *found = (hash_t *) hc_bsearch_r (&hash_buf, hashes_buf, hashes_cnt, sizeof (hash_t), sort_by_hash_no_salt, (void *) hashconfig);
|
|
|
|
|
|
|
|
if (found)
|
|
|
|
{
|
|
|
|
found->pw_buf = "";
|
|
|
|
found->pw_len = 0;
|
|
|
|
|
|
|
|
found->cracked = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-06 13:40:27 +00:00
|
|
|
const int rc = potfile_read_open (hashcat_ctx);
|
2016-09-10 10:16:16 +00:00
|
|
|
|
2016-10-13 08:07:04 +00:00
|
|
|
if (rc == -1) return -1;
|
2016-09-10 10:16:16 +00:00
|
|
|
|
2016-11-20 21:54:52 +00:00
|
|
|
char *line_buf = (char *) hcmalloc (HCBUFSIZ_LARGE);
|
2016-09-10 10:16:16 +00:00
|
|
|
|
|
|
|
while (!feof (potfile_ctx->fp))
|
|
|
|
{
|
2016-10-19 09:55:43 +00:00
|
|
|
int line_len = fgetl (potfile_ctx->fp, line_buf);
|
2016-09-10 10:16:16 +00:00
|
|
|
|
|
|
|
if (line_len == 0) continue;
|
|
|
|
|
2016-12-09 13:54:13 +00:00
|
|
|
char *last_separator = strrchr (line_buf, hashconfig->separator);
|
2016-10-19 09:55:43 +00:00
|
|
|
|
2016-12-09 13:54:13 +00:00
|
|
|
if (last_separator == NULL) continue; // ??
|
2016-09-10 10:16:16 +00:00
|
|
|
|
2016-12-09 13:54:13 +00:00
|
|
|
char *line_pw_buf = last_separator + 1;
|
2016-09-10 10:16:16 +00:00
|
|
|
|
2016-12-09 13:54:13 +00:00
|
|
|
int line_pw_len = line_buf + line_len - line_pw_buf;
|
2016-11-19 14:25:01 +00:00
|
|
|
|
2016-12-09 13:54:13 +00:00
|
|
|
char *line_hash_buf = line_buf;
|
2016-09-10 10:16:16 +00:00
|
|
|
|
2016-12-09 13:54:13 +00:00
|
|
|
int line_hash_len = last_separator - line_buf;
|
|
|
|
|
|
|
|
line_hash_buf[line_hash_len] = 0;
|
2016-09-10 10:16:16 +00:00
|
|
|
|
2016-12-09 13:54:13 +00:00
|
|
|
if (line_hash_len == 0) continue;
|
2016-09-10 10:16:16 +00:00
|
|
|
|
2017-01-03 08:39:13 +00:00
|
|
|
// we should allow length 0 passwords (detected by weak hash check)
|
|
|
|
//if (line_pw_len == 0) continue;
|
2016-12-09 13:54:13 +00:00
|
|
|
|
|
|
|
if (hashconfig->is_salted)
|
|
|
|
{
|
|
|
|
memset (hash_buf.salt, 0, sizeof (salt_t));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (hashconfig->esalt_size)
|
|
|
|
{
|
|
|
|
memset (hash_buf.esalt, 0, hashconfig->esalt_size);
|
|
|
|
}
|
|
|
|
|
|
|
|
hash_t *found = NULL;
|
|
|
|
|
|
|
|
if (hashconfig->hash_mode == 6800)
|
|
|
|
{
|
|
|
|
if (line_hash_len < 64) // 64 = 16 * u32 in salt_buf[]
|
2016-09-10 10:16:16 +00:00
|
|
|
{
|
2016-12-09 13:54:13 +00:00
|
|
|
// manipulate salt_buf
|
|
|
|
memcpy (hash_buf.salt->salt_buf, line_hash_buf, line_hash_len);
|
2016-09-10 10:16:16 +00:00
|
|
|
|
2016-12-09 13:54:13 +00:00
|
|
|
hash_buf.salt->salt_len = line_hash_len;
|
2016-09-10 10:16:16 +00:00
|
|
|
|
2016-12-09 13:54:13 +00:00
|
|
|
found = (hash_t *) bsearch (&hash_buf, hashes_buf, hashes_cnt, sizeof (hash_t), sort_by_hash_t_salt);
|
2016-09-10 10:16:16 +00:00
|
|
|
}
|
2016-12-09 13:54:13 +00:00
|
|
|
}
|
|
|
|
else if (hashconfig->hash_mode == 2500)
|
|
|
|
{
|
|
|
|
if (line_hash_len < 64) // 64 = 16 * u32 in salt_buf[]
|
2016-09-10 10:16:16 +00:00
|
|
|
{
|
2016-12-09 13:54:13 +00:00
|
|
|
// here we have in line_hash_buf: ESSID:MAC1:MAC2 (without the plain)
|
2016-09-10 10:16:16 +00:00
|
|
|
|
2016-12-09 13:54:13 +00:00
|
|
|
char *mac2_pos = strrchr (line_hash_buf, ':');
|
2016-09-10 10:16:16 +00:00
|
|
|
|
2016-12-09 13:54:13 +00:00
|
|
|
if (mac2_pos == NULL) continue;
|
2016-11-16 15:08:40 +00:00
|
|
|
|
2016-12-09 13:54:13 +00:00
|
|
|
mac2_pos[0] = 0;
|
|
|
|
mac2_pos++;
|
2016-09-10 10:16:16 +00:00
|
|
|
|
2016-12-09 13:54:13 +00:00
|
|
|
if (strlen (mac2_pos) != 12) continue;
|
2016-09-10 10:16:16 +00:00
|
|
|
|
2016-12-09 13:54:13 +00:00
|
|
|
char *mac1_pos = strrchr (line_hash_buf, ':');
|
2016-09-10 10:16:16 +00:00
|
|
|
|
2016-12-09 13:54:13 +00:00
|
|
|
if (mac1_pos == NULL) continue;
|
2016-09-10 10:16:16 +00:00
|
|
|
|
2016-12-09 13:54:13 +00:00
|
|
|
mac1_pos[0] = 0;
|
|
|
|
mac1_pos++;
|
2016-09-10 10:16:16 +00:00
|
|
|
|
2016-12-09 13:54:13 +00:00
|
|
|
if (strlen (mac1_pos) != 12) continue;
|
2016-09-10 10:16:16 +00:00
|
|
|
|
2016-12-09 13:54:13 +00:00
|
|
|
u32 essid_length = mac1_pos - line_hash_buf - 1;
|
2016-09-10 10:16:16 +00:00
|
|
|
|
2016-12-09 13:54:13 +00:00
|
|
|
if (hashconfig->is_salted)
|
|
|
|
{
|
|
|
|
// this should be always true, but we need it to make scan-build happy
|
2016-09-10 10:16:16 +00:00
|
|
|
|
2016-12-09 13:54:13 +00:00
|
|
|
memcpy (hash_buf.salt->salt_buf, line_hash_buf, essid_length);
|
2016-09-10 10:16:16 +00:00
|
|
|
|
2016-12-09 13:54:13 +00:00
|
|
|
hash_buf.salt->salt_len = essid_length;
|
|
|
|
}
|
2016-11-12 14:06:10 +00:00
|
|
|
|
2016-12-09 13:54:13 +00:00
|
|
|
found = (hash_t *) bsearch (&hash_buf, hashes_buf, hashes_cnt, sizeof (hash_t), sort_by_hash_t_salt_hccap);
|
2016-09-10 10:16:16 +00:00
|
|
|
|
2016-12-09 13:54:13 +00:00
|
|
|
if (found)
|
|
|
|
{
|
|
|
|
wpa_t *wpa = (wpa_t *) found->esalt;
|
2016-09-10 10:16:16 +00:00
|
|
|
|
2016-12-09 13:54:13 +00:00
|
|
|
// compare hex string(s) vs binary MAC address(es)
|
2016-09-10 10:16:16 +00:00
|
|
|
|
2016-12-09 13:54:13 +00:00
|
|
|
for (u32 mac_idx = 0, orig_mac_idx = 0; mac_idx < 6; mac_idx += 1, orig_mac_idx += 2)
|
2016-09-10 10:16:16 +00:00
|
|
|
{
|
2016-12-09 13:54:13 +00:00
|
|
|
if (wpa->orig_mac1[mac_idx] != hex_to_u8 ((const u8 *) &mac1_pos[orig_mac_idx]))
|
2016-09-10 10:16:16 +00:00
|
|
|
{
|
2016-12-09 13:54:13 +00:00
|
|
|
found = NULL;
|
2016-09-10 10:16:16 +00:00
|
|
|
|
2016-12-09 13:54:13 +00:00
|
|
|
break;
|
2016-09-10 10:16:16 +00:00
|
|
|
}
|
|
|
|
|
2016-12-09 13:54:13 +00:00
|
|
|
if (wpa->orig_mac2[mac_idx] != hex_to_u8 ((const u8 *) &mac2_pos[orig_mac_idx]))
|
2016-09-10 10:16:16 +00:00
|
|
|
{
|
2016-12-09 13:54:13 +00:00
|
|
|
found = NULL;
|
2016-09-10 10:16:16 +00:00
|
|
|
|
2016-12-09 13:54:13 +00:00
|
|
|
break;
|
2016-09-10 10:16:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-12-09 13:54:13 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
int parser_status = hashconfig->parse_func ((u8 *) line_hash_buf, line_hash_len, &hash_buf, hashconfig);
|
2016-09-10 10:16:16 +00:00
|
|
|
|
2016-12-09 13:54:13 +00:00
|
|
|
if (parser_status == PARSER_OK)
|
|
|
|
{
|
|
|
|
if (hashconfig->is_salted)
|
2016-09-10 10:16:16 +00:00
|
|
|
{
|
2016-12-09 13:54:13 +00:00
|
|
|
found = (hash_t *) hc_bsearch_r (&hash_buf, hashes_buf, hashes_cnt, sizeof (hash_t), sort_by_hash, (void *) hashconfig);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
found = (hash_t *) hc_bsearch_r (&hash_buf, hashes_buf, hashes_cnt, sizeof (hash_t), sort_by_hash_no_salt, (void *) hashconfig);
|
2016-09-10 10:16:16 +00:00
|
|
|
}
|
|
|
|
}
|
2016-12-09 13:54:13 +00:00
|
|
|
}
|
2016-09-10 10:16:16 +00:00
|
|
|
|
2016-12-09 13:54:13 +00:00
|
|
|
if (found == NULL) continue;
|
2016-10-19 09:55:43 +00:00
|
|
|
|
2016-12-09 13:54:13 +00:00
|
|
|
char *pw_buf = line_pw_buf;
|
|
|
|
int pw_len = line_pw_len;
|
2016-10-19 09:55:43 +00:00
|
|
|
|
2016-12-09 13:54:13 +00:00
|
|
|
found->pw_buf = (char *) hcmalloc (pw_len + 1);
|
|
|
|
found->pw_len = pw_len;
|
2016-10-19 09:55:43 +00:00
|
|
|
|
2016-12-09 13:54:13 +00:00
|
|
|
memcpy (found->pw_buf, pw_buf, pw_len);
|
2016-10-19 09:55:43 +00:00
|
|
|
|
2016-12-09 13:54:13 +00:00
|
|
|
found->pw_buf[found->pw_len] = 0;
|
2016-09-10 10:16:16 +00:00
|
|
|
|
2016-12-09 13:54:13 +00:00
|
|
|
found->cracked = 1;
|
2017-01-03 18:21:27 +00:00
|
|
|
|
|
|
|
// if enabled, update also the loopback file
|
|
|
|
|
|
|
|
if (loopback_ctx->fp != NULL)
|
|
|
|
{
|
|
|
|
loopback_write_append (hashcat_ctx, (u8 *) pw_buf, (unsigned int) pw_len);
|
|
|
|
}
|
2016-09-10 10:16:16 +00:00
|
|
|
}
|
|
|
|
|
2016-10-10 09:03:11 +00:00
|
|
|
hcfree (line_buf);
|
2016-09-10 10:16:16 +00:00
|
|
|
|
2016-10-06 13:40:27 +00:00
|
|
|
potfile_read_close (hashcat_ctx);
|
2016-09-10 10:16:16 +00:00
|
|
|
|
|
|
|
if (hashconfig->esalt_size)
|
|
|
|
{
|
2016-10-10 09:03:11 +00:00
|
|
|
hcfree (hash_buf.esalt);
|
2016-09-10 10:16:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (hashconfig->is_salted)
|
|
|
|
{
|
2016-10-10 09:03:11 +00:00
|
|
|
hcfree (hash_buf.salt);
|
2016-09-10 10:16:16 +00:00
|
|
|
}
|
|
|
|
|
2016-10-10 09:03:11 +00:00
|
|
|
hcfree (hash_buf.digest);
|
2016-10-13 08:07:04 +00:00
|
|
|
|
|
|
|
return 0;
|
2016-09-10 10:16:16 +00:00
|
|
|
}
|
2016-10-18 18:42:34 +00:00
|
|
|
|
|
|
|
int potfile_handle_show (hashcat_ctx_t *hashcat_ctx)
|
|
|
|
{
|
2016-10-30 21:47:48 +00:00
|
|
|
hashes_t *hashes = hashcat_ctx->hashes;
|
|
|
|
potfile_ctx_t *potfile_ctx = hashcat_ctx->potfile_ctx;
|
2016-10-19 09:55:43 +00:00
|
|
|
|
2016-10-30 21:47:48 +00:00
|
|
|
hash_t *hashes_buf = hashes->hashes_buf;
|
2016-10-19 09:55:43 +00:00
|
|
|
|
|
|
|
u32 salts_cnt = hashes->salts_cnt;
|
|
|
|
salt_t *salts_buf = hashes->salts_buf;
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
2016-10-30 21:47:48 +00:00
|
|
|
u8 *out_buf = potfile_ctx->out_buf;
|
2016-10-19 09:55:43 +00:00
|
|
|
|
|
|
|
out_buf[0] = 0;
|
|
|
|
|
2016-11-19 15:10:01 +00:00
|
|
|
ascii_digest (hashcat_ctx, (char *) out_buf, HCBUFSIZ_LARGE, salt_idx, digest_idx);
|
2016-10-19 09:55:43 +00:00
|
|
|
|
2016-10-19 10:42:41 +00:00
|
|
|
hash_t *hash = &hashes_buf[hashes_idx];
|
2016-10-19 09:55:43 +00:00
|
|
|
|
2016-10-19 10:42:41 +00:00
|
|
|
// 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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-30 21:47:48 +00:00
|
|
|
u8 *tmp_buf = potfile_ctx->tmp_buf;
|
|
|
|
|
|
|
|
tmp_buf[0] = 0;
|
|
|
|
|
2016-10-30 21:22:26 +00:00
|
|
|
const int tmp_len = outfile_write (hashcat_ctx, (char *) out_buf, (u8 *) hash->pw_buf, hash->pw_len, 0, username, user_len, (char *) tmp_buf);
|
2016-10-19 10:42:41 +00:00
|
|
|
|
|
|
|
EVENT_DATA (EVENT_POTFILE_HASH_SHOW, tmp_buf, tmp_len);
|
2016-10-19 09:55:43 +00:00
|
|
|
}
|
|
|
|
}
|
2016-10-18 18:42:34 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int potfile_handle_left (hashcat_ctx_t *hashcat_ctx)
|
|
|
|
{
|
2016-10-30 21:47:48 +00:00
|
|
|
hashes_t *hashes = hashcat_ctx->hashes;
|
|
|
|
potfile_ctx_t *potfile_ctx = hashcat_ctx->potfile_ctx;
|
2016-10-18 18:42:34 +00:00
|
|
|
|
2016-10-19 10:42:41 +00:00
|
|
|
hash_t *hashes_buf = hashes->hashes_buf;
|
|
|
|
|
2016-10-18 19:03:16 +00:00
|
|
|
u32 salts_cnt = hashes->salts_cnt;
|
|
|
|
salt_t *salts_buf = hashes->salts_buf;
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
2016-10-30 21:47:48 +00:00
|
|
|
u8 *out_buf = potfile_ctx->out_buf;
|
2016-10-18 19:03:16 +00:00
|
|
|
|
|
|
|
out_buf[0] = 0;
|
|
|
|
|
2016-11-19 15:10:01 +00:00
|
|
|
ascii_digest (hashcat_ctx, (char *) out_buf, HCBUFSIZ_LARGE, salt_idx, digest_idx);
|
2016-10-18 19:03:16 +00:00
|
|
|
|
2016-10-19 10:42:41 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-30 21:47:48 +00:00
|
|
|
u8 *tmp_buf = potfile_ctx->tmp_buf;
|
|
|
|
|
|
|
|
tmp_buf[0] = 0;
|
2016-10-18 19:03:16 +00:00
|
|
|
|
2016-10-30 21:22:26 +00:00
|
|
|
const int tmp_len = outfile_write (hashcat_ctx, (char *) out_buf, NULL, 0, 0, username, user_len, (char *) tmp_buf);
|
2016-10-18 19:03:16 +00:00
|
|
|
|
2016-10-19 10:42:41 +00:00
|
|
|
EVENT_DATA (EVENT_POTFILE_HASH_LEFT, tmp_buf, tmp_len);
|
2016-10-18 19:03:16 +00:00
|
|
|
}
|
|
|
|
}
|
2016-10-18 18:42:34 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|