Added -m 23700/23800 = RAR3-p cracking

pull/2542/head
philsmd 4 years ago
parent 777c5339a0
commit 3cc828ce0a
No known key found for this signature in database
GPG Key ID: 4F25D016D9D6A8AF

@ -0,0 +1,561 @@
/**
* Author......: See docs/credits.txt
* License.....: MIT
*/
#ifdef KERNEL_STATIC
#include "inc_vendor.h"
#include "inc_types.h"
#include "inc_platform.cl"
#include "inc_common.cl"
#include "inc_hash_sha1.cl"
#include "inc_cipher_aes.cl"
#endif
#define COMPARE_S "inc_comp_single.cl"
#define COMPARE_M "inc_comp_multi.cl"
#define ROUNDS 0x40000
#define PUTCHAR(a,p,c) ((u8 *)(a))[(p)] = (u8) (c)
#define GETCHAR(a,p) ((u8 *)(a))[(p)]
#define PUTCHAR_BE(a,p,c) ((u8 *)(a))[(p) ^ 3] = (u8) (c)
#define GETCHAR_BE(a,p) ((u8 *)(a))[(p) ^ 3]
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
typedef struct rar3
{
u32 data[81920];
u32 pack_size;
u32 unpack_size;
} rar3_t;
typedef struct rar3_tmp
{
u32 dgst[17][5];
} rar3_tmp_t;
CONSTANT_VK u32a crc32tab[0x100] =
{
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
DECLSPEC u32 round_crc32 (const u32 a, const u32 v, LOCAL_AS u32 *l_crc32tab)
{
const u32 k = (a ^ v) & 0xff;
const u32 s = a >> 8;
return l_crc32tab[k] ^ s;
}
DECLSPEC u32 round_crc32_16 (const u32 crc32, const u32 *buf, const u32 len, LOCAL_AS u32 *l_crc32tab)
{
const int crc_len = MIN (len, 16);
u32 c = crc32;
for (int i = 0; i < crc_len; i++)
{
const u32 idx = i / 4;
const u32 mod = i % 4;
const u32 sht = (3 - mod) * 8;
const u32 b = buf[idx] >> sht; // b & 0xff (but already done in round_crc32 ())
c = round_crc32 (c, b, l_crc32tab);
}
return c;
}
KERNEL_FQ void m23700_init (KERN_ATTR_TMPS_ESALT (rar3_tmp_t, rar3_t))
{
/**
* base
*/
const u64 gid = get_global_id (0);
if (gid >= gid_max) return;
tmps[gid].dgst[0][0] = SHA1M_A;
tmps[gid].dgst[0][1] = SHA1M_B;
tmps[gid].dgst[0][2] = SHA1M_C;
tmps[gid].dgst[0][3] = SHA1M_D;
tmps[gid].dgst[0][4] = SHA1M_E;
}
KERNEL_FQ void m23700_loop (KERN_ATTR_TMPS_ESALT (rar3_tmp_t, rar3_t))
{
const u64 gid = get_global_id (0);
if (gid >= gid_max) return;
u32 pw_buf[5];
pw_buf[0] = pws[gid].i[0];
pw_buf[1] = pws[gid].i[1];
pw_buf[2] = pws[gid].i[2];
pw_buf[3] = pws[gid].i[3];
pw_buf[4] = pws[gid].i[4];
const u32 pw_len = MIN (pws[gid].pw_len, 20);
u32 salt_buf[2];
salt_buf[0] = salt_bufs[salt_pos].salt_buf[0];
salt_buf[1] = salt_bufs[salt_pos].salt_buf[1];
const u32 salt_len = 8;
// this is large enough to hold all possible w[] arrays for 64 iterations
#define LARGEBLOCK_ELEMS ((40 + 8 + 3) * 16)
u32 largeblock[LARGEBLOCK_ELEMS];
for (u32 i = 0; i < LARGEBLOCK_ELEMS; i++) largeblock[i] = 0;
for (u32 i = 0, p = 0; i < 64; i++)
{
for (u32 j = 0; j < pw_len; j++, p += 2)
{
PUTCHAR_BE (largeblock, p, GETCHAR (pw_buf, j));
}
for (u32 j = 0; j < salt_len; j++, p += 1)
{
PUTCHAR_BE (largeblock, p, GETCHAR (salt_buf, j));
}
PUTCHAR_BE (largeblock, p + 2, (loop_pos >> 16) & 0xff);
p += 3;
}
const u32 p3 = (pw_len * 2) + salt_len + 3;
const u32 init_pos = loop_pos / (ROUNDS / 16);
u32 dgst[5];
dgst[0] = tmps[gid].dgst[init_pos][0];
dgst[1] = tmps[gid].dgst[init_pos][1];
dgst[2] = tmps[gid].dgst[init_pos][2];
dgst[3] = tmps[gid].dgst[init_pos][3];
dgst[4] = tmps[gid].dgst[init_pos][4];
u32 iter = loop_pos;
for (u32 i = 0; i < 256; i += 4)
{
for (u32 j = 0; j < 64; j++)
{
const u32 p = ((j + 1) * p3) - 2;
PUTCHAR_BE (largeblock, p, iter >> 8);
}
for (u32 k = 0; k < 4; k++)
{
for (u32 j = 0; j < 64; j++)
{
const u32 p = ((j + 1) * p3) - 3;
PUTCHAR_BE (largeblock, p, iter >> 0);
iter++;
}
for (u32 j = 0; j < p3; j++)
{
const u32 j16 = j * 16;
u32 w0[4];
u32 w1[4];
u32 w2[4];
u32 w3[4];
w0[0] = largeblock[j16 + 0];
w0[1] = largeblock[j16 + 1];
w0[2] = largeblock[j16 + 2];
w0[3] = largeblock[j16 + 3];
w1[0] = largeblock[j16 + 4];
w1[1] = largeblock[j16 + 5];
w1[2] = largeblock[j16 + 6];
w1[3] = largeblock[j16 + 7];
w2[0] = largeblock[j16 + 8];
w2[1] = largeblock[j16 + 9];
w2[2] = largeblock[j16 + 10];
w2[3] = largeblock[j16 + 11];
w3[0] = largeblock[j16 + 12];
w3[1] = largeblock[j16 + 13];
w3[2] = largeblock[j16 + 14];
w3[3] = largeblock[j16 + 15];
sha1_transform (w0, w1, w2, w3, dgst);
}
}
}
tmps[gid].dgst[init_pos + 1][0] = dgst[0];
tmps[gid].dgst[init_pos + 1][1] = dgst[1];
tmps[gid].dgst[init_pos + 1][2] = dgst[2];
tmps[gid].dgst[init_pos + 1][3] = dgst[3];
tmps[gid].dgst[init_pos + 1][4] = dgst[4];
}
KERNEL_FQ void m23700_comp (KERN_ATTR_TMPS_ESALT (rar3_tmp_t, rar3_t))
{
const u64 gid = get_global_id (0);
const u64 lid = get_local_id (0);
const u64 lsz = get_local_size (0);
/**
* aes shared
*/
#ifdef REAL_SHM
LOCAL_VK u32 s_td0[256];
LOCAL_VK u32 s_td1[256];
LOCAL_VK u32 s_td2[256];
LOCAL_VK u32 s_td3[256];
LOCAL_VK u32 s_td4[256];
LOCAL_VK u32 s_te0[256];
LOCAL_VK u32 s_te1[256];
LOCAL_VK u32 s_te2[256];
LOCAL_VK u32 s_te3[256];
LOCAL_VK u32 s_te4[256];
for (u32 i = lid; i < 256; i += lsz)
{
s_td0[i] = td0[i];
s_td1[i] = td1[i];
s_td2[i] = td2[i];
s_td3[i] = td3[i];
s_td4[i] = td4[i];
s_te0[i] = te0[i];
s_te1[i] = te1[i];
s_te2[i] = te2[i];
s_te3[i] = te3[i];
s_te4[i] = te4[i];
}
#else
CONSTANT_AS u32a *s_td0 = td0;
CONSTANT_AS u32a *s_td1 = td1;
CONSTANT_AS u32a *s_td2 = td2;
CONSTANT_AS u32a *s_td3 = td3;
CONSTANT_AS u32a *s_td4 = td4;
CONSTANT_AS u32a *s_te0 = te0;
CONSTANT_AS u32a *s_te1 = te1;
CONSTANT_AS u32a *s_te2 = te2;
CONSTANT_AS u32a *s_te3 = te3;
CONSTANT_AS u32a *s_te4 = te4;
#endif
LOCAL_VK u32 l_crc32tab[256];
for (int i = lid; i < 256; i += lsz)
{
l_crc32tab[i] = crc32tab[i];
}
SYNC_THREADS ();
if (gid >= gid_max) return;
/**
* base
*/
const u32 pw_len = MIN (pws[gid].pw_len, 20);
const u32 salt_len = 8;
const u32 p3 = (pw_len * 2) + salt_len + 3;
u32 w0[4];
u32 w1[4];
u32 w2[4];
u32 w3[4];
w0[0] = 0x80000000;
w0[1] = 0;
w0[2] = 0;
w0[3] = 0;
w1[0] = 0;
w1[1] = 0;
w1[2] = 0;
w1[3] = 0;
w2[0] = 0;
w2[1] = 0;
w2[2] = 0;
w2[3] = 0;
w3[0] = 0;
w3[1] = 0;
w3[2] = 0;
w3[3] = (p3 * ROUNDS) * 8;
u32 dgst[5];
dgst[0] = tmps[gid].dgst[16][0];
dgst[1] = tmps[gid].dgst[16][1];
dgst[2] = tmps[gid].dgst[16][2];
dgst[3] = tmps[gid].dgst[16][3];
dgst[4] = tmps[gid].dgst[16][4];
sha1_transform (w0, w1, w2, w3, dgst);
u32 ukey[4];
ukey[0] = hc_swap32_S (dgst[0]);
ukey[1] = hc_swap32_S (dgst[1]);
ukey[2] = hc_swap32_S (dgst[2]);
ukey[3] = hc_swap32_S (dgst[3]);
u32 ks[44];
AES128_set_decrypt_key (ks, ukey, s_te0, s_te1, s_te2, s_te3, s_td0, s_td1, s_td2, s_td3);
u32 iv[4];
iv[0] = 0;
iv[1] = 0;
iv[2] = 0;
iv[3] = 0;
for (int i = 0; i < 16; i++)
{
u32 pw_buf[5];
pw_buf[0] = pws[gid].i[0];
pw_buf[1] = pws[gid].i[1];
pw_buf[2] = pws[gid].i[2];
pw_buf[3] = pws[gid].i[3];
pw_buf[4] = pws[gid].i[4];
//const u32 pw_len = pws[gid].pw_len;
u32 salt_buf[2];
salt_buf[0] = salt_bufs[salt_pos].salt_buf[0];
salt_buf[1] = salt_bufs[salt_pos].salt_buf[1];
//const u32 salt_len = 8;
//const u32 p3 = (pw_len * 2) + salt_len + 3;
u32 w[16];
w[ 0] = 0;
w[ 1] = 0;
w[ 2] = 0;
w[ 3] = 0;
w[ 4] = 0;
w[ 5] = 0;
w[ 6] = 0;
w[ 7] = 0;
w[ 8] = 0;
w[ 9] = 0;
w[10] = 0;
w[11] = 0;
w[12] = 0;
w[13] = 0;
w[14] = 0;
w[15] = 0;
u32 p = 0;
for (u32 j = 0; j < pw_len; j++, p += 2)
{
PUTCHAR_BE (w, p, GETCHAR (pw_buf, j));
}
for (u32 j = 0; j < salt_len; j++, p += 1)
{
PUTCHAR_BE (w, p, GETCHAR (salt_buf, j));
}
const u32 iter_pos = i * (ROUNDS / 16);
PUTCHAR_BE (w, p + 0, (iter_pos >> 0) & 0xff);
PUTCHAR_BE (w, p + 1, (iter_pos >> 8) & 0xff);
PUTCHAR_BE (w, p + 2, (iter_pos >> 16) & 0xff);
PUTCHAR_BE (w, p3, 0x80);
w[15] = ((iter_pos + 1) * p3) * 8;
u32 dgst[5];
dgst[0] = tmps[gid].dgst[i][0];
dgst[1] = tmps[gid].dgst[i][1];
dgst[2] = tmps[gid].dgst[i][2];
dgst[3] = tmps[gid].dgst[i][3];
dgst[4] = tmps[gid].dgst[i][4];
sha1_transform (w + 0, w + 4, w + 8, w + 12, dgst);
PUTCHAR (iv, i, dgst[4] & 0xff);
}
iv[0] = hc_swap32_S (iv[0]);
iv[1] = hc_swap32_S (iv[1]);
iv[2] = hc_swap32_S (iv[2]);
iv[3] = hc_swap32_S (iv[3]);
const u32 pack_size = esalt_bufs[digests_offset].pack_size;
const u32 unpack_size = esalt_bufs[digests_offset].unpack_size;
if (pack_size > unpack_size) // could be aligned
{
if (pack_size >= 32) // otherwise IV...
{
const u32 pack_size_elements = pack_size / 4;
u32 last_block_encrypted[4];
last_block_encrypted[0] = esalt_bufs[digests_offset].data[pack_size_elements - 4 + 0];
last_block_encrypted[1] = esalt_bufs[digests_offset].data[pack_size_elements - 4 + 1];
last_block_encrypted[2] = esalt_bufs[digests_offset].data[pack_size_elements - 4 + 2];
last_block_encrypted[3] = esalt_bufs[digests_offset].data[pack_size_elements - 4 + 3];
u32 last_block_decrypted[4];
AES128_decrypt (ks, last_block_encrypted, last_block_decrypted, s_td0, s_td1, s_td2, s_td3, s_td4);
u32 last_block_iv[4];
last_block_iv[0] = esalt_bufs[digests_offset].data[pack_size_elements - 8 + 0];
last_block_iv[1] = esalt_bufs[digests_offset].data[pack_size_elements - 8 + 1];
last_block_iv[2] = esalt_bufs[digests_offset].data[pack_size_elements - 8 + 2];
last_block_iv[3] = esalt_bufs[digests_offset].data[pack_size_elements - 8 + 3];
last_block_decrypted[0] ^= last_block_iv[0];
last_block_decrypted[1] ^= last_block_iv[1];
last_block_decrypted[2] ^= last_block_iv[2];
last_block_decrypted[3] ^= last_block_iv[3];
if ((last_block_decrypted[3] & 0xff) != 0) return;
}
}
u32 data_left = unpack_size;
u32 crc32 = ~0;
for (u32 i = 0, j = 0; i < pack_size / 16; i += 1, j += 4)
{
u32 data[4];
data[0] = esalt_bufs[digests_offset].data[j + 0];
data[1] = esalt_bufs[digests_offset].data[j + 1];
data[2] = esalt_bufs[digests_offset].data[j + 2];
data[3] = esalt_bufs[digests_offset].data[j + 3];
u32 out[4];
AES128_decrypt (ks, data, out, s_td0, s_td1, s_td2, s_td3, s_td4);
out[0] ^= iv[0];
out[1] ^= iv[1];
out[2] ^= iv[2];
out[3] ^= iv[3];
crc32 = round_crc32_16 (crc32, out, data_left, l_crc32tab);
iv[0] = data[0];
iv[1] = data[1];
iv[2] = data[2];
iv[3] = data[3];
data_left -= 16;
}
const u32 r0 = crc32;
const u32 r1 = 0;
const u32 r2 = 0;
const u32 r3 = 0;
#define il_pos 0
#ifdef KERNEL_STATIC
#include COMPARE_M
#endif
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,436 @@
/**
* Author......: See docs/credits.txt
* License.....: MIT
*/
#ifdef KERNEL_STATIC
#include "inc_vendor.h"
#include "inc_types.h"
#include "inc_platform.cl"
#include "inc_common.cl"
#include "inc_hash_sha1.cl"
#include "inc_cipher_aes.cl"
#endif
#define COMPARE_S "inc_comp_single.cl"
#define COMPARE_M "inc_comp_multi.cl"
#define ROUNDS 0x40000
#define PUTCHAR(a,p,c) ((u8 *)(a))[(p)] = (u8) (c)
#define GETCHAR(a,p) ((u8 *)(a))[(p)]
#define PUTCHAR_BE(a,p,c) ((u8 *)(a))[(p) ^ 3] = (u8) (c)
#define GETCHAR_BE(a,p) ((u8 *)(a))[(p) ^ 3]
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
typedef struct rar3
{
u32 first_block_encrypted[4];
} rar3_t;
typedef struct rar3_tmp
{
u32 dgst[17][5];
} rar3_tmp_t;
typedef struct rar3_hook
{
u32 key[4];
u32 iv[4];
u32 first_block_decrypted[4];
u32 crc32;
} rar3_hook_t;
KERNEL_FQ void m23800_init (KERN_ATTR_TMPS_HOOKS_ESALT (rar3_tmp_t, rar3_hook_t, rar3_t))
{
/**
* base
*/
const u64 gid = get_global_id (0);
if (gid >= gid_max) return;
tmps[gid].dgst[0][0] = SHA1M_A;
tmps[gid].dgst[0][1] = SHA1M_B;
tmps[gid].dgst[0][2] = SHA1M_C;
tmps[gid].dgst[0][3] = SHA1M_D;
tmps[gid].dgst[0][4] = SHA1M_E;
}
KERNEL_FQ void m23800_loop (KERN_ATTR_TMPS_HOOKS_ESALT (rar3_tmp_t, rar3_hook_t, rar3_t))
{
const u64 gid = get_global_id (0);
if (gid >= gid_max) return;
u32 pw_buf[5];
pw_buf[0] = pws[gid].i[0];
pw_buf[1] = pws[gid].i[1];
pw_buf[2] = pws[gid].i[2];
pw_buf[3] = pws[gid].i[3];
pw_buf[4] = pws[gid].i[4];
const u32 pw_len = MIN (pws[gid].pw_len, 20);
u32 salt_buf[2];
salt_buf[0] = salt_bufs[salt_pos].salt_buf[0];
salt_buf[1] = salt_bufs[salt_pos].salt_buf[1];
const u32 salt_len = 8;
// this is large enough to hold all possible w[] arrays for 64 iterations
#define LARGEBLOCK_ELEMS ((40 + 8 + 3) * 16)
u32 largeblock[LARGEBLOCK_ELEMS];
for (u32 i = 0; i < LARGEBLOCK_ELEMS; i++) largeblock[i] = 0;
for (u32 i = 0, p = 0; i < 64; i++)
{
for (u32 j = 0; j < pw_len; j++, p += 2)
{
PUTCHAR_BE (largeblock, p, GETCHAR (pw_buf, j));
}
for (u32 j = 0; j < salt_len; j++, p += 1)
{
PUTCHAR_BE (largeblock, p, GETCHAR (salt_buf, j));
}
PUTCHAR_BE (largeblock, p + 2, (loop_pos >> 16) & 0xff);
p += 3;
}
const u32 p3 = (pw_len * 2) + salt_len + 3;
const u32 init_pos = loop_pos / (ROUNDS / 16);
u32 dgst[5];
dgst[0] = tmps[gid].dgst[init_pos][0];
dgst[1] = tmps[gid].dgst[init_pos][1];
dgst[2] = tmps[gid].dgst[init_pos][2];
dgst[3] = tmps[gid].dgst[init_pos][3];
dgst[4] = tmps[gid].dgst[init_pos][4];
u32 iter = loop_pos;
for (u32 i = 0; i < 256; i += 4)
{
for (u32 j = 0; j < 64; j++)
{
const u32 p = ((j + 1) * p3) - 2;
PUTCHAR_BE (largeblock, p, iter >> 8);
}
for (u32 k = 0; k < 4; k++)
{
for (u32 j = 0; j < 64; j++)
{
const u32 p = ((j + 1) * p3) - 3;
PUTCHAR_BE (largeblock, p, iter >> 0);
iter++;
}
for (u32 j = 0; j < p3; j++)
{
const u32 j16 = j * 16;
u32 w0[4];
u32 w1[4];
u32 w2[4];
u32 w3[4];
w0[0] = largeblock[j16 + 0];
w0[1] = largeblock[j16 + 1];
w0[2] = largeblock[j16 + 2];
w0[3] = largeblock[j16 + 3];
w1[0] = largeblock[j16 + 4];
w1[1] = largeblock[j16 + 5];
w1[2] = largeblock[j16 + 6];
w1[3] = largeblock[j16 + 7];
w2[0] = largeblock[j16 + 8];
w2[1] = largeblock[j16 + 9];
w2[2] = largeblock[j16 + 10];
w2[3] = largeblock[j16 + 11];
w3[0] = largeblock[j16 + 12];
w3[1] = largeblock[j16 + 13];
w3[2] = largeblock[j16 + 14];
w3[3] = largeblock[j16 + 15];
sha1_transform (w0, w1, w2, w3, dgst);
}
}
}
tmps[gid].dgst[init_pos + 1][0] = dgst[0];
tmps[gid].dgst[init_pos + 1][1] = dgst[1];
tmps[gid].dgst[init_pos + 1][2] = dgst[2];
tmps[gid].dgst[init_pos + 1][3] = dgst[3];
tmps[gid].dgst[init_pos + 1][4] = dgst[4];
}
KERNEL_FQ void m23800_hook23 (KERN_ATTR_TMPS_HOOKS_ESALT (rar3_tmp_t, rar3_hook_t, rar3_t))
{
const u64 gid = get_global_id (0);
const u64 lid = get_local_id (0);
const u64 lsz = get_local_size (0);
/**
* aes shared
*/
#ifdef REAL_SHM
LOCAL_VK u32 s_td0[256];
LOCAL_VK u32 s_td1[256];
LOCAL_VK u32 s_td2[256];
LOCAL_VK u32 s_td3[256];
LOCAL_VK u32 s_td4[256];
LOCAL_VK u32 s_te0[256];
LOCAL_VK u32 s_te1[256];
LOCAL_VK u32 s_te2[256];
LOCAL_VK u32 s_te3[256];
LOCAL_VK u32 s_te4[256];
for (u32 i = lid; i < 256; i += lsz)
{
s_td0[i] = td0[i];
s_td1[i] = td1[i];
s_td2[i] = td2[i];
s_td3[i] = td3[i];
s_td4[i] = td4[i];
s_te0[i] = te0[i];
s_te1[i] = te1[i];
s_te2[i] = te2[i];
s_te3[i] = te3[i];
s_te4[i] = te4[i];
}
#else
CONSTANT_AS u32a *s_td0 = td0;
CONSTANT_AS u32a *s_td1 = td1;
CONSTANT_AS u32a *s_td2 = td2;
CONSTANT_AS u32a *s_td3 = td3;
CONSTANT_AS u32a *s_td4 = td4;
CONSTANT_AS u32a *s_te0 = te0;
CONSTANT_AS u32a *s_te1 = te1;
CONSTANT_AS u32a *s_te2 = te2;
CONSTANT_AS u32a *s_te3 = te3;
CONSTANT_AS u32a *s_te4 = te4;
#endif
SYNC_THREADS ();
if (gid >= gid_max) return;
/**
* base
*/
const u32 pw_len = MIN (pws[gid].pw_len, 20);
const u32 salt_len = 8;
const u32 p3 = (pw_len * 2) + salt_len + 3;
u32 w0[4];
u32 w1[4];
u32 w2[4];
u32 w3[4];
w0[0] = 0x80000000;
w0[1] = 0;
w0[2] = 0;
w0[3] = 0;
w1[0] = 0;
w1[1] = 0;
w1[2] = 0;
w1[3] = 0;
w2[0] = 0;
w2[1] = 0;
w2[2] = 0;
w2[3] = 0;
w3[0] = 0;
w3[1] = 0;
w3[2] = 0;
w3[3] = (p3 * ROUNDS) * 8;
u32 h[5];
h[0] = tmps[gid].dgst[16][0];
h[1] = tmps[gid].dgst[16][1];
h[2] = tmps[gid].dgst[16][2];
h[3] = tmps[gid].dgst[16][3];
h[4] = tmps[gid].dgst[16][4];
sha1_transform (w0, w1, w2, w3, h);
u32 iv[4];
iv[0] = 0;
iv[1] = 0;
iv[2] = 0;
iv[3] = 0;
for (int i = 0; i < 16; i++)
{
u32 pw_buf[5];
pw_buf[0] = pws[gid].i[0];
pw_buf[1] = pws[gid].i[1];
pw_buf[2] = pws[gid].i[2];
pw_buf[3] = pws[gid].i[3];
pw_buf[4] = pws[gid].i[4];
//const u32 pw_len = pws[gid].pw_len;
u32 salt_buf[2];
salt_buf[0] = salt_bufs[salt_pos].salt_buf[0];
salt_buf[1] = salt_bufs[salt_pos].salt_buf[1];
//const u32 salt_len = 8;
//const u32 p3 = (pw_len * 2) + salt_len + 3;
u32 w[16];
w[ 0] = 0;
w[ 1] = 0;
w[ 2] = 0;
w[ 3] = 0;
w[ 4] = 0;
w[ 5] = 0;
w[ 6] = 0;
w[ 7] = 0;
w[ 8] = 0;
w[ 9] = 0;
w[10] = 0;
w[11] = 0;
w[12] = 0;
w[13] = 0;
w[14] = 0;
w[15] = 0;
u32 p = 0;
for (u32 j = 0; j < pw_len; j++, p += 2)
{
PUTCHAR_BE (w, p, GETCHAR (pw_buf, j));
}
for (u32 j = 0; j < salt_len; j++, p += 1)
{
PUTCHAR_BE (w, p, GETCHAR (salt_buf, j));
}
const u32 iter_pos = i * (ROUNDS / 16);
PUTCHAR_BE (w, p + 0, (iter_pos >> 0) & 0xff);
PUTCHAR_BE (w, p + 1, (iter_pos >> 8) & 0xff);
PUTCHAR_BE (w, p + 2, (iter_pos >> 16) & 0xff);
PUTCHAR_BE (w, p3, 0x80);
w[15] = ((iter_pos + 1) * p3) * 8;
u32 dgst[5];
dgst[0] = tmps[gid].dgst[i][0];
dgst[1] = tmps[gid].dgst[i][1];
dgst[2] = tmps[gid].dgst[i][2];
dgst[3] = tmps[gid].dgst[i][3];
dgst[4] = tmps[gid].dgst[i][4];
sha1_transform (w + 0, w + 4, w + 8, w + 12, dgst);
PUTCHAR (iv, i, dgst[4] & 0xff);
}
hooks[gid].key[0] = h[0];
hooks[gid].key[1] = h[1];
hooks[gid].key[2] = h[2];
hooks[gid].key[3] = h[3];
hooks[gid].iv[0] = iv[0];
hooks[gid].iv[1] = iv[1];
hooks[gid].iv[2] = iv[2];
hooks[gid].iv[3] = iv[3];
u32 ukey[4];
ukey[0] = hc_swap32_S (h[0]);
ukey[1] = hc_swap32_S (h[1]);
ukey[2] = hc_swap32_S (h[2]);
ukey[3] = hc_swap32_S (h[3]);
u32 ks[44];
AES128_set_decrypt_key (ks, ukey, s_te0, s_te1, s_te2, s_te3, s_td0, s_td1, s_td2, s_td3);
u32 data[4];
data[0] = hc_swap32_S (esalt_bufs[digests_offset].first_block_encrypted[0]);
data[1] = hc_swap32_S (esalt_bufs[digests_offset].first_block_encrypted[1]);
data[2] = hc_swap32_S (esalt_bufs[digests_offset].first_block_encrypted[2]);
data[3] = hc_swap32_S (esalt_bufs[digests_offset].first_block_encrypted[3]);
u32 out[4];
AES128_decrypt (ks, data, out, s_td0, s_td1, s_td2, s_td3, s_td4);
out[0] ^= hc_swap32_S (iv[0]);
out[1] ^= hc_swap32_S (iv[1]);
out[2] ^= hc_swap32_S (iv[2]);
out[3] ^= hc_swap32_S (iv[3]);
hooks[gid].first_block_decrypted[0] = hc_swap32_S (out[0]);
hooks[gid].first_block_decrypted[1] = hc_swap32_S (out[1]);
hooks[gid].first_block_decrypted[2] = hc_swap32_S (out[2]);
hooks[gid].first_block_decrypted[3] = hc_swap32_S (out[3]);
}
KERNEL_FQ void m23800_comp (KERN_ATTR_TMPS_HOOKS_ESALT (rar3_tmp_t, rar3_hook_t, rar3_t))
{
/**
* base
*/
const u64 gid = get_global_id (0);
if (gid >= gid_max) return;
u32 crc32 = hooks[gid].crc32;
const u32 r0 = crc32;
const u32 r1 = 0;
const u32 r2 = 0;
const u32 r3 = 0;
#define il_pos 0
#ifdef KERNEL_STATIC
#include COMPARE_M
#endif
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,55 @@
/**
* Author......: See docs/credits.txt
* License.....: MIT
*/
// CREDITS go to the UnRAR project from rarlab.com
// see license.txt file
#include "rar.hpp"
#define WINSIZE 0x100000 // minimum window size 0x20000 (MinAllocSize is 0x40000), 1 MiB
#define SOLID false
#define METHOD VER_UNPACK // 29 for RAR3 archives
extern "C" unsigned int hc_decompress_rar (unsigned char *Win, unsigned char *Inp, unsigned char *VM, unsigned char *PPM, const unsigned int OutputSize, const unsigned char *Input, const unsigned int PackSize, const unsigned int UnpackSize, const unsigned char *Key, const unsigned char *IV)
{
ComprDataIO DataIO;
DataIO.InitRijindal ((byte *) Key, (byte *) IV);
DataIO.SetPackedSizeToRead (PackSize);
DataIO.SetTestMode (false);
DataIO.SetSkipUnpCRC (false); // or 'true', if we use our own crc32 code
DataIO.UnpHash.Init (HASH_CRC32, 1); // 1: 1 single thread ?
DataIO.SetUnpackFromMemory ((byte *) Input, PackSize);
DataIO.SetUnpackToMemory ((byte *) NULL, UnpackSize);
Unpack *Unp = new Unpack (&DataIO);
// not needed in our tests (no false positives):
// memset (Win, 0, UnpackSize);
// #define INPSIZE 0x50000
// memset (Inp, 0, INPSIZE);
// memset (VM, 0, INPSIZE);
// #define PPMSIZE 216 * 1024 * 1024
// memset (PPM, 0, PPMSIZE);
Unp->SetWin (Win);
Unp->SetPPM (PPM);
Unp->Init (WINSIZE, SOLID);
Unp->SetDestSize (UnpackSize);
Unp->SetExternalBuffer (Inp, VM);
Unp->DoUnpack (METHOD, SOLID); // sets output
unsigned int crc32 = (unsigned int) DataIO.UnpHash.GetCRC32 ();
delete Unp;
return crc32;
}

@ -8,6 +8,8 @@
- Added hash-mode: Apple iWork
- Added hash-mode: AxCrypt 2 AES-128
- Added hash-mode: AxCrypt 2 AES-256
- Added hash-mode: RAR3-p (Compressed)
- Added hash-mode: RAR3-p (Uncompressed)
- Added hash-mode: RSA/DSA/EC/OPENSSH Private Keys
##

@ -57,6 +57,7 @@ Other contributors to hashcat
* zlib by Jean-loup Gailly and Mark Adler
* win-iconv by Yukihiro Nakadaira
* micro-ecc by Ken MacKay (used as reference for some secp256k1 operations)
* UnRAR by Alexander Roshal
# Furthermore the following persons helped the project:

@ -0,0 +1,42 @@
****** ***** ****** UnRAR - free utility for RAR archives
** ** ** ** ** ** ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
****** ******* ****** License for use and distribution of
** ** ** ** ** ** ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
** ** ** ** ** ** FREE portable version
~~~~~~~~~~~~~~~~~~~~~
The source code of UnRAR utility is freeware. This means:
1. All copyrights to RAR and the utility UnRAR are exclusively
owned by the author - Alexander Roshal.
2. UnRAR source code may be used in any software to handle
RAR archives without limitations free of charge, but cannot be
used to develop RAR (WinRAR) compatible archiver and to
re-create RAR compression algorithm, which is proprietary.
Distribution of modified UnRAR source code in separate form
or as a part of other software is permitted, provided that
full text of this paragraph, starting from "UnRAR source code"
words, is included in license, or in documentation if license
is not available, and in source code comments of resulting package.
3. The UnRAR utility may be freely distributed. It is allowed
to distribute UnRAR inside of other software packages.
4. THE RAR ARCHIVER AND THE UnRAR UTILITY ARE DISTRIBUTED "AS IS".
NO WARRANTY OF ANY KIND IS EXPRESSED OR IMPLIED. YOU USE AT
YOUR OWN RISK. THE AUTHOR WILL NOT BE LIABLE FOR DATA LOSS,
DAMAGES, LOSS OF PROFITS OR ANY OTHER KIND OF LOSS WHILE USING
OR MISUSING THIS SOFTWARE.
5. Installing and using the UnRAR utility signifies acceptance of
these terms and conditions of the license.
6. If you don't agree with terms of the license you must remove
UnRAR files from your storage devices and cease to use the
utility.
Thank you for your interest in RAR and UnRAR.
Alexander L. Roshal

@ -295,6 +295,7 @@ NVIDIA GPUs require "NVIDIA Driver" (440.64 or later) and "CUDA Toolkit" (9.0 or
- MultiBit HD (scrypt)
- 7-Zip
- RAR3-hp
- RAR3-p
- RAR5
- PKZIP (Compressed)
- PKZIP (Compressed Multi-File)

@ -13,6 +13,8 @@ USE_SYSTEM_LZMA ?= 0
USE_SYSTEM_ZLIB ?= 0
USE_SYSTEM_OPENCL ?= 0
USE_SYSTEM_XXHASH ?= 0
## do not change, requires some hacks
USE_SYSTEM_UNRAR ?= 0
##
## Detect Operating System
@ -57,6 +59,7 @@ MODULE_INTERFACE_VERSION := 620
##
CC := gcc
CXX := g++
AR := ar
FIND := find
INSTALL := install
@ -66,6 +69,7 @@ SED_IN_PLACE := -i
ifeq ($(UNAME),Darwin)
CC := clang
CXX := clang++
# the sed -i option of macOS requires a parameter for the backup file (we just use "")
AR := /usr/bin/ar
SED := /usr/bin/sed
@ -75,6 +79,7 @@ endif
ifeq ($(UNAME),FreeBSD)
CC := cc
CXX := c++
SED := gsed
endif
@ -133,6 +138,12 @@ else
DEPS_XXHASH_PATH := $(LIBRARY_DEV_ROOT_FOLDER)
endif
ifeq ($(USE_SYSTEM_UNRAR),0)
DEPS_UNRAR_PATH := deps/unrar
else
DEPS_UNRAR_PATH := $(LIBRARY_DEV_ROOT_FOLDER)
endif
##
## Filenames for library and frontend
##
@ -185,6 +196,22 @@ CFLAGS_ZLIB += -Wno-unused-parameter
CFLAGS_ZLIB += -DIOAPI_NO_64
endif
## because UNRAR
ifeq ($(USE_SYSTEM_UNRAR),0)
CFLAGS_UNRAR += -Wno-unused-variable
CFLAGS_UNRAR += -Wno-unused-parameter
CFLAGS_UNRAR += -Wno-unused-function
CFLAGS_UNRAR += -Wno-sign-compare
CFLAGS_UNRAR += -Wno-dangling-else
CFLAGS_UNRAR += -Wno-switch
CFLAGS_UNRAR += -Wno-parentheses
CFLAGS_UNRAR += -Wno-misleading-indentation
CFLAGS_UNRAR += -Wno-implicit-fallthrough
CFLAGS_UNRAR += -Wno-extra
CFLAGS_UNRAR += -Wno-unknown-pragmas
CFLAGS_UNRAR += -Wno-class-memaccess
endif
ifeq ($(DEBUG),0)
CFLAGS += -O2
ifneq ($(UNAME),Darwin)
@ -209,7 +236,7 @@ endif
endif
endif
CFLAGS += -pipe -std=gnu99 -Iinclude/ -IOpenCL/
CFLAGS += -pipe -Iinclude/ -IOpenCL/
# LZMA
CFLAGS += -I$(DEPS_LZMA_PATH)
@ -240,6 +267,10 @@ ifeq ($(ENABLE_CUBIN),1)
CFLAGS += -DWITH_CUBIN
endif
# unrar
CFLAGS += -I$(DEPS_UNRAR_PATH)
LFLAGS += -lstdc++
##
## Native compilation target
##
@ -297,8 +328,15 @@ LFLAGS_NATIVE += -Wl,--nxcompat
LFLAGS_NATIVE += -lpsapi
LFLAGS_NATIVE += -liconv
LFLAGS_NATIVE += -lws2_32
LFLAGS_NATIVE += -lpowrprof
endif # MSYS2
# CCFLAGS only for C compiler
CCFLAGS := -std=gnu99
# CXXFLAGS only for C++ compiler
CXXFLAGS :=
##
## Objects
##
@ -345,6 +383,14 @@ WIN_OBJS += $(foreach OBJ,$(OBJS_XXHASH),obj/$(OBJ).WIN.o)
endif
endif
ifeq ($(USE_SYSTEM_UNRAR),0)
OBJS_UNRAR := strlist strfn pathfn smallfn global file filefn filcreat archive arcread unicode system isnt crypt crc rawread encname resource match timefn rdwrfn consio options errhnd rarvm secpassword rijndael getbits sha1 sha256 blake2s hash extinfo extract volume list find unpack headers threadpool rs16 cmddata ui filestr recvol rs scantree qopen hc_decompress_rar
NATIVE_OBJS += $(foreach OBJ,$(OBJS_UNRAR),obj/$(OBJ).NATIVE.o)
LINUX_OBJS += $(foreach OBJ,$(OBJS_UNRAR),obj/$(OBJ).LINUX.o)
WIN_OBJS += $(foreach OBJ,$(OBJS_UNRAR),obj/$(OBJ).WIN.o)
endif
##
## Targets: Native Compilation
##
@ -358,6 +404,7 @@ clean:
$(RM) -f modules/*.dll
$(RM) -f modules/*.so
$(RM) -f obj/*/*/*.o
$(RM) -f obj/*/*.o
$(RM) -f obj/*.o
$(RM) -f obj/*.a
$(RM) -rf *.dSYM
@ -484,23 +531,28 @@ uninstall:
##
obj/%.NATIVE.o: src/%.c
$(CC) -c $(CFLAGS_NATIVE) $< -o $@ -fpic
$(CC) -c $(CCFLAGS) $(CFLAGS_NATIVE) $< -o $@ -fpic
ifeq ($(USE_SYSTEM_LZMA),0)
obj/%.NATIVE.o: $(DEPS_LZMA_PATH)/%.c
$(CC) -c $(CFLAGS_NATIVE) $< -o $@ -fpic
$(CC) -c $(CCFLAGS) $(CFLAGS_NATIVE) $< -o $@ -fpic
endif
ifeq ($(USE_SYSTEM_ZLIB),0)
obj/%.NATIVE.o: $(DEPS_ZLIB_PATH)/%.c
$(CC) -c $(CFLAGS_NATIVE) $(CFLAGS_ZLIB) $< -o $@ -fpic
$(CC) -c $(CCFLAGS) $(CFLAGS_NATIVE) $(CFLAGS_ZLIB) $< -o $@ -fpic
endif
ifeq ($(USE_SYSTEM_XXHASH),0)
ifeq ($(ENABLE_BRAIN),1)
obj/%.NATIVE.o: $(DEPS_XXHASH_PATH)/%.c
$(CC) -c $(CFLAGS_NATIVE) $< -o $@ -fpic
$(CC) -c $(CCFLAGS) $(CFLAGS_NATIVE) $< -o $@ -fpic
endif
endif
ifeq ($(USE_SYSTEM_UNRAR),0)
obj/%.NATIVE.o: $(DEPS_UNRAR_PATH)/%.cpp
$(CXX) -c $(CXXFLAGS) $(CFLAGS_NATIVE) $(CFLAGS_UNRAR) $< -o $@ -fpic
endif
obj/combined.NATIVE.a: $(NATIVE_OBJS)
@ -516,10 +568,10 @@ endif
ifeq ($(SHARED),1)
$(HASHCAT_FRONTEND): src/main.c $(HASHCAT_LIBRARY)
$(CC) $(CFLAGS_NATIVE) $^ -o $@ $(HASHCAT_LIBRARY) $(LFLAGS_NATIVE) -DCOMPTIME=$(COMPTIME) -DVERSION_TAG=\"$(VERSION_TAG)\" -DINSTALL_FOLDER=\"$(INSTALL_FOLDER)\" -DSHARED_FOLDER=\"$(SHARED_FOLDER)\" -DDOCUMENT_FOLDER=\"$(DOCUMENT_FOLDER)\"
$(CC) $(CCFLAGS) $(CFLAGS_NATIVE) $^ -o $@ $(HASHCAT_LIBRARY) $(LFLAGS_NATIVE) -DCOMPTIME=$(COMPTIME) -DVERSION_TAG=\"$(VERSION_TAG)\" -DINSTALL_FOLDER=\"$(INSTALL_FOLDER)\" -DSHARED_FOLDER=\"$(SHARED_FOLDER)\" -DDOCUMENT_FOLDER=\"$(DOCUMENT_FOLDER)\"
else
$(HASHCAT_FRONTEND): src/main.c obj/combined.NATIVE.a
$(CC) $(CFLAGS_NATIVE) $^ -o $@ $(LFLAGS_NATIVE) -DCOMPTIME=$(COMPTIME) -DVERSION_TAG=\"$(VERSION_TAG)\" -DINSTALL_FOLDER=\"$(INSTALL_FOLDER)\" -DSHARED_FOLDER=\"$(SHARED_FOLDER)\" -DDOCUMENT_FOLDER=\"$(DOCUMENT_FOLDER)\"
$(CC) $(CCFLAGS) $(CFLAGS_NATIVE) $^ -o $@ $(LFLAGS_NATIVE) -DCOMPTIME=$(COMPTIME) -DVERSION_TAG=\"$(VERSION_TAG)\" -DINSTALL_FOLDER=\"$(INSTALL_FOLDER)\" -DSHARED_FOLDER=\"$(SHARED_FOLDER)\" -DDOCUMENT_FOLDER=\"$(DOCUMENT_FOLDER)\"
endif
##
@ -541,10 +593,10 @@ MODULES_LIB := $(patsubst src/modules/module_%.c, modules/module_%.$(MODULE_SU
ifeq ($(SHARED),1)
modules/module_%.$(MODULE_SUFFIX): src/modules/module_%.c $(HASHCAT_LIBRARY)
$(CC) $(CFLAGS_NATIVE) $^ -o $@ $(LFLAGS_NATIVE) -shared -fPIC -D MODULE_INTERFACE_VERSION_CURRENT=$(MODULE_INTERFACE_VERSION)
$(CC) $(CCFLAGS) $(CFLAGS_NATIVE) $^ -o $@ $(LFLAGS_NATIVE) -shared -fPIC -D MODULE_INTERFACE_VERSION_CURRENT=$(MODULE_INTERFACE_VERSION)
else
modules/module_%.$(MODULE_SUFFIX): src/modules/module_%.c obj/combined.NATIVE.a
$(CC) $(CFLAGS_NATIVE) $^ -o $@ $(LFLAGS_NATIVE) -shared -fPIC -D MODULE_INTERFACE_VERSION_CURRENT=$(MODULE_INTERFACE_VERSION)
$(CC) $(CCFLAGS) $(CFLAGS_NATIVE) $^ -o $@ $(LFLAGS_NATIVE) -shared -fPIC -D MODULE_INTERFACE_VERSION_CURRENT=$(MODULE_INTERFACE_VERSION)
endif
modules: $(MODULES_LIB)
@ -560,7 +612,9 @@ ifeq ($(UNAME),Linux)
##
CC_LINUX := gcc
CXX_LINUX := g++
CC_WIN := x86_64-w64-mingw32-gcc
CXX_WIN := x86_64-w64-mingw32-g++
AR_LINUX := ar
AR_WIN := x86_64-w64-mingw32-ar
@ -593,6 +647,8 @@ LFLAGS_CROSS_WIN += -Wl,--dynamicbase
LFLAGS_CROSS_WIN += -Wl,--nxcompat
LFLAGS_CROSS_WIN += -lpsapi
LFLAGS_CROSS_WIN += -lws2_32
LFLAGS_CROSS_WIN += -lpowrprof
LFLAGS_CROSS_WIN += -static -static-libgcc -static-libstdc++
##
## Targets
@ -617,45 +673,53 @@ modules_linux: $(MODULES_LIB_LINUX)
modules_win: $(MODULES_LIB_WIN)
modules/module_%.so: src/modules/module_%.c obj/combined.LINUX.a
$(CC_LINUX) $(CFLAGS_CROSS_LINUX) $^ -o $@ $(LFLAGS_CROSS_LINUX) -shared -fPIC -D MODULE_INTERFACE_VERSION_CURRENT=$(MODULE_INTERFACE_VERSION)
$(CC_LINUX) $(CCFLAGS) $(CFLAGS_CROSS_LINUX) $^ -o $@ $(LFLAGS_CROSS_LINUX) -shared -fPIC -D MODULE_INTERFACE_VERSION_CURRENT=$(MODULE_INTERFACE_VERSION)
modules/module_%.dll: src/modules/module_%.c obj/combined.WIN.a
$(CC_WIN) $(CFLAGS_CROSS_WIN) $^ -o $@ $(LFLAGS_CROSS_WIN) -shared -fPIC -D MODULE_INTERFACE_VERSION_CURRENT=$(MODULE_INTERFACE_VERSION)
$(CC_WIN) $(CCFLAGS) $(CFLAGS_CROSS_WIN) $^ -o $@ $(LFLAGS_CROSS_WIN) -shared -fPIC -D MODULE_INTERFACE_VERSION_CURRENT=$(MODULE_INTERFACE_VERSION)
##
## cross compiled hashcat
##
obj/%.LINUX.o: src/%.c
$(CC_LINUX) $(CFLAGS_CROSS_LINUX) -c -o $@ $<
$(CC_LINUX) $(CCFLAGS) $(CFLAGS_CROSS_LINUX) -c -o $@ $<
obj/%.WIN.o: src/%.c
$(CC_WIN) $(CFLAGS_CROSS_WIN) -c -o $@ $<
$(CC_WIN) $(CCFLAGS) $(CFLAGS_CROSS_WIN) -c -o $@ $<
ifeq ($(USE_SYSTEM_LZMA),0)
obj/%.LINUX.o: $(DEPS_LZMA_PATH)/%.c
$(CC_LINUX) $(CFLAGS_CROSS_LINUX) -c -o $@ $<
$(CC_LINUX) $(CCFLAGS) $(CFLAGS_CROSS_LINUX) -c -o $@ $<
obj/%.WIN.o: $(DEPS_LZMA_PATH)/%.c
$(CC_WIN) $(CFLAGS_CROSS_WIN) -c -o $@ $<
$(CC_WIN) $(CCFLAGS) $(CFLAGS_CROSS_WIN) -c -o $@ $<
endif
ifeq ($(USE_SYSTEM_ZLIB),0)
obj/%.LINUX.o: $(DEPS_ZLIB_PATH)/%.c
$(CC_LINUX) $(CFLAGS_CROSS_LINUX) $(CFLAGS_ZLIB) -c -o $@ $<
$(CC_LINUX) $(CCFLAGS) $(CFLAGS_CROSS_LINUX) $(CFLAGS_ZLIB) -c -o $@ $<
obj/%.WIN.o: $(DEPS_ZLIB_PATH)/%.c
$(CC_WIN) $(CFLAGS_CROSS_WIN) $(CFLAGS_ZLIB) -c -o $@ $<
$(CC_WIN) $(CCFLAGS) $(CFLAGS_CROSS_WIN) $(CFLAGS_ZLIB) -c -o $@ $<
endif
ifeq ($(USE_SYSTEM_XXHASH),0)
ifeq ($(ENABLE_BRAIN),1)
obj/%.LINUX.o: $(DEPS_XXHASH_PATH)/%.c
$(CC_LINUX) $(CFLAGS_CROSS_LINUX) -c -o $@ $<
$(CC_LINUX) $(CCFLAGS) $(CFLAGS_CROSS_LINUX) -c -o $@ $<
obj/%.WIN.o: $(DEPS_XXHASH_PATH)/%.c
$(CC_WIN) $(CFLAGS_CROSS_WIN) -c -o $@ $<
$(CC_WIN) $(CCFLAGS) $(CFLAGS_CROSS_WIN) -c -o $@ $<
endif
endif
ifeq ($(USE_SYSTEM_UNRAR),0)
obj/%.LINUX.o: $(DEPS_UNRAR_PATH)/%.cpp
$(CXX_LINUX) $(CXXFLAGS) $(CFLAGS_CROSS_LINUX) $(CFLAGS_UNRAR) -c -o $@ $<
obj/%.WIN.o: $(DEPS_UNRAR_PATH)/%.cpp
$(CXX_WIN) $(CXXFLAGS) $(CFLAGS_CROSS_WIN) $(CFLAGS_UNRAR) -c -o $@ $<
endif
obj/combined.LINUX.a: $(LINUX_OBJS)
@ -665,12 +729,12 @@ obj/combined.WIN.a: $(WIN_OBJS)
$(AR_WIN) rcs $@ $^
hashcat.bin: src/main.c obj/combined.LINUX.a
$(CC_LINUX) $(CFLAGS_CROSS_LINUX) -o $@ $^ $(LFLAGS_CROSS_LINUX) -DCOMPTIME=$(COMPTIME) -DVERSION_TAG=\"$(VERSION_TAG)\" -DINSTALL_FOLDER=\"$(INSTALL_FOLDER)\" -DSHARED_FOLDER=\"$(SHARED_FOLDER)\" -DDOCUMENT_FOLDER=\"$(DOCUMENT_FOLDER)\"
$(CC_LINUX) $(CCFLAGS) $(CFLAGS_CROSS_LINUX) -o $@ $^ $(LFLAGS_CROSS_LINUX) -DCOMPTIME=$(COMPTIME) -DVERSION_TAG=\"$(VERSION_TAG)\" -DINSTALL_FOLDER=\"$(INSTALL_FOLDER)\" -DSHARED_FOLDER=\"$(SHARED_FOLDER)\" -DDOCUMENT_FOLDER=\"$(DOCUMENT_FOLDER)\"
hashcat.exe: src/main.c obj/combined.WIN.a $(WIN_ICONV)/lib/libiconv.a
$(CC_WIN) $(CFLAGS_CROSS_WIN) -o $@ $^ $(LFLAGS_CROSS_WIN) -DCOMPTIME=$(COMPTIME) -DVERSION_TAG=\"$(VERSION_TAG)\"
$(CC_WIN) $(CCFLAGS) $(CFLAGS_CROSS_WIN) -o $@ $^ $(LFLAGS_CROSS_WIN) -DCOMPTIME=$(COMPTIME) -DVERSION_TAG=\"$(VERSION_TAG)\"
hashcat.dll: src/main.c obj/combined.WIN.a $(WIN_ICONV)/lib/libiconv.a
$(CC_WIN) $(CFLAGS_CROSS_WIN) -o $@ $^ $(LFLAGS_CROSS_WIN) -DCOMPTIME=$(COMPTIME) -DVERSION_TAG=\"$(VERSION_TAG)\" -shared
$(CC_WIN) $(CCFLAGS) $(CFLAGS_CROSS_WIN) -o $@ $^ $(LFLAGS_CROSS_WIN) -DCOMPTIME=$(COMPTIME) -DVERSION_TAG=\"$(VERSION_TAG)\" -shared
endif

@ -0,0 +1,397 @@
/**
* Author......: See docs/credits.txt
* License.....: MIT
*/
#include "common.h"
#include "types.h"
#include "modules.h"
#include "bitops.h"
#include "convert.h"
#include "shared.h"
static const u32 ATTACK_EXEC = ATTACK_EXEC_OUTSIDE_KERNEL;
static const u32 DGST_POS0 = 0;
static const u32 DGST_POS1 = 1;
static const u32 DGST_POS2 = 2;
static const u32 DGST_POS3 = 3;
static const u32 DGST_SIZE = DGST_SIZE_4_4; // actually only DGST_SIZE_4_1
static const u32 HASH_CATEGORY = HASH_CATEGORY_ARCHIVE;
static const char *HASH_NAME = "RAR3-p (Uncompressed)";
static const u64 KERN_TYPE = 23700;
static const u32 OPTI_TYPE = OPTI_TYPE_ZERO_BYTE;
static const u64 OPTS_TYPE = OPTS_TYPE_PT_GENERATE_LE;
static const u32 SALT_TYPE = SALT_TYPE_EMBEDDED;
static const char *ST_PASS = "hashcat";
static const char *ST_HASH = "$RAR3$*1*e54a73729887cb53*49b0a846*16*14*1*34620bcca8176642a210b1051901921e*30";
u32 module_attack_exec (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return ATTACK_EXEC; }
u32 module_dgst_pos0 (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return DGST_POS0; }
u32 module_dgst_pos1 (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return DGST_POS1; }
u32 module_dgst_pos2 (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return DGST_POS2; }
u32 module_dgst_pos3 (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return DGST_POS3; }
u32 module_dgst_size (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return DGST_SIZE; }
u32 module_hash_category (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return HASH_CATEGORY; }
const char *module_hash_name (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return HASH_NAME; }
u64 module_kern_type (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return KERN_TYPE; }
u32 module_opti_type (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return OPTI_TYPE; }
u64 module_opts_type (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return OPTS_TYPE; }
u32 module_salt_type (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return SALT_TYPE; }
const char *module_st_hash (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return ST_HASH; }
const char *module_st_pass (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return ST_PASS; }
typedef struct rar3
{
u32 data[81920];
u32 pack_size;
u32 unpack_size;
} rar3_t;
typedef struct rar3_tmp
{
u32 dgst[5];
u32 w[66]; // 256 byte pass + 8 byte salt
u32 iv[4];
} rar3_tmp_t;
typedef struct rar3_tmp_optimized
{
u32 dgst[17][5];
} rar3_tmp_optimized_t;
static const int ROUNDS_RAR3 = 262144;
static const char *SIGNATURE_RAR3 = "$RAR3$";
u64 module_tmp_size (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra)
{
const bool optimized_kernel = user_options->optimized_kernel_enable;
u64 tmp_size = (u64) sizeof (rar3_tmp_t);
if (optimized_kernel == true)
{
tmp_size = (u64) sizeof (rar3_tmp_optimized_t);
}
return tmp_size;
}
u64 module_esalt_size (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra)
{
u64 esalt_size = (u64) sizeof (rar3_t);
return esalt_size;
}
u32 module_kernel_loops_min (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra)
{
const u32 kernel_loops_min = ROUNDS_RAR3 / 16;
return kernel_loops_min;
}
u32 module_kernel_loops_max (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra)
{
const u32 kernel_loops_max = ROUNDS_RAR3 / 16;
return kernel_loops_max;
}
u32 module_kernel_threads_max (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra)
{
// -T 128 works slightly faster but it's free for the user to change
const u32 kernel_threads_max = (user_options->kernel_threads_chgd == true) ? user_options->kernel_threads : 128;
return kernel_threads_max;
}
u32 module_pw_max (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra)
{
const bool optimized_kernel = (hashconfig->opti_type & OPTI_TYPE_OPTIMIZED_KERNEL);
u32 pw_max = 127;
if (optimized_kernel == true)
{
pw_max = 20;
}
return pw_max;
}
const char *module_benchmark_mask (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra)
{
const char *mask = "?b?b?b?b?b";
return mask;
}
int module_hash_decode (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED void *digest_buf, MAYBE_UNUSED salt_t *salt, MAYBE_UNUSED void *esalt_buf, MAYBE_UNUSED void *hook_salt_buf, MAYBE_UNUSED hashinfo_t *hash_info, const char *line_buf, MAYBE_UNUSED const int line_len)
{
u32 *digest = (u32 *) digest_buf;
rar3_t *rar3 = (rar3_t *) esalt_buf;
token_t token;
token.token_cnt = 9;
token.signatures_cnt = 1;
token.signatures_buf[0] = SIGNATURE_RAR3;
token.sep[0] = '*';
token.len_min[0] = 6;
token.len_max[0] = 6;
token.attr[0] = TOKEN_ATTR_VERIFY_LENGTH
| TOKEN_ATTR_VERIFY_SIGNATURE;
token.sep[1] = '*';
token.len_min[1] = 1;
token.len_max[1] = 1;
token.attr[1] = TOKEN_ATTR_VERIFY_LENGTH
| TOKEN_ATTR_VERIFY_DIGIT;
token.sep[2] = '*';
token.len_min[2] = 16;
token.len_max[2] = 16;
token.attr[2] = TOKEN_ATTR_VERIFY_LENGTH
| TOKEN_ATTR_VERIFY_HEX;
token.sep[3] = '*';
token.len_min[3] = 8;
token.len_max[3] = 8;
token.attr[3] = TOKEN_ATTR_VERIFY_LENGTH
| TOKEN_ATTR_VERIFY_HEX;
token.sep[4] = '*';
token.len_min[4] = 1;
token.len_max[4] = 7;
token.attr[4] = TOKEN_ATTR_VERIFY_LENGTH
| TOKEN_ATTR_VERIFY_DIGIT;
token.sep[5] = '*';
token.len_min[5] = 1;
token.len_max[5] = 6;
token.attr[5] = TOKEN_ATTR_VERIFY_LENGTH
| TOKEN_ATTR_VERIFY_DIGIT;
token.sep[6] = '*';
token.len_min[6] = 1;
token.len_max[6] = 1;
token.attr[6] = TOKEN_ATTR_VERIFY_LENGTH
| TOKEN_ATTR_VERIFY_DIGIT;
token.sep[7] = '*';
token.len_min[7] = 2;
token.len_max[7] = 655056;
token.attr[7] = TOKEN_ATTR_VERIFY_LENGTH
| TOKEN_ATTR_VERIFY_HEX;
token.len[8] = 2;
token.attr[8] = TOKEN_ATTR_FIXED_LENGTH
| TOKEN_ATTR_VERIFY_DIGIT;
const int rc_tokenizer = input_tokenizer ((const u8 *) line_buf, line_len, &token);
if (rc_tokenizer != PARSER_OK) return (rc_tokenizer);
const u8 *type_pos = token.buf[1];
if (type_pos[0] != '1') return (PARSER_SIGNATURE_UNMATCHED);
// salt
const u8 *salt_pos = token.buf[2];
salt->salt_buf[0] = hex_to_u32 (salt_pos + 0);
salt->salt_buf[1] = hex_to_u32 (salt_pos + 8);
salt->salt_len = 8;
salt->salt_iter = ROUNDS_RAR3;
// CRC32
const u8 *crc32_pos = token.buf[3];
u32 crc32_sum = hex_to_u32 (crc32_pos);
// pack size
const u8 *pack_size_pos = token.buf[4];
const u32 pack_size = hc_strtoul ((const char *) pack_size_pos, NULL, 10);
if (pack_size < 1) return (PARSER_SALT_VALUE);
if (pack_size > 327680) return (PARSER_SALT_VALUE);
if ((pack_size % 16) != 0) return (PARSER_SALT_VALUE);
rar3->pack_size = pack_size;
// unpack size
const u8 *unpack_size_pos = token.buf[5];
const u32 unpack_size = hc_strtoul ((const char *) unpack_size_pos, NULL, 10);
if (unpack_size < 1) return (PARSER_SALT_VALUE);
if (unpack_size > 655360) return (PARSER_SALT_VALUE);
if (unpack_size > pack_size) return (PARSER_SALT_VALUE);
rar3->unpack_size = unpack_size;
// data is within the hash line
const u8 *is_data_pos = token.buf[6];
if (is_data_pos[0] != '1') return (PARSER_SALT_VALUE);
// data
const u8 *data_pos = token.buf[7];
const u32 data_len = token.len[7];
if (data_len != (pack_size * 2)) return (PARSER_SALT_VALUE);
// like hex decode, but swapped:
// hex_decode (data_pos, data_len, (u8 *) rar3->data);
for (u32 i = 0, j = 0; i < data_len; i += 8, j++)
{
rar3->data[j] = hex_to_u32 (data_pos + i);
rar3->data[j] = byte_swap_32 (rar3->data[j]);
}
// method
const u8 *method_pos = token.buf[8];
const u32 method = hc_strtoul ((const char *) method_pos, NULL, 10);
if (method != 30) return (PARSER_SALT_VALUE);
// digest
digest[0] = crc32_sum ^ 0xffffffff;
digest[1] = 0;
digest[2] = 0;
digest[3] = 0;
return (PARSER_OK);
}
int module_hash_encode (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const void *digest_buf, MAYBE_UNUSED const salt_t *salt, MAYBE_UNUSED const void *esalt_buf, MAYBE_UNUSED const void *hook_salt_buf, MAYBE_UNUSED const hashinfo_t *hash_info, char *line_buf, MAYBE_UNUSED const int line_size)
{
const u32 *digest = (const u32 *) digest_buf;
const rar3_t *rar3 = (const rar3_t *) esalt_buf;
u8 data[655360] = { 0 };
const u32 data_len = rar3->pack_size;
// like hex encode, but swapped:
// hex_encode ((const u8 *) rar3->data, rar3->pack_size, data);
for (u32 i = 0, j = 0; i < data_len / 4; i += 1, j += 8)
{
const u32 d = byte_swap_32 (rar3->data[i]);
u32_to_hex (d, data + j);
}
const int line_len = snprintf (line_buf, line_size, "%s*1*%08x%08x*%08x*%u*%u*1*%s*30",
SIGNATURE_RAR3,
byte_swap_32 (salt->salt_buf[0]),
byte_swap_32 (salt->salt_buf[1]),
byte_swap_32 (digest[0]) ^ 0xffffffff,
rar3->pack_size,
rar3->unpack_size,
data);
return line_len;
}
void module_init (module_ctx_t *module_ctx)
{
module_ctx->module_context_size = MODULE_CONTEXT_SIZE_CURRENT;
module_ctx->module_interface_version = MODULE_INTERFACE_VERSION_CURRENT;
module_ctx->module_attack_exec = module_attack_exec;
module_ctx->module_benchmark_esalt = MODULE_DEFAULT;
module_ctx->module_benchmark_hook_salt = MODULE_DEFAULT;
module_ctx->module_benchmark_mask = module_benchmark_mask;
module_ctx->module_benchmark_salt = MODULE_DEFAULT;
module_ctx->module_build_plain_postprocess = MODULE_DEFAULT;
module_ctx->module_deep_comp_kernel = MODULE_DEFAULT;
module_ctx->module_dgst_pos0 = module_dgst_pos0;
module_ctx->module_dgst_pos1 = module_dgst_pos1;
module_ctx->module_dgst_pos2 = module_dgst_pos2;
module_ctx->module_dgst_pos3 = module_dgst_pos3;
module_ctx->module_dgst_size = module_dgst_size;
module_ctx->module_dictstat_disable = MODULE_DEFAULT;
module_ctx->module_esalt_size = module_esalt_size;
module_ctx->module_extra_buffer_size = MODULE_DEFAULT;
module_ctx->module_extra_tmp_size = MODULE_DEFAULT;
module_ctx->module_forced_outfile_format = MODULE_DEFAULT;
module_ctx->module_hash_binary_count = MODULE_DEFAULT;
module_ctx->module_hash_binary_parse = MODULE_DEFAULT;
module_ctx->module_hash_binary_save = MODULE_DEFAULT;
module_ctx->module_hash_decode_potfile = MODULE_DEFAULT;
module_ctx->module_hash_decode_zero_hash = MODULE_DEFAULT;
module_ctx->module_hash_decode = module_hash_decode;
module_ctx->module_hash_encode_status = MODULE_DEFAULT;
module_ctx->module_hash_encode_potfile = MODULE_DEFAULT;
module_ctx->module_hash_encode = module_hash_encode;
module_ctx->module_hash_init_selftest = MODULE_DEFAULT;
module_ctx->module_hash_mode = MODULE_DEFAULT;
module_ctx->module_hash_category = module_hash_category;
module_ctx->module_hash_name = module_hash_name;
module_ctx->module_hashes_count_min = MODULE_DEFAULT;
module_ctx->module_hashes_count_max = MODULE_DEFAULT;
module_ctx->module_hlfmt_disable = MODULE_DEFAULT;
module_ctx->module_hook_extra_param_size = MODULE_DEFAULT;
module_ctx->module_hook_extra_param_init = MODULE_DEFAULT;
module_ctx->module_hook_extra_param_term = MODULE_DEFAULT;
module_ctx->module_hook12 = MODULE_DEFAULT;
module_ctx->module_hook23 = MODULE_DEFAULT;
module_ctx->module_hook_salt_size = MODULE_DEFAULT;
module_ctx->module_hook_size = MODULE_DEFAULT;
module_ctx->module_jit_build_options = MODULE_DEFAULT;
module_ctx->module_jit_cache_disable = MODULE_DEFAULT;
module_ctx->module_kernel_accel_max = MODULE_DEFAULT;
module_ctx->module_kernel_accel_min = MODULE_DEFAULT;
module_ctx->module_kernel_loops_max = module_kernel_loops_max;
module_ctx->module_kernel_loops_min = module_kernel_loops_min;
module_ctx->module_kernel_threads_max = module_kernel_threads_max;
module_ctx->module_kernel_threads_min = MODULE_DEFAULT;
module_ctx->module_kern_type = module_kern_type;
module_ctx->module_kern_type_dynamic = MODULE_DEFAULT;
module_ctx->module_opti_type = module_opti_type;
module_ctx->module_opts_type = module_opts_type;
module_ctx->module_outfile_check_disable = MODULE_DEFAULT;
module_ctx->module_outfile_check_nocomp = MODULE_DEFAULT;
module_ctx->module_potfile_custom_check = MODULE_DEFAULT;
module_ctx->module_potfile_disable = MODULE_DEFAULT;
module_ctx->module_potfile_keep_all_hashes = MODULE_DEFAULT;
module_ctx->module_pwdump_column = MODULE_DEFAULT;
module_ctx->module_pw_max = module_pw_max;
module_ctx->module_pw_min = MODULE_DEFAULT;
module_ctx->module_salt_max = MODULE_DEFAULT;
module_ctx->module_salt_min = MODULE_DEFAULT;
module_ctx->module_salt_type = module_salt_type;
module_ctx->module_separator = MODULE_DEFAULT;
module_ctx->module_st_hash = module_st_hash;
module_ctx->module_st_pass = module_st_pass;
module_ctx->module_tmp_size = module_tmp_size;
module_ctx->module_unstable_warning = MODULE_DEFAULT;
module_ctx->module_warmup_disable = MODULE_DEFAULT;
}

@ -0,0 +1,663 @@
/**
* Author......: See docs/credits.txt
* License.....: MIT
*/
#include "common.h"
#include "types.h"
#include "modules.h"
#include "bitops.h"
#include "convert.h"
#include "shared.h"
#include "memory.h"
static const u32 ATTACK_EXEC = ATTACK_EXEC_OUTSIDE_KERNEL;
static const u32 DGST_POS0 = 0;
static const u32 DGST_POS1 = 1;
static const u32 DGST_POS2 = 2;
static const u32 DGST_POS3 = 3;
static const u32 DGST_SIZE = DGST_SIZE_4_4; // actually only DGST_SIZE_4_1
static const u32 HASH_CATEGORY = HASH_CATEGORY_ARCHIVE;
static const char *HASH_NAME = "RAR3-p (Compressed)";
static const u64 KERN_TYPE = 23800;
static const u32 OPTI_TYPE = OPTI_TYPE_ZERO_BYTE;
static const u64 OPTS_TYPE = OPTS_TYPE_PT_GENERATE_LE
| OPTS_TYPE_HOOK23;
static const u32 SALT_TYPE = SALT_TYPE_EMBEDDED;
static const char *ST_PASS = "hashcat";
static const char *ST_HASH = "$RAR3$*1*ad56eb40219c9da2*834064ce*32*13*1*eb47b1abe17a1a75bce6c92ab1cef3f4126035ea95deaf08b3f32a0c7b8078e1*33";
u32 module_attack_exec (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return ATTACK_EXEC; }
u32 module_dgst_pos0 (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return DGST_POS0; }
u32 module_dgst_pos1 (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return DGST_POS1; }
u32 module_dgst_pos2 (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return DGST_POS2; }
u32 module_dgst_pos3 (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return DGST_POS3; }
u32 module_dgst_size (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return DGST_SIZE; }
u32 module_hash_category (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return HASH_CATEGORY; }
const char *module_hash_name (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return HASH_NAME; }
u64 module_kern_type (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return KERN_TYPE; }
u32 module_opti_type (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return OPTI_TYPE; }
u64 module_opts_type (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return OPTS_TYPE; }
u32 module_salt_type (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return SALT_TYPE; }
const char *module_st_hash (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return ST_HASH; }
const char *module_st_pass (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return ST_PASS; }
typedef struct rar3
{
u32 first_block_encrypted[4];
} rar3_t;
typedef struct rar3_tmp
{
u32 dgst[5];
u32 w[66]; // 256 byte pass + 8 byte salt
u32 iv[4];
} rar3_tmp_t;
typedef struct rar3_tmp_optimized
{
u32 dgst[17][5];
} rar3_tmp_optimized_t;
typedef struct rar3_hook
{
u32 key[4];
u32 iv[4];
u32 first_block_decrypted[4];
u32 crc32;
} rar3_hook_t;
typedef struct rar3_hook_salt
{
u32 data[81920];
u32 pack_size;
u32 unpack_size;
u32 method;
} rar3_hook_salt_t;
typedef struct rar3_hook_extra
{
void **win;
void **inp;
void **vm;
void **ppm;
} rar3_hook_extra_t;
static const int ROUNDS_RAR3 = 262144;
static const char *SIGNATURE_RAR3 = "$RAR3$";
#define ADD_BITS(n) \
{ \
if (bits < 9) \
{ \
hold |= ((unsigned int) *next++ << (24 - bits)); \
bits += 8; \
} \
\
hold <<= n; \
bits -= n; \
}
/*
* The following function was implemented similar to the check_huffman ()
* function from John The Ripper.
* Thanks go to magnum and JTR for the permission.
*/
static int check_huffman (const unsigned char *next)
{
unsigned int bits;
unsigned int hold;
unsigned int i;
int left;
unsigned int ncount[4];
unsigned char *count = (unsigned char*) ncount;
unsigned char bit_length[20];
hold = next[3]
+ (((unsigned int) next[2]) << 8)
+ (((unsigned int) next[1]) << 16)
+ (((unsigned int) next[0]) << 24);
next += 4; // we already have the first 32 bits
hold <<= 2; // we already processed 2 bits, PPM and keepOldTable
bits = 32 - 2;
/* First, read 20 pairs of (bitlength[, zerocount]) */
for (i = 0; i < 20; i++)
{
int length, zero_count;
length = hold >> 28;
ADD_BITS (4);
if (length == 15)
{
zero_count = hold >> 28;
ADD_BITS (4);
if (zero_count == 0)
{
bit_length[i] = 15;
}
else
{
zero_count += 2;
while (zero_count-- > 0 && i < sizeof(bit_length) / sizeof (bit_length[0]))
{
bit_length[i++] = 0;
}
i--;
}
}
else
{
bit_length[i] = length;
}
}
/* Count the number of codes for each code length */
memset (count, 0, 16);
for (i = 0; i < 20; i++)
{
++count[bit_length[i]];
}
count[0] = 0;
if (!ncount[0] && !ncount[1] && !ncount[2] && !ncount[3]) return 0; /* No codes at all */
left = 1;
for (i = 1; i < 16; ++i)
{
left <<= 1;
left -= count[i];
if (left < 0) return 0; /* over-subscribed */
}
if (left) return 0; /* incomplete set */
return 1; /* Passed this check! */
}
bool module_hook_extra_param_init (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra, MAYBE_UNUSED const folder_config_t *folder_config, MAYBE_UNUSED const backend_ctx_t *backend_ctx, void *hook_extra_param)
{
rar3_hook_extra_t *rar3_hook_extra = (rar3_hook_extra_t *) hook_extra_param;
#define WINSIZE 0x100000
#define INPSIZE 0x50000
#define PPMSIZE 216 * 1024 * 1024
rar3_hook_extra->win = hccalloc (backend_ctx->backend_devices_cnt, sizeof (void *));
if (rar3_hook_extra->win == NULL) return false;
rar3_hook_extra->inp = hccalloc (backend_ctx->backend_devices_cnt, sizeof (void *));
if (rar3_hook_extra->inp == NULL) return false;
rar3_hook_extra->vm = hccalloc (backend_ctx->backend_devices_cnt, sizeof (void *));
if (rar3_hook_extra->vm == NULL) return false;
rar3_hook_extra->ppm = hccalloc (backend_ctx->backend_devices_cnt, sizeof (void *));
if (rar3_hook_extra->ppm == NULL) return false;
for (int backend_devices_idx = 0; backend_devices_idx < backend_ctx->backend_devices_cnt; backend_devices_idx++)
{
hc_device_param_t *device_param = &backend_ctx->devices_param[backend_devices_idx];
if (device_param->skipped == true) continue;
rar3_hook_extra->win[backend_devices_idx] = hcmalloc (WINSIZE);
if (rar3_hook_extra->win[backend_devices_idx] == NULL) return false;
rar3_hook_extra->inp[backend_devices_idx] = hcmalloc (INPSIZE);
if (rar3_hook_extra->inp[backend_devices_idx] == NULL) return false;
rar3_hook_extra->vm [backend_devices_idx] = hcmalloc (INPSIZE);
if (rar3_hook_extra->vm [backend_devices_idx] == NULL) return false;
rar3_hook_extra->ppm[backend_devices_idx] = hcmalloc (PPMSIZE);
if (rar3_hook_extra->ppm[backend_devices_idx] == NULL) return false;
}
return true;
}
bool module_hook_extra_param_term (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra, MAYBE_UNUSED const folder_config_t *folder_config, MAYBE_UNUSED const backend_ctx_t *backend_ctx, void *hook_extra_param)
{
rar3_hook_extra_t *rar3_hook_extra = (rar3_hook_extra_t *) hook_extra_param;
for (int backend_devices_idx = 0; backend_devices_idx < backend_ctx->backend_devices_cnt; backend_devices_idx++)
{
hc_device_param_t *device_param = &backend_ctx->devices_param[backend_devices_idx];
if (device_param->skipped == true) continue;
hcfree (rar3_hook_extra->ppm[backend_devices_idx]);
hcfree (rar3_hook_extra->win[backend_devices_idx]);
hcfree (rar3_hook_extra->inp[backend_devices_idx]);
hcfree (rar3_hook_extra->vm [backend_devices_idx]);
}
hcfree (rar3_hook_extra->win);
hcfree (rar3_hook_extra->inp);
hcfree (rar3_hook_extra->vm);
return true;
}
unsigned int hc_decompress_rar (unsigned char *Win, unsigned char *Inp, unsigned char *VM, unsigned char *PPM, const unsigned int OutputSize, const unsigned char *Input, const unsigned int PackSize, const unsigned int UnpackSize, const unsigned char *Key, const unsigned char *IV);
void module_hook23 (hc_device_param_t *device_param, const void *hook_extra_param, const void *hook_salts_buf, const u32 salt_pos, const u64 pw_pos)
{
rar3_hook_t *hook_items = (rar3_hook_t *) device_param->hooks_buf;
rar3_hook_t *hook_item = &hook_items[pw_pos];
rar3_hook_salt_t *rar3s = (rar3_hook_salt_t *) hook_salts_buf;
rar3_hook_salt_t *rar3 = &rar3s[salt_pos];
rar3_hook_extra_t *rar3_hook_extra = (rar3_hook_extra_t *) hook_extra_param;
const unsigned int pack_size = (const unsigned int) rar3->pack_size;
const unsigned int unpack_size = (const unsigned int) rar3->unpack_size;
const u8 *first_block_decrypted = (const u8 *) hook_item->first_block_decrypted;
/* Early rejection */
if (first_block_decrypted[0] & 0x80)
{
// PPM checks here.
if (((first_block_decrypted[0] & 0x20) == 0) // Reset bit must be set
|| (first_block_decrypted[1] & 0x80)) // MaxMB must be < 128
{
return;
}
}
else
{
// LZ checks here.
if ((first_block_decrypted[0] & 0x40) // KeepOldTable can't be set
|| (check_huffman (first_block_decrypted)) == 0) // Huffman table check
{
return;
}
}
const u8 *data = (u8 *) rar3->data;
const u8 *key = (u8 *) hook_item->key;
const u8 *iv = (u8 *) hook_item->iv;
const u32 crc32 = hc_decompress_rar (rar3_hook_extra->win[device_param->device_id], rar3_hook_extra->inp[device_param->device_id], rar3_hook_extra->vm[device_param->device_id], rar3_hook_extra->ppm[device_param->device_id], unpack_size, data, pack_size, unpack_size, key, iv);
hook_item->crc32 = crc32;
}
u64 module_hook_size (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra)
{
const u64 hook_size = (const u64) sizeof (rar3_hook_t);
return hook_size;
}
u64 module_hook_salt_size (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra)
{
const u64 hook_salt_size = (const u64) sizeof (rar3_hook_salt_t);
return hook_salt_size;
}
u64 module_hook_extra_param_size (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra)
{
const u64 hook_extra_param_size = (const u64) sizeof (rar3_hook_extra_t);
return hook_extra_param_size;
}
u64 module_tmp_size (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra)
{
const bool optimized_kernel = user_options->optimized_kernel_enable;
u64 tmp_size = (u64) sizeof (rar3_tmp_t);
if (optimized_kernel == true)
{
tmp_size = (u64) sizeof (rar3_tmp_optimized_t);
}
return tmp_size;
}
u64 module_esalt_size (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra)
{
u64 esalt_size = (u64) sizeof (rar3_t);
return esalt_size;
}
u32 module_kernel_loops_min (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra)
{
const u32 kernel_loops_min = ROUNDS_RAR3 / 16;
return kernel_loops_min;
}
u32 module_kernel_loops_max (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra)
{
const u32 kernel_loops_max = ROUNDS_RAR3 / 16;
return kernel_loops_max;
}
u32 module_kernel_threads_max (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra)
{
// -T 128 works slightly faster but it's free for the user to change
const u32 kernel_threads_max = (user_options->kernel_threads_chgd == true) ? user_options->kernel_threads : 128;
return kernel_threads_max;
}
u32 module_pw_max (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra)
{
const bool optimized_kernel = (hashconfig->opti_type & OPTI_TYPE_OPTIMIZED_KERNEL);
u32 pw_max = 127;
if (optimized_kernel == true)
{
pw_max = 20;
}
return pw_max;
}
const char *module_benchmark_mask (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra)
{
const char *mask = "?b?b?b?b?b";
return mask;
}
int module_hash_decode (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED void *digest_buf, MAYBE_UNUSED salt_t *salt, MAYBE_UNUSED void *esalt_buf, MAYBE_UNUSED void *hook_salt_buf, MAYBE_UNUSED hashinfo_t *hash_info, const char *line_buf, MAYBE_UNUSED const int line_len)
{
u32 *digest = (u32 *) digest_buf;
rar3_t *rar3 = (rar3_t *) esalt_buf;
rar3_hook_salt_t *rar3_hook_salt = (rar3_hook_salt_t *) hook_salt_buf;
token_t token;
token.token_cnt = 9;
token.signatures_cnt = 1;
token.signatures_buf[0] = SIGNATURE_RAR3;
token.sep[0] = '*';
token.len_min[0] = 6;
token.len_max[0] = 6;
token.attr[0] = TOKEN_ATTR_VERIFY_LENGTH
| TOKEN_ATTR_VERIFY_SIGNATURE;
token.sep[1] = '*';
token.len_min[1] = 1;
token.len_max[1] = 1;
token.attr[1] = TOKEN_ATTR_VERIFY_LENGTH
| TOKEN_ATTR_VERIFY_DIGIT;
token.sep[2] = '*';
token.len_min[2] = 16;
token.len_max[2] = 16;
token.attr[2] = TOKEN_ATTR_VERIFY_LENGTH
| TOKEN_ATTR_VERIFY_HEX;
token.sep[3] = '*';
token.len_min[3] = 8;
token.len_max[3] = 8;
token.attr[3] = TOKEN_ATTR_VERIFY_LENGTH
| TOKEN_ATTR_VERIFY_HEX;
token.sep[4] = '*';
token.len_min[4] = 1;
token.len_max[4] = 7;
token.attr[4] = TOKEN_ATTR_VERIFY_LENGTH
| TOKEN_ATTR_VERIFY_DIGIT;
token.sep[5] = '*';
token.len_min[5] = 1;
token.len_max[5] = 6;
token.attr[5] = TOKEN_ATTR_VERIFY_LENGTH
| TOKEN_ATTR_VERIFY_DIGIT;
token.sep[6] = '*';
token.len_min[6] = 1;
token.len_max[6] = 1;
token.attr[6] = TOKEN_ATTR_VERIFY_LENGTH
| TOKEN_ATTR_VERIFY_DIGIT;
token.sep[7] = '*';
token.len_min[7] = 2;
token.len_max[7] = 655056;
token.attr[7] = TOKEN_ATTR_VERIFY_LENGTH
| TOKEN_ATTR_VERIFY_HEX;
token.len[8] = 2;
token.attr[8] = TOKEN_ATTR_FIXED_LENGTH
| TOKEN_ATTR_VERIFY_DIGIT;
const int rc_tokenizer = input_tokenizer ((const u8 *) line_buf, line_len, &token);
if (rc_tokenizer != PARSER_OK) return (rc_tokenizer);
const u8 *type_pos = token.buf[1];
if (type_pos[0] != '1') return (PARSER_SIGNATURE_UNMATCHED);
// salt
const u8 *salt_pos = token.buf[2];
salt->salt_buf[0] = hex_to_u32 (salt_pos + 0);
salt->salt_buf[1] = hex_to_u32 (salt_pos + 8);
salt->salt_len = 8;
salt->salt_iter = ROUNDS_RAR3;
// CRC32
const u8 *crc32_pos = token.buf[3];
u32 crc32_sum = hex_to_u32 (crc32_pos);
// pack size
const u8 *pack_size_pos = token.buf[4];
const u32 pack_size = hc_strtoul ((const char *) pack_size_pos, NULL, 10);
if (pack_size < 1) return (PARSER_SALT_VALUE);
if (pack_size > 327680) return (PARSER_SALT_VALUE);
if ((pack_size % 16) != 0) return (PARSER_SALT_VALUE);
rar3_hook_salt->pack_size = pack_size;
// unpack size
const u8 *unpack_size_pos = token.buf[5];
const u32 unpack_size = hc_strtoul ((const char *) unpack_size_pos, NULL, 10);
if (unpack_size < 1) return (PARSER_SALT_VALUE);
if (unpack_size > 655360) return (PARSER_SALT_VALUE);
rar3_hook_salt->unpack_size = unpack_size;
// data is within the hash line
const u8 *is_data_pos = token.buf[6];
if (is_data_pos[0] != '1') return (PARSER_SALT_VALUE);
// data
const u8 *data_pos = token.buf[7];
const u32 data_len = token.len[7];
if (data_len != (pack_size * 2)) return (PARSER_SALT_VALUE);
hex_decode (data_pos, data_len, (u8 *) rar3_hook_salt->data);
rar3->first_block_encrypted[0] = rar3_hook_salt->data[0];
rar3->first_block_encrypted[1] = rar3_hook_salt->data[1];
rar3->first_block_encrypted[2] = rar3_hook_salt->data[2];
rar3->first_block_encrypted[3] = rar3_hook_salt->data[3];
// method
const u8 *method_pos = token.buf[8];
const u32 method = hc_strtoul ((const char *) method_pos, NULL, 10);
if (method < 31) return (PARSER_SALT_VALUE);
if (method > 35) return (PARSER_SALT_VALUE);
rar3_hook_salt->method = method;
// digest
digest[0] = crc32_sum;
digest[1] = 0;
digest[2] = 0;
digest[3] = 0;
return (PARSER_OK);
}
int module_hash_encode (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const void *digest_buf, MAYBE_UNUSED const salt_t *salt, MAYBE_UNUSED const void *esalt_buf, MAYBE_UNUSED const void *hook_salt_buf, MAYBE_UNUSED const hashinfo_t *hash_info, char *line_buf, MAYBE_UNUSED const int line_size)
{
const u32 *digest = (const u32 *) digest_buf;
rar3_hook_salt_t *rar3_hook_salt = (rar3_hook_salt_t *) hook_salt_buf;
u8 data[655360] = { 0 };
const u32 data_len = rar3_hook_salt->pack_size;
hex_encode ((const u8 *) rar3_hook_salt->data, data_len, data);
const int line_len = snprintf (line_buf, line_size, "%s*1*%08x%08x*%08x*%u*%u*1*%s*%i",
SIGNATURE_RAR3,
byte_swap_32 (salt->salt_buf[0]),
byte_swap_32 (salt->salt_buf[1]),
byte_swap_32 (digest[0]),
rar3_hook_salt->pack_size,
rar3_hook_salt->unpack_size,
data,
rar3_hook_salt->method);
return line_len;
}
void module_init (module_ctx_t *module_ctx)
{
module_ctx->module_context_size = MODULE_CONTEXT_SIZE_CURRENT;
module_ctx->module_interface_version = MODULE_INTERFACE_VERSION_CURRENT;
module_ctx->module_attack_exec = module_attack_exec;
module_ctx->module_benchmark_esalt = MODULE_DEFAULT;
module_ctx->module_benchmark_hook_salt = MODULE_DEFAULT;
module_ctx->module_benchmark_mask = module_benchmark_mask;
module_ctx->module_benchmark_salt = MODULE_DEFAULT;
module_ctx->module_build_plain_postprocess = MODULE_DEFAULT;
module_ctx->module_deep_comp_kernel = MODULE_DEFAULT;
module_ctx->module_dgst_pos0 = module_dgst_pos0;
module_ctx->module_dgst_pos1 = module_dgst_pos1;
module_ctx->module_dgst_pos2 = module_dgst_pos2;
module_ctx->module_dgst_pos3 = module_dgst_pos3;
module_ctx->module_dgst_size = module_dgst_size;
module_ctx->module_dictstat_disable = MODULE_DEFAULT;
module_ctx->module_esalt_size = module_esalt_size;
module_ctx->module_extra_buffer_size = MODULE_DEFAULT;
module_ctx->module_extra_tmp_size = MODULE_DEFAULT;
module_ctx->module_forced_outfile_format = MODULE_DEFAULT;
module_ctx->module_hash_binary_count = MODULE_DEFAULT;
module_ctx->module_hash_binary_parse = MODULE_DEFAULT;
module_ctx->module_hash_binary_save = MODULE_DEFAULT;
module_ctx->module_hash_decode_potfile = MODULE_DEFAULT;
module_ctx->module_hash_decode_zero_hash = MODULE_DEFAULT;
module_ctx->module_hash_decode = module_hash_decode;
module_ctx->module_hash_encode_status = MODULE_DEFAULT;
module_ctx->module_hash_encode_potfile = MODULE_DEFAULT;
module_ctx->module_hash_encode = module_hash_encode;
module_ctx->module_hash_init_selftest = MODULE_DEFAULT;
module_ctx->module_hash_mode = MODULE_DEFAULT;
module_ctx->module_hash_category = module_hash_category;
module_ctx->module_hash_name = module_hash_name;
module_ctx->module_hashes_count_min = MODULE_DEFAULT;
module_ctx->module_hashes_count_max = MODULE_DEFAULT;
module_ctx->module_hlfmt_disable = MODULE_DEFAULT;
module_ctx->module_hook_extra_param_size = module_hook_extra_param_size;
module_ctx->module_hook_extra_param_init = module_hook_extra_param_init;
module_ctx->module_hook_extra_param_term = module_hook_extra_param_term;
module_ctx->module_hook12 = MODULE_DEFAULT;
module_ctx->module_hook23 = module_hook23;
module_ctx->module_hook_salt_size = module_hook_salt_size;
module_ctx->module_hook_size = module_hook_size;
module_ctx->module_jit_build_options = MODULE_DEFAULT;
module_ctx->module_jit_cache_disable = MODULE_DEFAULT;
module_ctx->module_kernel_accel_max = MODULE_DEFAULT;
module_ctx->module_kernel_accel_min = MODULE_DEFAULT;
module_ctx->module_kernel_loops_max = module_kernel_loops_max;
module_ctx->module_kernel_loops_min = module_kernel_loops_min;
module_ctx->module_kernel_threads_max = module_kernel_threads_max;
module_ctx->module_kernel_threads_min = MODULE_DEFAULT;
module_ctx->module_kern_type = module_kern_type;
module_ctx->module_kern_type_dynamic = MODULE_DEFAULT;
module_ctx->module_opti_type = module_opti_type;
module_ctx->module_opts_type = module_opts_type;
module_ctx->module_outfile_check_disable = MODULE_DEFAULT;
module_ctx->module_outfile_check_nocomp = MODULE_DEFAULT;
module_ctx->module_potfile_custom_check = MODULE_DEFAULT;
module_ctx->module_potfile_disable = MODULE_DEFAULT;
module_ctx->module_potfile_keep_all_hashes = MODULE_DEFAULT;
module_ctx->module_pwdump_column = MODULE_DEFAULT;
module_ctx->module_pw_max = module_pw_max;
module_ctx->module_pw_min = MODULE_DEFAULT;
module_ctx->module_salt_max = MODULE_DEFAULT;
module_ctx->module_salt_min = MODULE_DEFAULT;
module_ctx->module_salt_type = module_salt_type;
module_ctx->module_separator = MODULE_DEFAULT;
module_ctx->module_st_hash = module_st_hash;
module_ctx->module_st_pass = module_st_pass;
module_ctx->module_tmp_size = module_tmp_size;
module_ctx->module_unstable_warning = MODULE_DEFAULT;
module_ctx->module_warmup_disable = MODULE_DEFAULT;
}

@ -0,0 +1,496 @@
#!/usr/bin/env perl
##
## Author......: See docs/credits.txt
## License.....: MIT
##
use strict;
use warnings;
use Digest::SHA;
use Crypt::CBC;
use Encode;
use Digest::CRC qw (crc32);
sub module_constraints { [[0, 127], [8, 8], [0, 20], [8, 8], [-1, -1]] }
my $ITERATIONS = 0x40000;
my $FIXED_RAW_STRING = pack ("H*", "c43d7b00400700000000000000000000");
my $SHA1C00 = 0x5a827999;
my $SHA1C01 = 0x6ed9eba1;
my $SHA1C02 = 0x8f1bbcdc;
my $SHA1C03 = 0xca62c1d6;
my $SHA1M_A = 0x67452301;
my $SHA1M_B = 0xefcdab89;
my $SHA1M_C = 0x98badcfe;
my $SHA1M_D = 0x10325476;
my $SHA1M_E = 0xc3d2e1f0;
sub rotl32
{
my $x = shift;
my $n = shift;
return (($x << $n) | ($x >> (32 - $n))) & 0xffffffff;
}
sub blk
{
my $b = shift;
my $i = shift;
$$b[$i & 15] = rotl32 ($$b[($i + 13) & 15] ^
$$b[($i + 8) & 15] ^
$$b[($i + 2) & 15] ^
$$b[($i + 0) & 15], 1);
return $$b[$i & 15];
}
sub R0
{
my ($b, $v, $w, $x, $y, $z, $i) = @_;
$$b[$i] = unpack ("L<", pack ("L>", $$b[$i])); # blk0 or just swap_byte32 ()
$z += (($w & ($x ^ $y)) ^ $y) + $$b[$i] + $SHA1C00 + rotl32 ($v, 5);
$z &= 0xffffffff;
$w = rotl32 ($w, 30);
return ($z, $w);
}
sub R1
{
my ($b, $v, $w, $x, $y, $z, $i) = @_;
$z += (($w & ($x ^ $y)) ^ $y) + blk ($b, $i) + $SHA1C00 + rotl32 ($v, 5);
$z &= 0xffffffff;
$w = rotl32 ($w, 30);
return ($z, $w);
}
sub R2
{
my ($b, $v, $w, $x, $y, $z, $i) = @_;
$z += ($w ^ $x ^ $y) + blk ($b, $i) + $SHA1C01 + rotl32 ($v, 5);
$z &= 0xffffffff;
$w = rotl32 ($w, 30);
return ($z, $w);
}
sub R3
{
my ($b, $v, $w, $x, $y, $z, $i) = @_;
$z += ((($w | $x) & $y) | ($w & $x)) + blk ($b, $i) + $SHA1C02 + rotl32 ($v, 5);
$z &= 0xffffffff;
$w = rotl32 ($w, 30);
return ($z, $w);
}
sub R4
{
my ($b, $v, $w, $x, $y, $z, $i) = @_;
$z += ($w ^ $x ^ $y) + blk ($b, $i) + $SHA1C03 + rotl32 ($v, 5);
$z &= 0xffffffff;
$w = rotl32 ($w, 30);
return ($z, $w);
}
sub sha1_transform
{
my ($state, $buffer) = @_;
my @block = unpack ("L<*", $$buffer);
my $a = $$state[0];
my $b = $$state[1];
my $c = $$state[2];
my $d = $$state[3];
my $e = $$state[4];
($e, $b) = R0 (\@block, $a, $b, $c, $d, $e, 0);
($d, $a) = R0 (\@block, $e, $a, $b, $c, $d, 1);
($c, $e) = R0 (\@block, $d, $e, $a, $b, $c, 2);
($b, $d) = R0 (\@block, $c, $d, $e, $a, $b, 3);
($a, $c) = R0 (\@block, $b, $c, $d, $e, $a, 4);
($e, $b) = R0 (\@block, $a, $b, $c, $d, $e, 5);
($d, $a) = R0 (\@block, $e, $a, $b, $c, $d, 6);
($c, $e) = R0 (\@block, $d, $e, $a, $b, $c, 7);
($b, $d) = R0 (\@block, $c, $d, $e, $a, $b, 8);
($a, $c) = R0 (\@block, $b, $c, $d, $e, $a, 9);
($e, $b) = R0 (\@block, $a, $b, $c, $d, $e, 10);
($d, $a) = R0 (\@block, $e, $a, $b, $c, $d, 11);
($c, $e) = R0 (\@block, $d, $e, $a, $b, $c, 12);
($b, $d) = R0 (\@block, $c, $d, $e, $a, $b, 13);
($a, $c) = R0 (\@block, $b, $c, $d, $e, $a, 14);
($e, $b) = R0 (\@block, $a, $b, $c, $d, $e, 15);
($d, $a) = R1 (\@block, $e, $a, $b, $c, $d, 16);
($c, $e) = R1 (\@block, $d, $e, $a, $b, $c, 17);
($b, $d) = R1 (\@block, $c, $d, $e, $a, $b, 18);
($a, $c) = R1 (\@block, $b, $c, $d, $e, $a, 19);
($e, $b) = R2 (\@block, $a, $b, $c, $d, $e, 20);
($d, $a) = R2 (\@block, $e, $a, $b, $c, $d, 21);
($c, $e) = R2 (\@block, $d, $e, $a, $b, $c, 22);
($b, $d) = R2 (\@block, $c, $d, $e, $a, $b, 23);
($a, $c) = R2 (\@block, $b, $c, $d, $e, $a, 24);
($e, $b) = R2 (\@block, $a, $b, $c, $d, $e, 25);
($d, $a) = R2 (\@block, $e, $a, $b, $c, $d, 26);
($c, $e) = R2 (\@block, $d, $e, $a, $b, $c, 27);
($b, $d) = R2 (\@block, $c, $d, $e, $a, $b, 28);
($a, $c) = R2 (\@block, $b, $c, $d, $e, $a, 29);
($e, $b) = R2 (\@block, $a, $b, $c, $d, $e, 30);
($d, $a) = R2 (\@block, $e, $a, $b, $c, $d, 31);
($c, $e) = R2 (\@block, $d, $e, $a, $b, $c, 32);
($b, $d) = R2 (\@block, $c, $d, $e, $a, $b, 33);
($a, $c) = R2 (\@block, $b, $c, $d, $e, $a, 34);
($e, $b) = R2 (\@block, $a, $b, $c, $d, $e, 35);
($d, $a) = R2 (\@block, $e, $a, $b, $c, $d, 36);
($c, $e) = R2 (\@block, $d, $e, $a, $b, $c, 37);
($b, $d) = R2 (\@block, $c, $d, $e, $a, $b, 38);
($a, $c) = R2 (\@block, $b, $c, $d, $e, $a, 39);
($e, $b) = R3 (\@block, $a, $b, $c, $d, $e, 40);
($d, $a) = R3 (\@block, $e, $a, $b, $c, $d, 41);
($c, $e) = R3 (\@block, $d, $e, $a, $b, $c, 42);
($b, $d) = R3 (\@block, $c, $d, $e, $a, $b, 43);
($a, $c) = R3 (\@block, $b, $c, $d, $e, $a, 44);
($e, $b) = R3 (\@block, $a, $b, $c, $d, $e, 45);
($d, $a) = R3 (\@block, $e, $a, $b, $c, $d, 46);
($c, $e) = R3 (\@block, $d, $e, $a, $b, $c, 47);
($b, $d) = R3 (\@block, $c, $d, $e, $a, $b, 48);
($a, $c) = R3 (\@block, $b, $c, $d, $e, $a, 49);
($e, $b) = R3 (\@block, $a, $b, $c, $d, $e, 50);
($d, $a) = R3 (\@block, $e, $a, $b, $c, $d, 51);
($c, $e) = R3 (\@block, $d, $e, $a, $b, $c, 52);
($b, $d) = R3 (\@block, $c, $d, $e, $a, $b, 53);
($a, $c) = R3 (\@block, $b, $c, $d, $e, $a, 54);
($e, $b) = R3 (\@block, $a, $b, $c, $d, $e, 55);
($d, $a) = R3 (\@block, $e, $a, $b, $c, $d, 56);
($c, $e) = R3 (\@block, $d, $e, $a, $b, $c, 57);
($b, $d) = R3 (\@block, $c, $d, $e, $a, $b, 58);
($a, $c) = R3 (\@block, $b, $c, $d, $e, $a, 59);
($e, $b) = R4 (\@block, $a, $b, $c, $d, $e, 60);
($d, $a) = R4 (\@block, $e, $a, $b, $c, $d, 61);
($c, $e) = R4 (\@block, $d, $e, $a, $b, $c, 62);
($b, $d) = R4 (\@block, $c, $d, $e, $a, $b, 63);
($a, $c) = R4 (\@block, $b, $c, $d, $e, $a, 64);
($e, $b) = R4 (\@block, $a, $b, $c, $d, $e, 65);
($d, $a) = R4 (\@block, $e, $a, $b, $c, $d, 66);
($c, $e) = R4 (\@block, $d, $e, $a, $b, $c, 67);
($b, $d) = R4 (\@block, $c, $d, $e, $a, $b, 68);
($a, $c) = R4 (\@block, $b, $c, $d, $e, $a, 69);
($e, $b) = R4 (\@block, $a, $b, $c, $d, $e, 70);
($d, $a) = R4 (\@block, $e, $a, $b, $c, $d, 71);
($c, $e) = R4 (\@block, $d, $e, $a, $b, $c, 72);
($b, $d) = R4 (\@block, $c, $d, $e, $a, $b, 73);
($a, $c) = R4 (\@block, $b, $c, $d, $e, $a, 74);
($e, $b) = R4 (\@block, $a, $b, $c, $d, $e, 75);
($d, $a) = R4 (\@block, $e, $a, $b, $c, $d, 76);
($c, $e) = R4 (\@block, $d, $e, $a, $b, $c, 77);
($b, $d) = R4 (\@block, $c, $d, $e, $a, $b, 78);
($a, $c) = R4 (\@block, $b, $c, $d, $e, $a, 79);
$$state[0] = ($$state[0] + $a) & 0xffffffff;
$$state[1] = ($$state[1] + $b) & 0xffffffff;
$$state[2] = ($$state[2] + $c) & 0xffffffff;
$$state[3] = ($$state[3] + $d) & 0xffffffff;
$$state[4] = ($$state[4] + $e) & 0xffffffff;
$$buffer = pack ("L<*", @block);
}
sub sha1_getstate
{
my $ctx = shift;
my $info = $ctx->getstate;
# state:
my $idx = index ($info, "H:");
my $state = substr ($info, $idx + 2, 44);
$state =~ s/://g;
my @state_arr = unpack ("L>*", pack ("H*", $state));
# block:
$idx = index ($info, "block:");
my $block = substr ($info, $idx + 6, 191);
$block =~ s/://g;
$block = pack ("H*", $block);
return (\@state_arr, $block);
}
sub sha1_update_rar29
{
my $ctx = shift;
my $data = shift;
my $len = shift;
my $count = shift;
my $ctx_orig = $ctx->clone;
$ctx->add ($$data);
# two early exits from this function, if (strange data) manipulation is not needed:
my $j = $count & 63;
return if (($j + $len) <= 63);
my $i = 64 - $j;
return if (($i + 63) >= $len);
# proceed with updating $data:
my ($state, $block) = sha1_getstate ($ctx_orig);
substr ($block, $j, $i) = substr ($$data, 0, $i);
sha1_transform ($state, \$block);
while (($i + 63) < $len)
{
my $workspace = substr ($$data, $i, 64);
sha1_transform ($state, \$workspace);
substr ($$data, $i, 64) = $workspace;
$i += 64;
}
}
sub module_generate_hash
{
my $word = shift;
my $salt = shift;
my $crc32_sum = shift;
my $pack_size = shift;
my $unpack_size = shift;
my $data = shift;
# convert to utf16le:
my $buf = encode ("UTF-16LE", $word);
# add the salt to the password buffer:
$buf .= $salt;
my $len = length ($buf);
my $count = 0;
my $ctx = Digest::SHA->new ('SHA1');
my $iv = "";
# main loop:
for (my $i = 0; $i < $ITERATIONS; $i++)
{
sha1_update_rar29 ($ctx, \$buf, $len, $count);
$count += $len;
my $pos = substr (pack ("L<", $i), 0, 3);
$ctx->add ($pos);
$count += 3;
if (($i & 0x3fff) == 0)
{
my $dgst = $ctx->clone->digest;
$iv .= substr ($dgst, 19, 1);
}
}
my $k = $ctx->digest;
$k = pack ("L<*", unpack ("L>4", $k)); # byte swap the first 4 * 4 = 16 bytes
# AES-128 encrypt:
my $aes = Crypt::CBC->new (
-cipher => "Crypt::Rijndael",
-key => $k,
-iv => $iv,
-keysize => 16,
-literal_key => 1,
-header => 'none',
-padding => 'null'
);
if (defined ($data))
{
my $data_orig = $data;
my $data_encrypted = substr ($data, 0, $pack_size);
my $data_decrypted = $aes->decrypt ($data_encrypted);
# CRC32 checksum of the decrypted data:
my $data_crc = substr ($data_decrypted, 0, $unpack_size);
my $crc32_computed = crc32 ($data_crc);
$data = "WRONG";
# verify:
if ($crc32_computed eq $crc32_sum)
{
$data = $data_crc;
}
}
else
{
my $data_len = random_number (1, 4096);
$data = random_bytes ($data_len);
}
my $crc32_computed = crc32 ($data);
# byte-swap CRC32 checksum:
$crc32_computed = unpack ("L<", pack ("L>", $crc32_computed));
my $data_encrypted = $aes->encrypt ($data);
$pack_size = length ($data_encrypted);
$unpack_size = length ($data);
return sprintf ("\$RAR3\$*1*%s*%08x*%i*%i*1*%s*30", unpack ("H*", $salt), $crc32_computed, $pack_size, $unpack_size, unpack ("H*", $data_encrypted));
}
sub module_verify_hash
{
my $line = shift;
my $idx1 = index ($line, ':');
return if ($idx1 < 1);
my $hash = substr ($line, 0, $idx1);
my $word = substr ($line, $idx1 + 1);
return if (substr ($hash, 0, 9) ne "\$RAR3\$*1*");
$idx1 = index ($hash, '*', 9);
return if ($idx1 < 1);
# salt
my $salt = substr ($hash, 9, $idx1 - 9);
# crc32
my $idx2 = index ($hash, '*', $idx1 + 1);
return if ($idx2 < 1);
my $crc32_sum = substr ($hash, $idx1 + 1, $idx2 - $idx1 - 1);
# pack size
$idx1 = index ($hash, '*', $idx2 + 1);
return if ($idx1 < 1);
my $pack_size = substr ($hash, $idx2 + 1, $idx1 - $idx2 - 1);
# unpack size
$idx2 = index ($hash, '*', $idx1 + 1);
return if ($idx2 < 1);
my $unpack_size = substr ($hash, $idx1 + 1, $idx2 - $idx1 - 1);
return unless (substr ($hash, $idx2, 3) eq "*1*");
# data
$idx1 = index ($hash, '*', $idx2 + 3);
return if ($idx1 < 1);
my $data = substr ($hash, $idx2 + 3, $idx1 - $idx2 - 3);
return unless (substr ($hash, $idx1, 3) eq "*30");
# convert to hex:
$salt = pack ("H*", $salt);
$data = pack ("H*", $data);
$crc32_sum = unpack ("L<", pack ("H*", $crc32_sum));
my $word_packed = pack_if_HEX_notation ($word);
my $new_hash = module_generate_hash ($word_packed, $salt, $crc32_sum, $pack_size, $unpack_size, $data);
return ($new_hash, $word);
}
1;
Loading…
Cancel
Save