2016-09-08 14:32:24 +00:00
|
|
|
/**
|
2016-09-11 20:20:15 +00:00
|
|
|
* Author......: See docs/credits.txt
|
2016-09-08 14:32:24 +00:00
|
|
|
* License.....: MIT
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "common.h"
|
|
|
|
#include "types.h"
|
2016-09-14 14:07:24 +00:00
|
|
|
#include "interface.h"
|
2016-09-08 14:32:24 +00:00
|
|
|
#include "timer.h"
|
|
|
|
#include "memory.h"
|
|
|
|
#include "convert.h"
|
|
|
|
#include "logging.h"
|
|
|
|
#include "logfile.h"
|
|
|
|
#include "ext_OpenCL.h"
|
|
|
|
#include "ext_ADL.h"
|
|
|
|
#include "ext_nvapi.h"
|
|
|
|
#include "ext_nvml.h"
|
|
|
|
#include "ext_xnvctrl.h"
|
2016-09-15 14:02:52 +00:00
|
|
|
#include "tuningdb.h"
|
2016-09-20 11:18:47 +00:00
|
|
|
#include "thread.h"
|
2016-09-08 14:32:24 +00:00
|
|
|
#include "opencl.h"
|
2016-09-15 14:02:52 +00:00
|
|
|
#include "hwmon.h"
|
|
|
|
#include "restore.h"
|
2016-09-16 15:01:18 +00:00
|
|
|
#include "hash_management.h"
|
2016-09-08 14:32:24 +00:00
|
|
|
#include "locking.h"
|
|
|
|
#include "rp_cpu.h"
|
|
|
|
#include "rp_kernel_on_cpu.h"
|
|
|
|
#include "shared.h"
|
2016-09-12 10:59:40 +00:00
|
|
|
#include "dictstat.h"
|
2016-09-08 14:32:24 +00:00
|
|
|
#include "mpsp.h"
|
2016-09-10 15:35:58 +00:00
|
|
|
#include "outfile.h"
|
2016-09-09 21:17:43 +00:00
|
|
|
#include "potfile.h"
|
2016-09-13 08:38:59 +00:00
|
|
|
#include "debugfile.h"
|
2016-09-12 12:58:25 +00:00
|
|
|
#include "loopback.h"
|
2016-09-08 14:32:24 +00:00
|
|
|
#include "data.h"
|
|
|
|
#include "wordlist.h"
|
|
|
|
|
|
|
|
extern hc_global_data_t data;
|
|
|
|
|
2016-09-22 13:14:55 +00:00
|
|
|
uint convert_from_hex (char *line_buf, const uint line_len, const user_options_t *user_options)
|
2016-09-08 14:32:24 +00:00
|
|
|
{
|
|
|
|
if (line_len & 1) return (line_len); // not in hex
|
|
|
|
|
2016-09-22 13:14:55 +00:00
|
|
|
if (user_options->hex_wordlist == true)
|
2016-09-08 14:32:24 +00:00
|
|
|
{
|
|
|
|
uint i;
|
|
|
|
uint j;
|
|
|
|
|
|
|
|
for (i = 0, j = 0; j < line_len; i += 1, j += 2)
|
|
|
|
{
|
|
|
|
line_buf[i] = hex_to_u8 ((const u8 *) &line_buf[j]);
|
|
|
|
}
|
|
|
|
|
|
|
|
memset (line_buf + i, 0, line_len - i);
|
|
|
|
|
|
|
|
return (i);
|
|
|
|
}
|
|
|
|
else if (line_len >= 6) // $HEX[] = 6
|
|
|
|
{
|
|
|
|
if (line_buf[0] != '$') return (line_len);
|
|
|
|
if (line_buf[1] != 'H') return (line_len);
|
|
|
|
if (line_buf[2] != 'E') return (line_len);
|
|
|
|
if (line_buf[3] != 'X') return (line_len);
|
|
|
|
if (line_buf[4] != '[') return (line_len);
|
|
|
|
if (line_buf[line_len - 1] != ']') return (line_len);
|
|
|
|
|
|
|
|
uint i;
|
|
|
|
uint j;
|
|
|
|
|
|
|
|
for (i = 0, j = 5; j < line_len - 1; i += 1, j += 2)
|
|
|
|
{
|
|
|
|
line_buf[i] = hex_to_u8 ((const u8 *) &line_buf[j]);
|
|
|
|
}
|
|
|
|
|
|
|
|
memset (line_buf + i, 0, line_len - i);
|
|
|
|
|
|
|
|
return (i);
|
|
|
|
}
|
|
|
|
|
|
|
|
return (line_len);
|
|
|
|
}
|
|
|
|
|
|
|
|
void load_segment (wl_data_t *wl_data, FILE *fd)
|
|
|
|
{
|
|
|
|
// NOTE: use (never changing) ->incr here instead of ->avail otherwise the buffer gets bigger and bigger
|
|
|
|
|
|
|
|
wl_data->pos = 0;
|
|
|
|
|
|
|
|
wl_data->cnt = fread (wl_data->buf, 1, wl_data->incr - 1000, fd);
|
|
|
|
|
|
|
|
wl_data->buf[wl_data->cnt] = 0;
|
|
|
|
|
|
|
|
if (wl_data->cnt == 0) return;
|
|
|
|
|
|
|
|
if (wl_data->buf[wl_data->cnt - 1] == '\n') return;
|
|
|
|
|
|
|
|
while (!feof (fd))
|
|
|
|
{
|
|
|
|
if (wl_data->cnt == wl_data->avail)
|
|
|
|
{
|
|
|
|
wl_data->buf = (char *) myrealloc (wl_data->buf, wl_data->avail, wl_data->incr);
|
|
|
|
|
|
|
|
wl_data->avail += wl_data->incr;
|
|
|
|
}
|
|
|
|
|
|
|
|
const int c = fgetc (fd);
|
|
|
|
|
|
|
|
if (c == EOF) break;
|
|
|
|
|
|
|
|
wl_data->buf[wl_data->cnt] = (char) c;
|
|
|
|
|
|
|
|
wl_data->cnt++;
|
|
|
|
|
|
|
|
if (c == '\n') break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ensure stream ends with a newline
|
|
|
|
|
|
|
|
if (wl_data->buf[wl_data->cnt - 1] != '\n')
|
|
|
|
{
|
|
|
|
wl_data->cnt++;
|
|
|
|
|
|
|
|
wl_data->buf[wl_data->cnt - 1] = '\n';
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
void get_next_word_lm (char *buf, u32 sz, u32 *len, u32 *off)
|
|
|
|
{
|
|
|
|
char *ptr = buf;
|
|
|
|
|
|
|
|
for (u32 i = 0; i < sz; i++, ptr++)
|
|
|
|
{
|
|
|
|
if (*ptr >= 'a' && *ptr <= 'z') *ptr -= 0x20;
|
|
|
|
|
|
|
|
if (i == 7)
|
|
|
|
{
|
|
|
|
*off = i;
|
|
|
|
*len = i;
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (*ptr != '\n') continue;
|
|
|
|
|
|
|
|
*off = i + 1;
|
|
|
|
|
|
|
|
if ((i > 0) && (buf[i - 1] == '\r')) i--;
|
|
|
|
|
|
|
|
*len = i;
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
*off = sz;
|
|
|
|
*len = sz;
|
|
|
|
}
|
|
|
|
|
|
|
|
void get_next_word_uc (char *buf, u32 sz, u32 *len, u32 *off)
|
|
|
|
{
|
|
|
|
char *ptr = buf;
|
|
|
|
|
|
|
|
for (u32 i = 0; i < sz; i++, ptr++)
|
|
|
|
{
|
|
|
|
if (*ptr >= 'a' && *ptr <= 'z') *ptr -= 0x20;
|
|
|
|
|
|
|
|
if (*ptr != '\n') continue;
|
|
|
|
|
|
|
|
*off = i + 1;
|
|
|
|
|
|
|
|
if ((i > 0) && (buf[i - 1] == '\r')) i--;
|
|
|
|
|
|
|
|
*len = i;
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
*off = sz;
|
|
|
|
*len = sz;
|
|
|
|
}
|
|
|
|
|
|
|
|
void get_next_word_std (char *buf, u32 sz, u32 *len, u32 *off)
|
|
|
|
{
|
|
|
|
char *ptr = buf;
|
|
|
|
|
|
|
|
for (u32 i = 0; i < sz; i++, ptr++)
|
|
|
|
{
|
|
|
|
if (*ptr != '\n') continue;
|
|
|
|
|
|
|
|
*off = i + 1;
|
|
|
|
|
|
|
|
if ((i > 0) && (buf[i - 1] == '\r')) i--;
|
|
|
|
|
|
|
|
*len = i;
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
*off = sz;
|
|
|
|
*len = sz;
|
|
|
|
}
|
|
|
|
|
2016-09-22 10:15:13 +00:00
|
|
|
void get_next_word (wl_data_t *wl_data, const user_options_t *user_options, const user_options_extra_t *user_options_extra, FILE *fd, char **out_buf, uint *out_len)
|
2016-09-08 14:32:24 +00:00
|
|
|
{
|
|
|
|
while (wl_data->pos < wl_data->cnt)
|
|
|
|
{
|
|
|
|
uint off;
|
|
|
|
uint len;
|
|
|
|
|
|
|
|
char *ptr = wl_data->buf + wl_data->pos;
|
|
|
|
|
2016-09-22 09:35:08 +00:00
|
|
|
wl_data->func (ptr, wl_data->cnt - wl_data->pos, &len, &off);
|
2016-09-08 14:32:24 +00:00
|
|
|
|
|
|
|
wl_data->pos += off;
|
|
|
|
|
2016-09-22 10:15:13 +00:00
|
|
|
if (run_rule_engine (user_options_extra->rule_len_l, user_options->rule_buf_l))
|
2016-09-08 14:32:24 +00:00
|
|
|
{
|
|
|
|
char rule_buf_out[BLOCK_SIZE] = { 0 };
|
|
|
|
|
|
|
|
int rule_len_out = -1;
|
|
|
|
|
|
|
|
if (len < BLOCK_SIZE)
|
|
|
|
{
|
2016-09-22 10:15:13 +00:00
|
|
|
rule_len_out = _old_apply_rule (user_options->rule_buf_l, user_options_extra->rule_len_l, ptr, len, rule_buf_out);
|
2016-09-08 14:32:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (rule_len_out < 0)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rule_len_out > PW_MAX)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (len > PW_MAX)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
*out_buf = ptr;
|
|
|
|
*out_len = len;
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (feof (fd))
|
|
|
|
{
|
|
|
|
fprintf (stderr, "BUG feof()!!\n");
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
load_segment (wl_data, fd);
|
|
|
|
|
2016-09-22 10:15:13 +00:00
|
|
|
get_next_word (wl_data, user_options, user_options_extra, fd, out_buf, out_len);
|
2016-09-08 14:32:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void pw_add (hc_device_param_t *device_param, const u8 *pw_buf, const int pw_len)
|
|
|
|
{
|
|
|
|
//if (device_param->pws_cnt < device_param->kernel_power)
|
|
|
|
//{
|
|
|
|
pw_t *pw = (pw_t *) device_param->pws_buf + device_param->pws_cnt;
|
|
|
|
|
|
|
|
u8 *ptr = (u8 *) pw->i;
|
|
|
|
|
|
|
|
memcpy (ptr, pw_buf, pw_len);
|
|
|
|
|
|
|
|
memset (ptr + pw_len, 0, sizeof (pw->i) - pw_len);
|
|
|
|
|
|
|
|
pw->pw_len = pw_len;
|
|
|
|
|
|
|
|
device_param->pws_cnt++;
|
|
|
|
//}
|
|
|
|
//else
|
|
|
|
//{
|
|
|
|
// fprintf (stderr, "BUG pw_add()!!\n");
|
|
|
|
//
|
|
|
|
// return;
|
|
|
|
//}
|
|
|
|
}
|
2016-09-12 10:59:40 +00:00
|
|
|
|
2016-09-22 10:15:13 +00:00
|
|
|
u64 count_words (wl_data_t *wl_data, const user_options_t *user_options, const user_options_extra_t *user_options_extra, FILE *fd, const char *dictfile, dictstat_ctx_t *dictstat_ctx)
|
2016-09-12 10:59:40 +00:00
|
|
|
{
|
|
|
|
hc_signal (NULL);
|
|
|
|
|
|
|
|
dictstat_t d;
|
|
|
|
|
|
|
|
d.cnt = 0;
|
|
|
|
|
|
|
|
#if defined (_POSIX)
|
|
|
|
fstat (fileno (fd), &d.stat);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined (_WIN)
|
|
|
|
_fstat64 (fileno (fd), &d.stat);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
d.stat.st_mode = 0;
|
|
|
|
d.stat.st_nlink = 0;
|
|
|
|
d.stat.st_uid = 0;
|
|
|
|
d.stat.st_gid = 0;
|
|
|
|
d.stat.st_rdev = 0;
|
|
|
|
d.stat.st_atime = 0;
|
|
|
|
|
|
|
|
#if defined (_POSIX)
|
|
|
|
d.stat.st_blksize = 0;
|
|
|
|
d.stat.st_blocks = 0;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (d.stat.st_size == 0) return 0;
|
|
|
|
|
|
|
|
const u64 cached_cnt = dictstat_find (dictstat_ctx, &d);
|
|
|
|
|
2016-09-22 10:15:13 +00:00
|
|
|
if (run_rule_engine (user_options_extra->rule_len_l, user_options->rule_buf_l) == 0)
|
2016-09-12 10:59:40 +00:00
|
|
|
{
|
|
|
|
if (cached_cnt)
|
|
|
|
{
|
|
|
|
u64 keyspace = cached_cnt;
|
|
|
|
|
2016-09-22 13:50:49 +00:00
|
|
|
if (user_options_extra->attack_kern == ATTACK_KERN_STRAIGHT)
|
2016-09-12 10:59:40 +00:00
|
|
|
{
|
|
|
|
keyspace *= data.kernel_rules_cnt;
|
|
|
|
}
|
2016-09-22 13:50:49 +00:00
|
|
|
else if (user_options_extra->attack_kern == ATTACK_KERN_COMBI)
|
2016-09-12 10:59:40 +00:00
|
|
|
{
|
|
|
|
keyspace *= data.combs_cnt;
|
|
|
|
}
|
|
|
|
|
2016-09-21 14:07:49 +00:00
|
|
|
if (data.quiet == false) log_info ("Cache-hit dictionary stats %s: %" PRIu64 " bytes, %" PRIu64 " words, %" PRIu64 " keyspace", dictfile, d.stat.st_size, cached_cnt, keyspace);
|
|
|
|
if (data.quiet == false) log_info ("");
|
2016-09-12 10:59:40 +00:00
|
|
|
|
|
|
|
hc_signal (sigHandler_default);
|
|
|
|
|
|
|
|
return (keyspace);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
time_t now = 0;
|
|
|
|
time_t prev = 0;
|
|
|
|
|
|
|
|
u64 comp = 0;
|
|
|
|
u64 cnt = 0;
|
|
|
|
u64 cnt2 = 0;
|
|
|
|
|
|
|
|
while (!feof (fd))
|
|
|
|
{
|
|
|
|
load_segment (wl_data, fd);
|
|
|
|
|
|
|
|
comp += wl_data->cnt;
|
|
|
|
|
|
|
|
u32 i = 0;
|
|
|
|
|
|
|
|
while (i < wl_data->cnt)
|
|
|
|
{
|
|
|
|
u32 len;
|
|
|
|
u32 off;
|
|
|
|
|
2016-09-22 09:35:08 +00:00
|
|
|
wl_data->func (wl_data->buf + i, wl_data->cnt - i, &len, &off);
|
2016-09-12 10:59:40 +00:00
|
|
|
|
2016-09-22 10:15:13 +00:00
|
|
|
if (run_rule_engine (user_options_extra->rule_len_l, user_options->rule_buf_l))
|
2016-09-12 10:59:40 +00:00
|
|
|
{
|
|
|
|
char rule_buf_out[BLOCK_SIZE] = { 0 };
|
|
|
|
|
|
|
|
int rule_len_out = -1;
|
|
|
|
|
|
|
|
if (len < BLOCK_SIZE)
|
|
|
|
{
|
2016-09-22 10:15:13 +00:00
|
|
|
rule_len_out = _old_apply_rule (user_options->rule_buf_l, user_options_extra->rule_len_l, wl_data->buf + i, len, rule_buf_out);
|
2016-09-12 10:59:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (rule_len_out < 0)
|
|
|
|
{
|
|
|
|
len = PW_MAX1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
len = rule_len_out;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (len < PW_MAX1)
|
|
|
|
{
|
2016-09-22 13:50:49 +00:00
|
|
|
if (user_options_extra->attack_kern == ATTACK_KERN_STRAIGHT)
|
2016-09-12 10:59:40 +00:00
|
|
|
{
|
|
|
|
cnt += data.kernel_rules_cnt;
|
|
|
|
}
|
2016-09-22 13:50:49 +00:00
|
|
|
else if (user_options_extra->attack_kern == ATTACK_KERN_COMBI)
|
2016-09-12 10:59:40 +00:00
|
|
|
{
|
|
|
|
cnt += data.combs_cnt;
|
|
|
|
}
|
|
|
|
|
|
|
|
d.cnt++;
|
|
|
|
}
|
|
|
|
|
|
|
|
i += off;
|
|
|
|
|
|
|
|
cnt2++;
|
|
|
|
}
|
|
|
|
|
|
|
|
time (&now);
|
|
|
|
|
|
|
|
if ((now - prev) == 0) continue;
|
|
|
|
|
|
|
|
double percent = (double) comp / (double) d.stat.st_size;
|
|
|
|
|
2016-09-21 14:07:49 +00:00
|
|
|
if (data.quiet == false) log_info_nn ("Generating dictionary stats for %s: %" PRIu64 " bytes (%.2f%%), %" PRIu64 " words, %" PRIu64 " keyspace", dictfile, comp, percent * 100, cnt2, cnt);
|
2016-09-12 10:59:40 +00:00
|
|
|
|
|
|
|
time (&prev);
|
|
|
|
}
|
|
|
|
|
2016-09-21 14:07:49 +00:00
|
|
|
if (data.quiet == false) log_info ("Generated dictionary stats for %s: %" PRIu64 " bytes, %" PRIu64 " words, %" PRIu64 " keyspace", dictfile, comp, cnt2, cnt);
|
|
|
|
if (data.quiet == false) log_info ("");
|
2016-09-12 10:59:40 +00:00
|
|
|
|
|
|
|
dictstat_append (dictstat_ctx, &d);
|
|
|
|
|
|
|
|
hc_signal (sigHandler_default);
|
|
|
|
|
|
|
|
return (cnt);
|
|
|
|
}
|
2016-09-22 09:35:08 +00:00
|
|
|
|
|
|
|
void wl_data_init (wl_data_t *wl_data, const user_options_t *user_options, const hashconfig_t *hashconfig)
|
|
|
|
{
|
|
|
|
wl_data->buf = (char *) mymalloc (user_options->segment_size);
|
|
|
|
wl_data->avail = user_options->segment_size;
|
|
|
|
wl_data->incr = user_options->segment_size;
|
|
|
|
wl_data->cnt = 0;
|
|
|
|
wl_data->pos = 0;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* choose dictionary parser
|
|
|
|
*/
|
|
|
|
|
|
|
|
wl_data->func = get_next_word_std;
|
|
|
|
|
|
|
|
if (hashconfig->opts_type & OPTS_TYPE_PT_UPPER)
|
|
|
|
{
|
|
|
|
wl_data->func = get_next_word_uc;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (hashconfig->hash_type == HASH_TYPE_LM) // yes that's fine that way
|
|
|
|
{
|
|
|
|
wl_data->func = get_next_word_lm;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void wl_data_destroy (wl_data_t *wl_data)
|
|
|
|
{
|
|
|
|
myfree (wl_data->buf);
|
|
|
|
|
|
|
|
wl_data->func = NULL;
|
|
|
|
wl_data->buf = NULL;
|
|
|
|
wl_data->avail = 0;
|
|
|
|
wl_data->incr = 0;
|
|
|
|
wl_data->cnt = 0;
|
|
|
|
wl_data->pos = 0;
|
|
|
|
|
|
|
|
myfree (wl_data);
|
|
|
|
}
|