From 33581b4155cea76dbcda0a86ee000a65df0fb18e Mon Sep 17 00:00:00 2001 From: Christo Erasmus <131447877+erasmusc@users.noreply.github.com> Date: Mon, 15 May 2023 13:32:48 +0200 Subject: [PATCH 01/10] Added plugins for AES128 and AES256 AS-REPs --- OpenCL/m33100-pure.cl | 1038 ++++++++++++++++++++++++++++++++ OpenCL/m33200-pure.cl | 1101 ++++++++++++++++++++++++++++++++++ src/modules/module_33100.c | 420 +++++++++++++ src/modules/module_33200.c | 419 +++++++++++++ tools/test_modules/m33100.pm | 217 +++++++ tools/test_modules/m33200.pm | 224 +++++++ 6 files changed, 3419 insertions(+) create mode 100755 OpenCL/m33100-pure.cl create mode 100755 OpenCL/m33200-pure.cl create mode 100755 src/modules/module_33100.c create mode 100755 src/modules/module_33200.c create mode 100755 tools/test_modules/m33100.pm create mode 100755 tools/test_modules/m33200.pm diff --git a/OpenCL/m33100-pure.cl b/OpenCL/m33100-pure.cl new file mode 100755 index 000000000..a7869ea33 --- /dev/null +++ b/OpenCL/m33100-pure.cl @@ -0,0 +1,1038 @@ +/** + * Author......: See docs/credits.txt + * License.....: MIT + */ + +#define NEW_SIMD_CODE + +#ifdef KERNEL_STATIC +#include M2S(INCLUDE_PATH/inc_vendor.h) +#include M2S(INCLUDE_PATH/inc_types.h) +#include M2S(INCLUDE_PATH/inc_platform.cl) +#include M2S(INCLUDE_PATH/inc_common.cl) +#include M2S(INCLUDE_PATH/inc_simd.cl) +#include M2S(INCLUDE_PATH/inc_hash_sha1.cl) +#include M2S(INCLUDE_PATH/inc_cipher_aes.cl) +#endif + +typedef struct krb5asrep_17 +{ + u32 user[128]; + u32 domain[128]; + u32 account_info[512]; + u32 account_info_len; + + u32 checksum[3]; + u32 edata2[5120]; + u32 edata2_len; + u32 format; + +} krb5asrep_17_t; + +typedef struct krb5asrep_17_tmp +{ + u32 ipad[5]; + u32 opad[5]; + u32 dgst[10]; + u32 out[10]; + +} krb5asrep_17_tmp_t; + +DECLSPEC void aes128_encrypt_cbc (PRIVATE_AS const u32 *aes_ks, PRIVATE_AS u32 *aes_iv, PRIVATE_AS const u32 *in, PRIVATE_AS u32 *out, SHM_TYPE u32 *s_te0, SHM_TYPE u32 *s_te1, SHM_TYPE u32 *s_te2, SHM_TYPE u32 *s_te3, SHM_TYPE u32 *s_te4) +{ + u32 data[4]; + + data[0] = hc_swap32_S (in[0]); + data[1] = hc_swap32_S (in[1]); + data[2] = hc_swap32_S (in[2]); + data[3] = hc_swap32_S (in[3]); + + data[0] ^= aes_iv[0]; + data[1] ^= aes_iv[1]; + data[2] ^= aes_iv[2]; + data[3] ^= aes_iv[3]; + + aes128_encrypt (aes_ks, data, out, s_te0, s_te1, s_te2, s_te3, s_te4); + + aes_iv[0] = out[0]; + aes_iv[1] = out[1]; + aes_iv[2] = out[2]; + aes_iv[3] = out[3]; + + out[0] = hc_swap32_S (out[0]); + out[1] = hc_swap32_S (out[1]); + out[2] = hc_swap32_S (out[2]); + out[3] = hc_swap32_S (out[3]); +} + +DECLSPEC void aes128_decrypt_cbc (PRIVATE_AS const u32 *ks1, PRIVATE_AS const u32 *in, PRIVATE_AS u32 *out, PRIVATE_AS u32 *essiv, SHM_TYPE u32 *s_td0, SHM_TYPE u32 *s_td1, SHM_TYPE u32 *s_td2, SHM_TYPE u32 *s_td3, SHM_TYPE u32 *s_td4) +{ + aes128_decrypt (ks1, in, out, s_td0, s_td1, s_td2, s_td3, s_td4); + + out[0] ^= essiv[0]; + out[1] ^= essiv[1]; + out[2] ^= essiv[2]; + out[3] ^= essiv[3]; + + essiv[0] = in[0]; + essiv[1] = in[1]; + essiv[2] = in[2]; + essiv[3] = in[3]; +} + +DECLSPEC void hmac_sha1_run_V (PRIVATE_AS u32x *w0, PRIVATE_AS u32x *w1, PRIVATE_AS u32x *w2, PRIVATE_AS u32x *w3, PRIVATE_AS u32x *ipad, PRIVATE_AS u32x *opad, PRIVATE_AS u32x *digest) +{ + digest[0] = ipad[0]; + digest[1] = ipad[1]; + digest[2] = ipad[2]; + digest[3] = ipad[3]; + digest[4] = ipad[4]; + + sha1_transform_vector (w0, w1, w2, w3, digest); + + w0[0] = digest[0]; + w0[1] = digest[1]; + w0[2] = digest[2]; + w0[3] = digest[3]; + w1[0] = digest[4]; + w1[1] = 0x80000000; + 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] = (64 + 20) * 8; + + digest[0] = opad[0]; + digest[1] = opad[1]; + digest[2] = opad[2]; + digest[3] = opad[3]; + digest[4] = opad[4]; + + sha1_transform_vector (w0, w1, w2, w3, digest); +} + +KERNEL_FQ void m33100_init (KERN_ATTR_TMPS_ESALT (krb5asrep_17_tmp_t, krb5asrep_17_t)) +{ + /** + * base + */ + + const u64 gid = get_global_id (0); + + if (gid >= GID_CNT) return; + + /** + * main + */ + + /* initialize hmac-sha1 for pbkdf2(password, account, 4096, account_len) */ + + sha1_hmac_ctx_t sha1_hmac_ctx; + + sha1_hmac_init_global_swap (&sha1_hmac_ctx, pws[gid].i, pws[gid].pw_len); + + tmps[gid].ipad[0] = sha1_hmac_ctx.ipad.h[0]; + tmps[gid].ipad[1] = sha1_hmac_ctx.ipad.h[1]; + tmps[gid].ipad[2] = sha1_hmac_ctx.ipad.h[2]; + tmps[gid].ipad[3] = sha1_hmac_ctx.ipad.h[3]; + tmps[gid].ipad[4] = sha1_hmac_ctx.ipad.h[4]; + + tmps[gid].opad[0] = sha1_hmac_ctx.opad.h[0]; + tmps[gid].opad[1] = sha1_hmac_ctx.opad.h[1]; + tmps[gid].opad[2] = sha1_hmac_ctx.opad.h[2]; + tmps[gid].opad[3] = sha1_hmac_ctx.opad.h[3]; + tmps[gid].opad[4] = sha1_hmac_ctx.opad.h[4]; + + sha1_hmac_update_global_swap (&sha1_hmac_ctx, esalt_bufs[DIGESTS_OFFSET_HOST].account_info, esalt_bufs[DIGESTS_OFFSET_HOST].account_info_len); + + for (u32 i = 0, j = 1; i < 4; i += 5, j += 1) + { + sha1_hmac_ctx_t sha1_hmac_ctx2 = sha1_hmac_ctx; + + u32 w0[4]; + u32 w1[4]; + u32 w2[4]; + u32 w3[4]; + + w0[0] = j; + 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] = 0; + + sha1_hmac_update_64 (&sha1_hmac_ctx2, w0, w1, w2, w3, 4); + + sha1_hmac_final (&sha1_hmac_ctx2); + + tmps[gid].dgst[i + 0] = sha1_hmac_ctx2.opad.h[0]; + tmps[gid].dgst[i + 1] = sha1_hmac_ctx2.opad.h[1]; + tmps[gid].dgst[i + 2] = sha1_hmac_ctx2.opad.h[2]; + tmps[gid].dgst[i + 3] = sha1_hmac_ctx2.opad.h[3]; + tmps[gid].dgst[i + 4] = sha1_hmac_ctx2.opad.h[4]; + + tmps[gid].out[i + 0] = tmps[gid].dgst[i + 0]; + tmps[gid].out[i + 1] = tmps[gid].dgst[i + 1]; + tmps[gid].out[i + 2] = tmps[gid].dgst[i + 2]; + tmps[gid].out[i + 3] = tmps[gid].dgst[i + 3]; + tmps[gid].out[i + 4] = tmps[gid].dgst[i + 4]; + } +} + +KERNEL_FQ void m33100_loop (KERN_ATTR_TMPS_ESALT (krb5asrep_17_tmp_t, krb5asrep_17_t)) +{ + /** + * base + */ + const u64 gid = get_global_id (0); + + if ((gid * VECT_SIZE) >= GID_CNT) return; + + u32x ipad[5]; + u32x opad[5]; + + ipad[0] = packv (tmps, ipad, gid, 0); + ipad[1] = packv (tmps, ipad, gid, 1); + ipad[2] = packv (tmps, ipad, gid, 2); + ipad[3] = packv (tmps, ipad, gid, 3); + ipad[4] = packv (tmps, ipad, gid, 4); + + opad[0] = packv (tmps, opad, gid, 0); + opad[1] = packv (tmps, opad, gid, 1); + opad[2] = packv (tmps, opad, gid, 2); + opad[3] = packv (tmps, opad, gid, 3); + opad[4] = packv (tmps, opad, gid, 4); + + for (u32 i = 0; i < 4; i += 5) + { + u32x dgst[5]; + u32x out[5]; + + dgst[0] = packv (tmps, dgst, gid, i + 0); + dgst[1] = packv (tmps, dgst, gid, i + 1); + dgst[2] = packv (tmps, dgst, gid, i + 2); + dgst[3] = packv (tmps, dgst, gid, i + 3); + dgst[4] = packv (tmps, dgst, gid, i + 4); + + out[0] = packv (tmps, out, gid, i + 0); + out[1] = packv (tmps, out, gid, i + 1); + out[2] = packv (tmps, out, gid, i + 2); + out[3] = packv (tmps, out, gid, i + 3); + out[4] = packv (tmps, out, gid, i + 4); + + for (u32 j = 0; j < LOOP_CNT; j++) + { + u32x w0[4]; + u32x w1[4]; + u32x w2[4]; + u32x w3[4]; + + w0[0] = dgst[0]; + w0[1] = dgst[1]; + w0[2] = dgst[2]; + w0[3] = dgst[3]; + w1[0] = dgst[4]; + w1[1] = 0x80000000; + 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] = (64 + 20) * 8; + + hmac_sha1_run_V (w0, w1, w2, w3, ipad, opad, dgst); + + out[0] ^= dgst[0]; + out[1] ^= dgst[1]; + out[2] ^= dgst[2]; + out[3] ^= dgst[3]; + out[4] ^= dgst[4]; + } + + unpackv (tmps, dgst, gid, i + 0, dgst[0]); + unpackv (tmps, dgst, gid, i + 1, dgst[1]); + unpackv (tmps, dgst, gid, i + 2, dgst[2]); + unpackv (tmps, dgst, gid, i + 3, dgst[3]); + unpackv (tmps, dgst, gid, i + 4, dgst[4]); + + unpackv (tmps, out, gid, i + 0, out[0]); + unpackv (tmps, out, gid, i + 1, out[1]); + unpackv (tmps, out, gid, i + 2, out[2]); + unpackv (tmps, out, gid, i + 3, out[3]); + unpackv (tmps, out, gid, i + 4, out[4]); + } +} + +KERNEL_FQ void m33100_comp (KERN_ATTR_TMPS_ESALT (krb5asrep_17_tmp_t, krb5asrep_17_t)) +{ + /** + * base + */ + + 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_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]; + + 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]; + + for (u32 i = lid; i < 256; i += lsz) + { + 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]; + + 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]; + } + + SYNC_THREADS (); + + #else + + 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; + + 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; + + #endif + + if (gid >= GID_CNT) return; + + /* + at this point, the output ('seed') will be used to generate AES keys: + + key_bytes = derive(seed, 'kerberos'.encode(), seedsize) + + 'key_bytes' will be the AES key used to generate 'ke' and 'ki' + 'ke' will be the AES key to decrypt the ticket + 'ki' will be the key to compute the final HMAC + */ + + u32 nfolded[4]; + + // we can precompute _nfold('kerberos', 16) + nfolded[0] = 0x6b657262; + nfolded[1] = 0x65726f73; + nfolded[2] = 0x7b9b5b2b; + nfolded[3] = 0x93132b93; + + // then aes_cbc encrypt this nfolded value with 'seed' as key along with a null IV + u32 aes_key[4]; + + aes_key[0] = hc_swap32_S (tmps[gid].out[0]); + aes_key[1] = hc_swap32_S (tmps[gid].out[1]); + aes_key[2] = hc_swap32_S (tmps[gid].out[2]); + aes_key[3] = hc_swap32_S (tmps[gid].out[3]); + + u32 aes_iv[4]; + + aes_iv[0] = 0; + aes_iv[1] = 0; + aes_iv[2] = 0; + aes_iv[3] = 0; + + u32 aes_ks[44]; + + aes128_set_encrypt_key (aes_ks, aes_key, s_te0, s_te1, s_te2, s_te3); + + u32 key_bytes[4]; + + aes128_encrypt_cbc (aes_ks, aes_iv, nfolded, key_bytes, s_te0, s_te1, s_te2, s_te3, s_te4); + + /* + We will now compute 'ki', having 'key_bytes' + + Description of the key derivation function from RFC3961 Section 5.3: + The "well-known constant" used for the DK function is the key usage + number, expressed as four octets in big-endian order, followed by + one octet indicated below. + Kc = DK(base-key, usage | 0x99); + Ke = DK(base-key, usage | 0xAA); + Ki = DK(base-key, usage | 0x55); + + The key usage numbers are defined in RFC4120. In Section 5.4.2, it + specifies that a key usage number of 3 is used for the EncASRepPart + of an AS-REP message. + */ + + u32 ki[4]; + + key_bytes[0] = hc_swap32_S (key_bytes[0]); + key_bytes[1] = hc_swap32_S (key_bytes[1]); + key_bytes[2] = hc_swap32_S (key_bytes[2]); + key_bytes[3] = hc_swap32_S (key_bytes[3]); + + // we can precompute _nfold(pack('>IB', 3, 0x55), 16) + nfolded[0] = 0x6b60b058; + nfolded[1] = 0x2a6ba80d; + nfolded[2] = 0x5aad56ab; + nfolded[3] = 0x55406ad5; + + aes_iv[0] = 0; + aes_iv[1] = 0; + aes_iv[2] = 0; + aes_iv[3] = 0; + + // then aes_cbc encrypt this nfolded value with 'key_bytes' as key along with a null IV + aes128_set_encrypt_key (aes_ks, key_bytes, s_te0, s_te1, s_te2, s_te3); + + aes128_encrypt_cbc (aes_ks, aes_iv, nfolded, ki, s_te0, s_te1, s_te2, s_te3, s_te4); + + /* we will now compute 'ke' */ + + u32 ke[4]; + + // we can precompute _nfold(pack('>IB', 3, 0xAA), 16) + nfolded[0] = 0xbe349a4d; + nfolded[1] = 0x24be500e; + nfolded[2] = 0xaf57abd5; + nfolded[3] = 0xea80757a; + + aes_iv[0] = 0; + aes_iv[1] = 0; + aes_iv[2] = 0; + aes_iv[3] = 0; + + // then aes_cbc encrypt this nfolded value with 'key_bytes' as key along with a null IV + aes128_encrypt_cbc (aes_ks, aes_iv, nfolded, ke, s_te0, s_te1, s_te2, s_te3, s_te4); + + /* + We now have 'ke' and 'ki' + + We will decrypt (with 'ke') the 32 first bytes to search for ASN.1 structs + and if we find ASN.1 structs, we will compute the hmac (with 'ki') + + For AS-REP EncASRepPart: + The first byte is 0x79 (01 1 11001, where 01 = "class=APPLICATION", 1 = "form=constructed", 11001 is application type 25) + + According to RFC4120 Section 5.4.2: "Some implementations unconditionally send an encrypted EncTGSRepPart (application + tag number 26) in this field regardless of whether the reply is a AS-REP or a TGS-REP. In the interest of compatibility, + implementors MAY relax the check on the tag number of the decrypted ENC-PART" + + The first byte can thus also be 0x7a (corresponding to application type 26) instead of 0x79 + + The next byte is the length: + + if length < 128 bytes: + length is on 1 byte, and the next byte is 0x30 (class=SEQUENCE) + else if length <= 256: + length is on 2 bytes, the first byte is 0x81, and the third byte is 0x30 (class=SEQUENCE) + else if length > 256: + length is on 3 bytes, the first byte is 0x82, and the fourth byte is 0x30 (class=SEQUENCE) + */ + + u32 first_blocks[16]; + + u32 decrypted_block[4]; + + first_blocks[0] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[0]; + first_blocks[1] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[1]; + first_blocks[2] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[2]; + first_blocks[3] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[3]; + + first_blocks[4] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[4]; // possible ASN1 structs + first_blocks[5] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[5]; + first_blocks[6] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[6]; // possible ASN1 structs + first_blocks[7] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[7]; + + /* + we will decrypt them here in order to be able to compute hmac directly + if ASN1 structs were to be found + */ + first_blocks[8] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[8]; + first_blocks[9] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[9]; + first_blocks[10] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[10]; + first_blocks[11] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[11]; + + first_blocks[12] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[12]; + first_blocks[13] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[13]; + first_blocks[14] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[14]; + first_blocks[15] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[15]; + + u32 w0[4]; + u32 w1[4]; + u32 w2[4]; + u32 w3[4]; + + u32 aes_cts_decrypt_ks[44]; + + AES128_set_decrypt_key (aes_cts_decrypt_ks, ke, s_te0, s_te1, s_te2, s_te3, s_td0, s_td1, s_td2, s_td3); + + aes_iv[0] = 0; + aes_iv[1] = 0; + aes_iv[2] = 0; + aes_iv[3] = 0; + + aes128_decrypt_cbc (aes_cts_decrypt_ks, first_blocks, decrypted_block, aes_iv, s_td0, s_td1, s_td2, s_td3, s_td4); + + w0[0] = hc_swap32_S (decrypted_block[0]); + w0[1] = hc_swap32_S (decrypted_block[1]); + w0[2] = hc_swap32_S (decrypted_block[2]); + w0[3] = hc_swap32_S (decrypted_block[3]); + + aes128_decrypt_cbc (aes_cts_decrypt_ks, first_blocks + 4, decrypted_block, aes_iv, s_td0, s_td1, s_td2, s_td3, s_td4); + + w1[0] = hc_swap32_S (decrypted_block[0]); + w1[1] = hc_swap32_S (decrypted_block[1]); + w1[2] = hc_swap32_S (decrypted_block[2]); + w1[3] = hc_swap32_S (decrypted_block[3]); + + if (((decrypted_block[0] & 0x00ff80ff) == 0x00300079) || + ((decrypted_block[0] & 0x00ff80ff) == 0x0030007a) || + ((decrypted_block[0] & 0xFF00FFFF) == 0x30008179) || + ((decrypted_block[0] & 0xFF00FFFF) == 0x3000817a) || + ((decrypted_block[0] & 0x0000FFFF) == 0x00008279 && (decrypted_block[1] & 0x000000FF) == 0x00000030) || + ((decrypted_block[0] & 0x0000FFFF) == 0x0000827a && (decrypted_block[1] & 0x000000FF) == 0x00000030)) + { + // now we decrypt all the ticket to verify checksum + int block_position; + + int edata2_len = esalt_bufs[DIGESTS_OFFSET_HOST].edata2_len; + + int edata2_left; + + u32 block[16]; + + int last_block_size = edata2_len % 16; + + if (last_block_size == 0) + { + last_block_size = 16; + } + + int last_part = last_block_size + 16; + + int need = edata2_len - last_part; + + int last_block_cbc_position = (need - 16) / 4; + + // we need to decrypt also the 2 following blocks in order to be able to compute the hmac directly + aes128_decrypt_cbc (aes_cts_decrypt_ks, first_blocks + 8, decrypted_block, aes_iv, s_td0, s_td1, s_td2, s_td3, s_td4); + + w2[0] = hc_swap32_S (decrypted_block[0]); + w2[1] = hc_swap32_S (decrypted_block[1]); + w2[2] = hc_swap32_S (decrypted_block[2]); + w2[3] = hc_swap32_S (decrypted_block[3]); + + aes128_decrypt_cbc (aes_cts_decrypt_ks, first_blocks + 12, decrypted_block, aes_iv, s_td0, s_td1, s_td2, s_td3, s_td4); + + w3[0] = hc_swap32_S (decrypted_block[0]); + w3[1] = hc_swap32_S (decrypted_block[1]); + w3[2] = hc_swap32_S (decrypted_block[2]); + w3[3] = hc_swap32_S (decrypted_block[3]); + + sha1_hmac_ctx_t sha1_hmac_ctx; + + /* + hmac message = plaintext + hmac key = ki + */ + + u32 k0[4]; + u32 k1[4]; + u32 k2[4]; + u32 k3[4]; + + k0[0] = ki[0]; + k0[1] = ki[1]; + k0[2] = ki[2]; + k0[3] = ki[3]; + + k1[0] = 0; + k1[1] = 0; + k1[2] = 0; + k1[3] = 0; + + k2[0] = 0; + k2[1] = 0; + k2[2] = 0; + k2[3] = 0; + + k3[0] = 0; + k3[1] = 0; + k3[2] = 0; + k3[3] = 0; + + sha1_hmac_init_64 (&sha1_hmac_ctx, k0, k1, k2, k3); + + sha1_hmac_update_64 (&sha1_hmac_ctx, w0, w1, w2, w3, 64); + + block_position = 16; + + // first 4 blocks are already decrypted + for (edata2_left = need - 64; edata2_left >= 64; edata2_left -= 64) + { + block[0] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 0]; + block[1] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 1]; + block[2] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 2]; + block[3] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 3]; + block[4] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 4]; + block[5] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 5]; + block[6] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 6]; + block[7] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 7]; + block[8] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 8]; + block[9] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 9]; + block[10] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 10]; + block[11] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 11]; + block[12] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 12]; + block[13] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 13]; + block[14] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 14]; + block[15] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 15]; + + aes128_decrypt_cbc (aes_cts_decrypt_ks, block, decrypted_block, aes_iv, s_td0, s_td1, s_td2, s_td3, s_td4); + + w0[0] = hc_swap32_S (decrypted_block[0]); + w0[1] = hc_swap32_S (decrypted_block[1]); + w0[2] = hc_swap32_S (decrypted_block[2]); + w0[3] = hc_swap32_S (decrypted_block[3]); + + aes128_decrypt_cbc (aes_cts_decrypt_ks, block + 4, decrypted_block, aes_iv, s_td0, s_td1, s_td2, s_td3, s_td4); + + w1[0] = hc_swap32_S (decrypted_block[0]); + w1[1] = hc_swap32_S (decrypted_block[1]); + w1[2] = hc_swap32_S (decrypted_block[2]); + w1[3] = hc_swap32_S (decrypted_block[3]); + + aes128_decrypt_cbc (aes_cts_decrypt_ks, block + 8, decrypted_block, aes_iv, s_td0, s_td1, s_td2, s_td3, s_td4); + + w2[0] = hc_swap32_S (decrypted_block[0]); + w2[1] = hc_swap32_S (decrypted_block[1]); + w2[2] = hc_swap32_S (decrypted_block[2]); + w2[3] = hc_swap32_S (decrypted_block[3]); + + aes128_decrypt_cbc (aes_cts_decrypt_ks, block + 12, decrypted_block, aes_iv, s_td0, s_td1, s_td2, s_td3, s_td4); + + w3[0] = hc_swap32_S (decrypted_block[0]); + w3[1] = hc_swap32_S (decrypted_block[1]); + w3[2] = hc_swap32_S (decrypted_block[2]); + w3[3] = hc_swap32_S (decrypted_block[3]); + + sha1_hmac_update_64 (&sha1_hmac_ctx, w0, w1, w2, w3, 64); + + block_position += 16; + } + + if (edata2_left == 16) + { + block[0] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 0]; + block[1] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 1]; + block[2] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 2]; + block[3] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 3]; + + aes128_decrypt_cbc (aes_cts_decrypt_ks, block, decrypted_block, aes_iv, s_td0, s_td1, s_td2, s_td3, s_td4); + + w0[0] = hc_swap32_S (decrypted_block[0]); + w0[1] = hc_swap32_S (decrypted_block[1]); + w0[2] = hc_swap32_S (decrypted_block[2]); + w0[3] = hc_swap32_S (decrypted_block[3]); + + 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] = 0; + + sha1_hmac_update_64 (&sha1_hmac_ctx, w0, w1, w2, w3, 16); + + block_position += 4; + } + else if (edata2_left == 32) + { + block[0] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 0]; + block[1] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 1]; + block[2] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 2]; + block[3] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 3]; + block[4] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 4]; + block[5] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 5]; + block[6] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 6]; + block[7] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 7]; + + aes128_decrypt_cbc (aes_cts_decrypt_ks, block, decrypted_block, aes_iv, s_td0, s_td1, s_td2, s_td3, s_td4); + + w0[0] = hc_swap32_S (decrypted_block[0]); + w0[1] = hc_swap32_S (decrypted_block[1]); + w0[2] = hc_swap32_S (decrypted_block[2]); + w0[3] = hc_swap32_S (decrypted_block[3]); + + aes128_decrypt_cbc (aes_cts_decrypt_ks, block + 4, decrypted_block, aes_iv, s_td0, s_td1, s_td2, s_td3, s_td4); + + w1[0] = hc_swap32_S (decrypted_block[0]); + w1[1] = hc_swap32_S (decrypted_block[1]); + w1[2] = hc_swap32_S (decrypted_block[2]); + w1[3] = hc_swap32_S (decrypted_block[3]); + + w2[0] = 0; + w2[1] = 0; + w2[2] = 0; + w2[3] = 0; + + w3[0] = 0; + w3[1] = 0; + w3[2] = 0; + w3[3] = 0; + + sha1_hmac_update_64 (&sha1_hmac_ctx, w0, w1, w2, w3, 32); + + block_position += 8; + } + else if (edata2_left == 48) + { + block[0] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 0]; + block[1] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 1]; + block[2] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 2]; + block[3] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 3]; + block[4] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 4]; + block[5] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 5]; + block[6] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 6]; + block[7] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 7]; + block[8] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 8]; + block[9] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 9]; + block[10] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 10]; + block[11] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 11]; + + aes128_decrypt_cbc (aes_cts_decrypt_ks, block, decrypted_block, aes_iv, s_td0, s_td1, s_td2, s_td3, s_td4); + + w0[0] = hc_swap32_S (decrypted_block[0]); + w0[1] = hc_swap32_S (decrypted_block[1]); + w0[2] = hc_swap32_S (decrypted_block[2]); + w0[3] = hc_swap32_S (decrypted_block[3]); + + aes128_decrypt_cbc (aes_cts_decrypt_ks, block + 4, decrypted_block, aes_iv, s_td0, s_td1, s_td2, s_td3, s_td4); + + w1[0] = hc_swap32_S (decrypted_block[0]); + w1[1] = hc_swap32_S (decrypted_block[1]); + w1[2] = hc_swap32_S (decrypted_block[2]); + w1[3] = hc_swap32_S (decrypted_block[3]); + + aes128_decrypt_cbc (aes_cts_decrypt_ks, block + 8, decrypted_block, aes_iv, s_td0, s_td1, s_td2, s_td3, s_td4); + + w2[0] = hc_swap32_S (decrypted_block[0]); + w2[1] = hc_swap32_S (decrypted_block[1]); + w2[2] = hc_swap32_S (decrypted_block[2]); + w2[3] = hc_swap32_S (decrypted_block[3]); + + w3[0] = 0; + w3[1] = 0; + w3[2] = 0; + w3[3] = 0; + + sha1_hmac_update_64 (&sha1_hmac_ctx, w0, w1, w2, w3, 48); + + block_position += 12; + } + + /* + now all the ticket should be decrypted until block n-1 (not included) + and n + */ + + // this is block n-2, it will be xored with the n-1 block later crafted + u32 last_block_cbc[4]; + + last_block_cbc[0] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[last_block_cbc_position + 0]; + last_block_cbc[1] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[last_block_cbc_position + 1]; + last_block_cbc[2] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[last_block_cbc_position + 2]; + last_block_cbc[3] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[last_block_cbc_position + 3]; + + // n-1 block is decrypted separately from the previous blocks which were cbc decrypted + block[0] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 0]; + block[1] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 1]; + block[2] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 2]; + block[3] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 3]; + + aes128_decrypt (aes_cts_decrypt_ks, block, decrypted_block, s_td0, s_td1, s_td2, s_td3, s_td4); + + u32 last_block[4]; + + int last_block_position = (edata2_len - last_block_size) / 4; + + u32 n_1_crafted[4]; + + u32 last_plaintext[4]; + + last_plaintext[0] = 0; + last_plaintext[1] = 0; + last_plaintext[2] = 0; + last_plaintext[3] = 0; + + /* + n-1 block is first computed as follows: + - fill n-1 block with the X first bytes of the encrypted last block (n) + with X == length of last block + - complete the rest of the block with + + Final block (n) is computed as follows: + - fill with the X first bytes from n-1 block decrypted and xor them with last block (n) + with X == length of last block + */ + int remaining_blocks = last_block_size / 4; + + /* + last block is not necessarily aligned on 4 bytes so we will have + to shift values for the CTS crap... + */ + u32 shift = last_block_size % 4; + + u32 mask; + + switch (remaining_blocks) + { + case 0: + + last_block[0] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[last_block_position + 0]; + + mask = (0xffffffff >> ((4 - last_block_size) * 8)); + + last_plaintext[0] = last_block[0] ^ (decrypted_block[0] & mask); + last_plaintext[0] = hc_swap32_S (last_plaintext[0]); + + n_1_crafted[0] = (last_block[0] & mask) | (decrypted_block[0] & (mask ^ 0xffffffff)); + n_1_crafted[1] = decrypted_block[1]; + n_1_crafted[2] = decrypted_block[2]; + n_1_crafted[3] = decrypted_block[3]; + break; + + case 1: + + last_block[0] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[last_block_position + 0]; + + if (shift == 0) + { + n_1_crafted[0] = last_block[0]; + n_1_crafted[1] = decrypted_block[1]; + n_1_crafted[2] = decrypted_block[2]; + n_1_crafted[3] = decrypted_block[3]; + + last_plaintext[0] = last_block[0] ^ decrypted_block[0]; + last_plaintext[0] = hc_swap32_S (last_plaintext[0]); + } + else + { + last_block[1] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[last_block_position + 1]; + + mask = (0xffffffff >> ((4 - (last_block_size % 4)) * 8)); + + last_plaintext[0] = last_block[0] ^ decrypted_block[0]; + last_plaintext[1] = last_block[1] ^ (decrypted_block[1] & mask); + + last_plaintext[0] = hc_swap32_S (last_plaintext[0]); + last_plaintext[1] = hc_swap32_S (last_plaintext[1]); + + n_1_crafted[0] = last_block[0]; + n_1_crafted[1] = (last_block[1] & mask) | (decrypted_block[1] & (mask ^ 0xffffffff)); + n_1_crafted[2] = decrypted_block[2]; + n_1_crafted[3] = decrypted_block[3]; + } + break; + + case 2: + + last_block[0] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[last_block_position + 0]; + last_block[1] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[last_block_position + 1]; + + if (shift == 0) + { + n_1_crafted[0] = last_block[0]; + n_1_crafted[1] = last_block[1]; + n_1_crafted[2] = decrypted_block[2]; + n_1_crafted[3] = decrypted_block[3]; + + last_plaintext[0] = last_block[0] ^ decrypted_block[0]; + last_plaintext[1] = last_block[1] ^ decrypted_block[1]; + + last_plaintext[0] = hc_swap32_S (last_plaintext[0]); + last_plaintext[1] = hc_swap32_S (last_plaintext[1]); + } + else + { + last_block[2] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[last_block_position + 2]; + + mask = (0xffffffff >> ((4 - (last_block_size % 4)) * 8)); + + last_plaintext[0] = last_block[0] ^ decrypted_block[0]; + last_plaintext[1] = last_block[1] ^ decrypted_block[1]; + last_plaintext[2] = last_block[2] ^ (decrypted_block[2] & mask); + + last_plaintext[0] = hc_swap32_S (last_plaintext[0]); + last_plaintext[1] = hc_swap32_S (last_plaintext[1]); + last_plaintext[2] = hc_swap32_S (last_plaintext[2]); + + n_1_crafted[0] = last_block[0]; + n_1_crafted[1] = last_block[1]; + n_1_crafted[2] = (last_block[2] & mask) | (decrypted_block[2] & (mask ^ 0xffffffff)); + n_1_crafted[3] = decrypted_block[3]; + } + break; + + case 3: + + last_block[0] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[last_block_position + 0]; + last_block[1] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[last_block_position + 1]; + last_block[2] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[last_block_position + 2]; + + if (shift == 0) + { + n_1_crafted[0] = last_block[0]; + n_1_crafted[1] = last_block[1]; + n_1_crafted[2] = last_block[2]; + n_1_crafted[3] = decrypted_block[3]; + + last_plaintext[0] = last_block[0] ^ decrypted_block[0]; + last_plaintext[1] = last_block[1] ^ decrypted_block[1]; + last_plaintext[2] = last_block[2] ^ decrypted_block[2]; + + last_plaintext[0] = hc_swap32_S (last_plaintext[0]); + last_plaintext[1] = hc_swap32_S (last_plaintext[1]); + last_plaintext[2] = hc_swap32_S (last_plaintext[2]); + } + else + { + last_block[3] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[last_block_position + 3]; + + mask = (0xffffffff >> ((4 - (last_block_size % 4)) * 8)); + + last_plaintext[0] = last_block[0] ^ decrypted_block[0]; + last_plaintext[1] = last_block[1] ^ decrypted_block[1]; + last_plaintext[2] = last_block[2] ^ decrypted_block[2]; + last_plaintext[3] = last_block[3] ^ (decrypted_block[3] & mask); + + last_plaintext[0] = hc_swap32_S (last_plaintext[0]); + last_plaintext[1] = hc_swap32_S (last_plaintext[1]); + last_plaintext[2] = hc_swap32_S (last_plaintext[2]); + last_plaintext[3] = hc_swap32_S (last_plaintext[3]); + + n_1_crafted[0] = last_block[0]; + n_1_crafted[1] = last_block[1]; + n_1_crafted[2] = last_block[2]; + n_1_crafted[3] = (last_block[3] & mask) | (decrypted_block[3] & (mask ^ 0xffffffff)); + } + break; + + case 4: + + last_block[0] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[last_block_position + 0]; + last_block[1] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[last_block_position + 1]; + last_block[2] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[last_block_position + 2]; + last_block[3] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[last_block_position + 3]; + + n_1_crafted[0] = last_block[0]; + n_1_crafted[1] = last_block[1]; + n_1_crafted[2] = last_block[2]; + n_1_crafted[3] = last_block[3]; + + last_plaintext[0] = last_block[0] ^ decrypted_block[0]; + last_plaintext[1] = last_block[1] ^ decrypted_block[1]; + last_plaintext[2] = last_block[2] ^ decrypted_block[2]; + last_plaintext[3] = last_block[3] ^ decrypted_block[3]; + + last_plaintext[0] = hc_swap32_S (last_plaintext[0]); + last_plaintext[1] = hc_swap32_S (last_plaintext[1]); + last_plaintext[2] = hc_swap32_S (last_plaintext[2]); + last_plaintext[3] = hc_swap32_S (last_plaintext[3]); + break; + + default: + return; + } + + // then decrypt this newly created n-1 with 'ke' + aes128_decrypt (aes_cts_decrypt_ks, n_1_crafted, n_1_crafted, s_td0, s_td1, s_td2, s_td3, s_td4); + + // then xor with the encrypted n-2 block + n_1_crafted[0] ^= last_block_cbc[0]; + n_1_crafted[1] ^= last_block_cbc[1]; + n_1_crafted[2] ^= last_block_cbc[2]; + n_1_crafted[3] ^= last_block_cbc[3]; + + w0[0] = hc_swap32_S (n_1_crafted[0]); + w0[1] = hc_swap32_S (n_1_crafted[1]); + w0[2] = hc_swap32_S (n_1_crafted[2]); + w0[3] = hc_swap32_S (n_1_crafted[3]); + + w1[0] = last_plaintext[0]; + w1[1] = last_plaintext[1]; + w1[2] = last_plaintext[2]; + w1[3] = last_plaintext[3]; + + w2[0] = 0; + w2[1] = 0; + w2[2] = 0; + w2[3] = 0; + + w3[0] = 0; + w3[1] = 0; + w3[2] = 0; + w3[3] = 0; + + sha1_hmac_update_64 (&sha1_hmac_ctx, w0, w1, w2, w3, 16 + last_block_size); + + sha1_hmac_final (&sha1_hmac_ctx); + + if (sha1_hmac_ctx.opad.h[0] == esalt_bufs[DIGESTS_OFFSET_HOST].checksum[0] + && sha1_hmac_ctx.opad.h[1] == esalt_bufs[DIGESTS_OFFSET_HOST].checksum[1] + && sha1_hmac_ctx.opad.h[2] == esalt_bufs[DIGESTS_OFFSET_HOST].checksum[2]) + { + if (hc_atomic_inc (&hashes_shown[DIGESTS_OFFSET_HOST]) == 0) + { + #define il_pos 0 + mark_hash (plains_buf, d_return_buf, SALT_POS_HOST, DIGESTS_CNT, 0, DIGESTS_OFFSET_HOST + 0, gid, il_pos, 0, 0); + } + } + } +} diff --git a/OpenCL/m33200-pure.cl b/OpenCL/m33200-pure.cl new file mode 100755 index 000000000..26f9840c8 --- /dev/null +++ b/OpenCL/m33200-pure.cl @@ -0,0 +1,1101 @@ +/** + * Author......: See docs/credits.txt + * License.....: MIT + */ + +#define NEW_SIMD_CODE + +#ifdef KERNEL_STATIC +#include M2S(INCLUDE_PATH/inc_vendor.h) +#include M2S(INCLUDE_PATH/inc_types.h) +#include M2S(INCLUDE_PATH/inc_platform.cl) +#include M2S(INCLUDE_PATH/inc_common.cl) +#include M2S(INCLUDE_PATH/inc_simd.cl) +#include M2S(INCLUDE_PATH/inc_hash_sha1.cl) +#include M2S(INCLUDE_PATH/inc_cipher_aes.cl) +#endif + +typedef struct krb5asrep_18 +{ + u32 user[128]; + u32 domain[128]; + u32 account_info[512]; + u32 account_info_len; + + u32 checksum[3]; + u32 edata2[5120]; + u32 edata2_len; + u32 format; + +} krb5asrep_18_t; + +typedef struct krb5asrep_18_tmp +{ + u32 ipad[5]; + u32 opad[5]; + u32 dgst[16]; + u32 out[16]; + +} krb5asrep_18_tmp_t; + +DECLSPEC void aes256_encrypt_cbc (PRIVATE_AS const u32 *aes_ks, PRIVATE_AS u32 *aes_iv, PRIVATE_AS const u32 *in, PRIVATE_AS u32 *out, SHM_TYPE u32 *s_te0, SHM_TYPE u32 *s_te1, SHM_TYPE u32 *s_te2, SHM_TYPE u32 *s_te3, SHM_TYPE u32 *s_te4) +{ + u32 data[4]; + + data[0] = hc_swap32_S (in[0]); + data[1] = hc_swap32_S (in[1]); + data[2] = hc_swap32_S (in[2]); + data[3] = hc_swap32_S (in[3]); + + data[0] ^= aes_iv[0]; + data[1] ^= aes_iv[1]; + data[2] ^= aes_iv[2]; + data[3] ^= aes_iv[3]; + + aes256_encrypt (aes_ks, data, out, s_te0, s_te1, s_te2, s_te3, s_te4); + + aes_iv[0] = out[0]; + aes_iv[1] = out[1]; + aes_iv[2] = out[2]; + aes_iv[3] = out[3]; + + out[0] = hc_swap32_S (out[0]); + out[1] = hc_swap32_S (out[1]); + out[2] = hc_swap32_S (out[2]); + out[3] = hc_swap32_S (out[3]); +} + +DECLSPEC void aes256_decrypt_cbc (PRIVATE_AS const u32 *ks1, PRIVATE_AS const u32 *in, PRIVATE_AS u32 *out, PRIVATE_AS u32 *essiv, SHM_TYPE u32 *s_td0, SHM_TYPE u32 *s_td1, SHM_TYPE u32 *s_td2, SHM_TYPE u32 *s_td3, SHM_TYPE u32 *s_td4) +{ + aes256_decrypt (ks1, in, out, s_td0, s_td1, s_td2, s_td3, s_td4); + + out[0] ^= essiv[0]; + out[1] ^= essiv[1]; + out[2] ^= essiv[2]; + out[3] ^= essiv[3]; + + essiv[0] = in[0]; + essiv[1] = in[1]; + essiv[2] = in[2]; + essiv[3] = in[3]; +} + +DECLSPEC void hmac_sha1_run_V (PRIVATE_AS u32x *w0, PRIVATE_AS u32x *w1, PRIVATE_AS u32x *w2, PRIVATE_AS u32x *w3, PRIVATE_AS u32x *ipad, PRIVATE_AS u32x *opad, PRIVATE_AS u32x *digest) +{ + digest[0] = ipad[0]; + digest[1] = ipad[1]; + digest[2] = ipad[2]; + digest[3] = ipad[3]; + digest[4] = ipad[4]; + + sha1_transform_vector (w0, w1, w2, w3, digest); + + w0[0] = digest[0]; + w0[1] = digest[1]; + w0[2] = digest[2]; + w0[3] = digest[3]; + w1[0] = digest[4]; + w1[1] = 0x80000000; + 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] = (64 + 20) * 8; + + digest[0] = opad[0]; + digest[1] = opad[1]; + digest[2] = opad[2]; + digest[3] = opad[3]; + digest[4] = opad[4]; + + sha1_transform_vector (w0, w1, w2, w3, digest); +} + +KERNEL_FQ void m33200_init (KERN_ATTR_TMPS_ESALT (krb5asrep_18_tmp_t, krb5asrep_18_t)) +{ + /** + * base + */ + + const u64 gid = get_global_id (0); + + if (gid >= GID_CNT) return; + + /** + * main + */ + + /* initialize hmac-sha1 for pbkdf2(password, account, 4096, account_len) */ + + sha1_hmac_ctx_t sha1_hmac_ctx; + + sha1_hmac_init_global_swap (&sha1_hmac_ctx, pws[gid].i, pws[gid].pw_len); + + tmps[gid].ipad[0] = sha1_hmac_ctx.ipad.h[0]; + tmps[gid].ipad[1] = sha1_hmac_ctx.ipad.h[1]; + tmps[gid].ipad[2] = sha1_hmac_ctx.ipad.h[2]; + tmps[gid].ipad[3] = sha1_hmac_ctx.ipad.h[3]; + tmps[gid].ipad[4] = sha1_hmac_ctx.ipad.h[4]; + + tmps[gid].opad[0] = sha1_hmac_ctx.opad.h[0]; + tmps[gid].opad[1] = sha1_hmac_ctx.opad.h[1]; + tmps[gid].opad[2] = sha1_hmac_ctx.opad.h[2]; + tmps[gid].opad[3] = sha1_hmac_ctx.opad.h[3]; + tmps[gid].opad[4] = sha1_hmac_ctx.opad.h[4]; + + sha1_hmac_update_global_swap (&sha1_hmac_ctx, esalt_bufs[DIGESTS_OFFSET_HOST].account_info, esalt_bufs[DIGESTS_OFFSET_HOST].account_info_len); + + for (u32 i = 0, j = 1; i < 8; i += 5, j += 1) + { + sha1_hmac_ctx_t sha1_hmac_ctx2 = sha1_hmac_ctx; + + u32 w0[4]; + u32 w1[4]; + u32 w2[4]; + u32 w3[4]; + + w0[0] = j; + 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] = 0; + + sha1_hmac_update_64 (&sha1_hmac_ctx2, w0, w1, w2, w3, 4); + + sha1_hmac_final (&sha1_hmac_ctx2); + + tmps[gid].dgst[i + 0] = sha1_hmac_ctx2.opad.h[0]; + tmps[gid].dgst[i + 1] = sha1_hmac_ctx2.opad.h[1]; + tmps[gid].dgst[i + 2] = sha1_hmac_ctx2.opad.h[2]; + tmps[gid].dgst[i + 3] = sha1_hmac_ctx2.opad.h[3]; + tmps[gid].dgst[i + 4] = sha1_hmac_ctx2.opad.h[4]; + + tmps[gid].out[i + 0] = tmps[gid].dgst[i + 0]; + tmps[gid].out[i + 1] = tmps[gid].dgst[i + 1]; + tmps[gid].out[i + 2] = tmps[gid].dgst[i + 2]; + tmps[gid].out[i + 3] = tmps[gid].dgst[i + 3]; + tmps[gid].out[i + 4] = tmps[gid].dgst[i + 4]; + } +} + +KERNEL_FQ void m33200_loop (KERN_ATTR_TMPS_ESALT (krb5asrep_18_tmp_t, krb5asrep_18_t)) +{ + /** + * base + */ + const u64 gid = get_global_id (0); + + if ((gid * VECT_SIZE) >= GID_CNT) return; + + u32x ipad[5]; + u32x opad[5]; + + ipad[0] = packv (tmps, ipad, gid, 0); + ipad[1] = packv (tmps, ipad, gid, 1); + ipad[2] = packv (tmps, ipad, gid, 2); + ipad[3] = packv (tmps, ipad, gid, 3); + ipad[4] = packv (tmps, ipad, gid, 4); + + opad[0] = packv (tmps, opad, gid, 0); + opad[1] = packv (tmps, opad, gid, 1); + opad[2] = packv (tmps, opad, gid, 2); + opad[3] = packv (tmps, opad, gid, 3); + opad[4] = packv (tmps, opad, gid, 4); + + for (u32 i = 0; i < 8; i += 5) + { + u32x dgst[5]; + u32x out[5]; + + dgst[0] = packv (tmps, dgst, gid, i + 0); + dgst[1] = packv (tmps, dgst, gid, i + 1); + dgst[2] = packv (tmps, dgst, gid, i + 2); + dgst[3] = packv (tmps, dgst, gid, i + 3); + dgst[4] = packv (tmps, dgst, gid, i + 4); + + out[0] = packv (tmps, out, gid, i + 0); + out[1] = packv (tmps, out, gid, i + 1); + out[2] = packv (tmps, out, gid, i + 2); + out[3] = packv (tmps, out, gid, i + 3); + out[4] = packv (tmps, out, gid, i + 4); + + for (u32 j = 0; j < LOOP_CNT; j++) + { + u32x w0[4]; + u32x w1[4]; + u32x w2[4]; + u32x w3[4]; + + w0[0] = dgst[0]; + w0[1] = dgst[1]; + w0[2] = dgst[2]; + w0[3] = dgst[3]; + w1[0] = dgst[4]; + w1[1] = 0x80000000; + 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] = (64 + 20) * 8; + + hmac_sha1_run_V (w0, w1, w2, w3, ipad, opad, dgst); + + out[0] ^= dgst[0]; + out[1] ^= dgst[1]; + out[2] ^= dgst[2]; + out[3] ^= dgst[3]; + out[4] ^= dgst[4]; + } + + unpackv (tmps, dgst, gid, i + 0, dgst[0]); + unpackv (tmps, dgst, gid, i + 1, dgst[1]); + unpackv (tmps, dgst, gid, i + 2, dgst[2]); + unpackv (tmps, dgst, gid, i + 3, dgst[3]); + unpackv (tmps, dgst, gid, i + 4, dgst[4]); + + unpackv (tmps, out, gid, i + 0, out[0]); + unpackv (tmps, out, gid, i + 1, out[1]); + unpackv (tmps, out, gid, i + 2, out[2]); + unpackv (tmps, out, gid, i + 3, out[3]); + unpackv (tmps, out, gid, i + 4, out[4]); + } +} + +KERNEL_FQ void m33200_comp (KERN_ATTR_TMPS_ESALT (krb5asrep_18_tmp_t, krb5asrep_18_t)) +{ + /** + * base + */ + + 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]; + } + + SYNC_THREADS (); + + #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 + + if (gid >= GID_CNT) return; + + /* + at this point, the output ('seed') will be used to generate AES keys: + + key_bytes = derive(seed, 'kerberos'.encode(), seedsize) + + 'key_bytes' will be the AES key used to generate 'ke' and 'ki' + 'ke' will be the AES key to decrypt the ticket + 'ki' will be the key to compute the final HMAC + */ + + u32 nfolded[4]; + + // we can precompute _nfold('kerberos', 16) + nfolded[0] = 0x6b657262; + nfolded[1] = 0x65726f73; + nfolded[2] = 0x7b9b5b2b; + nfolded[3] = 0x93132b93; + + // then aes_cbc encrypt this nfolded value with 'seed' as key along with a null IV + u32 aes_key[8]; + + aes_key[0] = hc_swap32_S (tmps[gid].out[0]); + aes_key[1] = hc_swap32_S (tmps[gid].out[1]); + aes_key[2] = hc_swap32_S (tmps[gid].out[2]); + aes_key[3] = hc_swap32_S (tmps[gid].out[3]); + aes_key[4] = hc_swap32_S (tmps[gid].out[4]); + aes_key[5] = hc_swap32_S (tmps[gid].out[5]); + aes_key[6] = hc_swap32_S (tmps[gid].out[6]); + aes_key[7] = hc_swap32_S (tmps[gid].out[7]); + + u32 aes_iv[4]; + + aes_iv[0] = 0; + aes_iv[1] = 0; + aes_iv[2] = 0; + aes_iv[3] = 0; + + u32 aes_ks[60]; + + aes256_set_encrypt_key (aes_ks, aes_key, s_te0, s_te1, s_te2, s_te3); + + u32 key_bytes[8]; + + u32 out[4]; + aes256_encrypt_cbc (aes_ks, aes_iv, nfolded, out, s_te0, s_te1, s_te2, s_te3, s_te4); + + key_bytes[0] = out[0]; + key_bytes[1] = out[1]; + key_bytes[2] = out[2]; + key_bytes[3] = out[3]; + + aes_iv[0] = 0; + aes_iv[1] = 0; + aes_iv[2] = 0; + aes_iv[3] = 0; + + aes256_encrypt_cbc (aes_ks, aes_iv, out, out, s_te0, s_te1, s_te2, s_te3, s_te4); + + key_bytes[4] = out[0]; + key_bytes[5] = out[1]; + key_bytes[6] = out[2]; + key_bytes[7] = out[3]; + + /* + We will now compute 'ki', having 'key_bytes' + + Description of the key derivation function from RFC3961 Section 5.3: + The "well-known constant" used for the DK function is the key usage + number, expressed as four octets in big-endian order, followed by + one octet indicated below. + Kc = DK(base-key, usage | 0x99); + Ke = DK(base-key, usage | 0xAA); + Ki = DK(base-key, usage | 0x55); + + The key usage numbers are defined in RFC4120. In Section 5.4.2, it + specifies that a key usage number of 3 is used for the EncASRepPart + of an AS-REP message. + */ + + u32 ki[8]; + + // we can precompute _nfold(pack('>IB', 3, 0x55), 16) + nfolded[0] = 0x6b60b058; + nfolded[1] = 0x2a6ba80d; + nfolded[2] = 0x5aad56ab; + nfolded[3] = 0x55406ad5; + + aes_iv[0] = 0; + aes_iv[1] = 0; + aes_iv[2] = 0; + aes_iv[3] = 0; + + key_bytes[0] = hc_swap32_S (key_bytes[0]); + key_bytes[1] = hc_swap32_S (key_bytes[1]); + key_bytes[2] = hc_swap32_S (key_bytes[2]); + key_bytes[3] = hc_swap32_S (key_bytes[3]); + key_bytes[4] = hc_swap32_S (key_bytes[4]); + key_bytes[5] = hc_swap32_S (key_bytes[5]); + key_bytes[6] = hc_swap32_S (key_bytes[6]); + key_bytes[7] = hc_swap32_S (key_bytes[7]); + + // then aes_cbc encrypt this nfolded value with 'key_bytes' as key along with a null IV + aes256_set_encrypt_key (aes_ks, key_bytes, s_te0, s_te1, s_te2, s_te3); + + aes256_encrypt_cbc (aes_ks, aes_iv, nfolded, out, s_te0, s_te1, s_te2, s_te3, s_te4); + + ki[0] = out[0]; + ki[1] = out[1]; + ki[2] = out[2]; + ki[3] = out[3]; + + aes_iv[0] = 0; + aes_iv[1] = 0; + aes_iv[2] = 0; + aes_iv[3] = 0; + + aes256_encrypt_cbc (aes_ks, aes_iv, out, out, s_te0, s_te1, s_te2, s_te3, s_te4); + + ki[4] = out[0]; + ki[5] = out[1]; + ki[6] = out[2]; + ki[7] = out[3]; + + /* we will now compute 'ke' */ + + u32 ke[8]; + + // we can precompute _nfold(pack('>IB', 3, 0xAA), 16) + nfolded[0] = 0xbe349a4d; + nfolded[1] = 0x24be500e; + nfolded[2] = 0xaf57abd5; + nfolded[3] = 0xea80757a; + + aes_iv[0] = 0; + aes_iv[1] = 0; + aes_iv[2] = 0; + aes_iv[3] = 0; + + // then aes_cbc encrypt this nfolded value with 'key_bytes' as key along with a null IV + aes256_encrypt_cbc (aes_ks, aes_iv, nfolded, out, s_te0, s_te1, s_te2, s_te3, s_te4); + + ke[0] = out[0]; + ke[1] = out[1]; + ke[2] = out[2]; + ke[3] = out[3]; + + aes_iv[0] = 0; + aes_iv[1] = 0; + aes_iv[2] = 0; + aes_iv[3] = 0; + + aes256_encrypt_cbc (aes_ks, aes_iv, out, out, s_te0, s_te1, s_te2, s_te3, s_te4); + + ke[4] = out[0]; + ke[5] = out[1]; + ke[6] = out[2]; + ke[7] = out[3]; + + /* + We now have 'ke' and 'ki' + + We will decrypt (with 'ke') the 32 first bytes to search for ASN.1 structs + and if we find ASN.1 structs, we will compute the hmac (with 'ki') + + For AS-REP EncASRepPart: + The first byte is 0x79 (01 1 11001, where 01 = "class=APPLICATION", 1 = "form=constructed", 11001 is application type 25) + + According to RFC4120 Section 5.4.2: "Some implementations unconditionally send an encrypted EncTGSRepPart (application + tag number 26) in this field regardless of whether the reply is a AS-REP or a TGS-REP. In the interest of compatibility, + implementors MAY relax the check on the tag number of the decrypted ENC-PART" + + The first byte can thus also be 0x7a (corresponding to application type 26) instead of 0x79 + + The next byte is the length: + + if length < 128 bytes: + length is on 1 byte, and the next byte is 0x30 (class=SEQUENCE) + else if length <= 256: + length is on 2 bytes, the first byte is 0x81, and the third byte is 0x30 (class=SEQUENCE) + else if length > 256: + length is on 3 bytes, the first byte is 0x82, and the fourth byte is 0x30 (class=SEQUENCE) + */ + + u32 first_blocks[16]; + + u32 decrypted_block[8]; + + first_blocks[0] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[0]; + first_blocks[1] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[1]; + first_blocks[2] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[2]; + first_blocks[3] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[3]; + + first_blocks[4] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[4]; // possible ASN1 structs + first_blocks[5] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[5]; + first_blocks[6] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[6]; // possible ASN1 structs + first_blocks[7] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[7]; + + /* + we will decrypt them here in order to be able to compute hmac directly + if ASN1 structs were to be found + */ + first_blocks[8] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[8]; + first_blocks[9] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[9]; + first_blocks[10] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[10]; + first_blocks[11] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[11]; + + first_blocks[12] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[12]; + first_blocks[13] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[13]; + first_blocks[14] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[14]; + first_blocks[15] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[15]; + + u32 w0[4]; + u32 w1[4]; + u32 w2[4]; + u32 w3[4]; + + u32 aes_cts_decrypt_ks[60]; + + AES256_set_decrypt_key (aes_cts_decrypt_ks, ke, s_te0, s_te1, s_te2, s_te3, s_td0, s_td1, s_td2, s_td3); + + aes_iv[0] = 0; + aes_iv[1] = 0; + aes_iv[2] = 0; + aes_iv[3] = 0; + + aes256_decrypt_cbc (aes_cts_decrypt_ks, first_blocks, decrypted_block, aes_iv, s_td0, s_td1, s_td2, s_td3, s_td4); + + w0[0] = hc_swap32_S (decrypted_block[0]); + w0[1] = hc_swap32_S (decrypted_block[1]); + w0[2] = hc_swap32_S (decrypted_block[2]); + w0[3] = hc_swap32_S (decrypted_block[3]); + + aes256_decrypt_cbc (aes_cts_decrypt_ks, first_blocks + 4, decrypted_block, aes_iv, s_td0, s_td1, s_td2, s_td3, s_td4); + + w1[0] = hc_swap32_S (decrypted_block[0]); + w1[1] = hc_swap32_S (decrypted_block[1]); + w1[2] = hc_swap32_S (decrypted_block[2]); + w1[3] = hc_swap32_S (decrypted_block[3]); + + if (((decrypted_block[0] & 0x00ff80ff) == 0x00300079) || + ((decrypted_block[0] & 0x00ff80ff) == 0x0030007a) || + ((decrypted_block[0] & 0xFF00FFFF) == 0x30008179) || + ((decrypted_block[0] & 0xFF00FFFF) == 0x3000817a) || + ((decrypted_block[0] & 0x0000FFFF) == 0x00008279 && (decrypted_block[1] & 0x000000FF) == 0x00000030) || + ((decrypted_block[0] & 0x0000FFFF) == 0x0000827a && (decrypted_block[1] & 0x000000FF) == 0x00000030)) + { + // now we decrypt all the ticket to verify checksum + + // we need to decrypt also the 2 following blocks in order to be able to compute the hmac directly + aes256_decrypt_cbc (aes_cts_decrypt_ks, first_blocks + 8, decrypted_block, aes_iv, s_td0, s_td1, s_td2, s_td3, s_td4); + + w2[0] = hc_swap32_S (decrypted_block[0]); + w2[1] = hc_swap32_S (decrypted_block[1]); + w2[2] = hc_swap32_S (decrypted_block[2]); + w2[3] = hc_swap32_S (decrypted_block[3]); + + aes256_decrypt_cbc (aes_cts_decrypt_ks, first_blocks + 12, decrypted_block, aes_iv, s_td0, s_td1, s_td2, s_td3, s_td4); + + w3[0] = hc_swap32_S (decrypted_block[0]); + w3[1] = hc_swap32_S (decrypted_block[1]); + w3[2] = hc_swap32_S (decrypted_block[2]); + w3[3] = hc_swap32_S (decrypted_block[3]); + + int block_position; + + int edata2_len = esalt_bufs[DIGESTS_OFFSET_HOST].edata2_len; + + int edata2_left; + + u32 block[16]; + + int last_block_size = edata2_len % 16; + + if (last_block_size == 0) + { + last_block_size = 16; + } + + int last_part = last_block_size + 16; + + int need = edata2_len - last_part; + + int last_block_cbc_position = (need - 16) / 4; + + sha1_hmac_ctx_t sha1_hmac_ctx; + + /* + hmac message = plaintext + hmac key = ki + */ + + u32 k0[4]; + u32 k1[4]; + u32 k2[4]; + u32 k3[4]; + + k0[0] = ki[0]; + k0[1] = ki[1]; + k0[2] = ki[2]; + k0[3] = ki[3]; + + k1[0] = ki[4]; + k1[1] = ki[5]; + k1[2] = ki[6]; + k1[3] = ki[7]; + + k2[0] = 0; + k2[1] = 0; + k2[2] = 0; + k2[3] = 0; + + k3[0] = 0; + k3[1] = 0; + k3[2] = 0; + k3[3] = 0; + + sha1_hmac_init_64 (&sha1_hmac_ctx, k0, k1, k2, k3); + + sha1_hmac_update_64 (&sha1_hmac_ctx, w0, w1, w2, w3, 64); + + block_position = 16; + + // first 4 blocks are already decrypted + for (edata2_left = need - 64; edata2_left >= 64; edata2_left -= 64) + { + block[0] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 0]; + block[1] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 1]; + block[2] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 2]; + block[3] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 3]; + block[4] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 4]; + block[5] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 5]; + block[6] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 6]; + block[7] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 7]; + block[8] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 8]; + block[9] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 9]; + block[10] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 10]; + block[11] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 11]; + block[12] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 12]; + block[13] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 13]; + block[14] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 14]; + block[15] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 15]; + + aes256_decrypt_cbc (aes_cts_decrypt_ks, block, decrypted_block, aes_iv, s_td0, s_td1, s_td2, s_td3, s_td4); + + w0[0] = hc_swap32_S (decrypted_block[0]); + w0[1] = hc_swap32_S (decrypted_block[1]); + w0[2] = hc_swap32_S (decrypted_block[2]); + w0[3] = hc_swap32_S (decrypted_block[3]); + + aes256_decrypt_cbc (aes_cts_decrypt_ks, block + 4, decrypted_block, aes_iv, s_td0, s_td1, s_td2, s_td3, s_td4); + + w1[0] = hc_swap32_S (decrypted_block[0]); + w1[1] = hc_swap32_S (decrypted_block[1]); + w1[2] = hc_swap32_S (decrypted_block[2]); + w1[3] = hc_swap32_S (decrypted_block[3]); + + aes256_decrypt_cbc (aes_cts_decrypt_ks, block + 8, decrypted_block, aes_iv, s_td0, s_td1, s_td2, s_td3, s_td4); + + w2[0] = hc_swap32_S (decrypted_block[0]); + w2[1] = hc_swap32_S (decrypted_block[1]); + w2[2] = hc_swap32_S (decrypted_block[2]); + w2[3] = hc_swap32_S (decrypted_block[3]); + + aes256_decrypt_cbc (aes_cts_decrypt_ks, block + 12, decrypted_block, aes_iv, s_td0, s_td1, s_td2, s_td3, s_td4); + + w3[0] = hc_swap32_S (decrypted_block[0]); + w3[1] = hc_swap32_S (decrypted_block[1]); + w3[2] = hc_swap32_S (decrypted_block[2]); + w3[3] = hc_swap32_S (decrypted_block[3]); + + sha1_hmac_update_64 (&sha1_hmac_ctx, w0, w1, w2, w3, 64); + + block_position += 16; + } + + if (edata2_left == 16) + { + + block[0] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 0]; + block[1] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 1]; + block[2] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 2]; + block[3] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 3]; + + aes256_decrypt_cbc (aes_cts_decrypt_ks, block, decrypted_block, aes_iv, s_td0, s_td1, s_td2, s_td3, s_td4); + + w0[0] = hc_swap32_S (decrypted_block[0]); + w0[1] = hc_swap32_S (decrypted_block[1]); + w0[2] = hc_swap32_S (decrypted_block[2]); + w0[3] = hc_swap32_S (decrypted_block[3]); + + 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] = 0; + + sha1_hmac_update_64 (&sha1_hmac_ctx, w0, w1, w2, w3, 16); + + block_position += 4; + } + else if (edata2_left == 32) + { + block[0] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 0]; + block[1] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 1]; + block[2] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 2]; + block[3] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 3]; + block[4] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 4]; + block[5] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 5]; + block[6] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 6]; + block[7] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 7]; + + aes256_decrypt_cbc (aes_cts_decrypt_ks, block, decrypted_block, aes_iv, s_td0, s_td1, s_td2, s_td3, s_td4); + + w0[0] = hc_swap32_S (decrypted_block[0]); + w0[1] = hc_swap32_S (decrypted_block[1]); + w0[2] = hc_swap32_S (decrypted_block[2]); + w0[3] = hc_swap32_S (decrypted_block[3]); + + aes256_decrypt_cbc (aes_cts_decrypt_ks, block + 4, decrypted_block, aes_iv, s_td0, s_td1, s_td2, s_td3, s_td4); + + w1[0] = hc_swap32_S (decrypted_block[0]); + w1[1] = hc_swap32_S (decrypted_block[1]); + w1[2] = hc_swap32_S (decrypted_block[2]); + w1[3] = hc_swap32_S (decrypted_block[3]); + + w2[0] = 0; + w2[1] = 0; + w2[2] = 0; + w2[3] = 0; + + w3[0] = 0; + w3[1] = 0; + w3[2] = 0; + w3[3] = 0; + + sha1_hmac_update_64 (&sha1_hmac_ctx, w0, w1, w2, w3, 32); + + block_position += 8; + } + else if (edata2_left == 48) + { + block[0] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 0]; + block[1] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 1]; + block[2] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 2]; + block[3] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 3]; + block[4] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 4]; + block[5] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 5]; + block[6] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 6]; + block[7] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 7]; + block[8] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 8]; + block[9] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 9]; + block[10] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 10]; + block[11] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 11]; + + aes256_decrypt_cbc (aes_cts_decrypt_ks, block, decrypted_block, aes_iv, s_td0, s_td1, s_td2, s_td3, s_td4); + + w0[0] = hc_swap32_S (decrypted_block[0]); + w0[1] = hc_swap32_S (decrypted_block[1]); + w0[2] = hc_swap32_S (decrypted_block[2]); + w0[3] = hc_swap32_S (decrypted_block[3]); + + aes256_decrypt_cbc (aes_cts_decrypt_ks, block + 4, decrypted_block, aes_iv, s_td0, s_td1, s_td2, s_td3, s_td4); + + w1[0] = hc_swap32_S (decrypted_block[0]); + w1[1] = hc_swap32_S (decrypted_block[1]); + w1[2] = hc_swap32_S (decrypted_block[2]); + w1[3] = hc_swap32_S (decrypted_block[3]); + + aes256_decrypt_cbc (aes_cts_decrypt_ks, block + 8, decrypted_block, aes_iv, s_td0, s_td1, s_td2, s_td3, s_td4); + + w2[0] = hc_swap32_S (decrypted_block[0]); + w2[1] = hc_swap32_S (decrypted_block[1]); + w2[2] = hc_swap32_S (decrypted_block[2]); + w2[3] = hc_swap32_S (decrypted_block[3]); + + w3[0] = 0; + w3[1] = 0; + w3[2] = 0; + w3[3] = 0; + + sha1_hmac_update_64 (&sha1_hmac_ctx, w0, w1, w2, w3, 48); + + block_position += 12; + } + + /* + now all the ticket should be decrypted until block n-1 (not included) + and n + */ + + // this is block n-2, it will be xored with the n-1 block later crafted + u32 last_block_cbc[4]; + + last_block_cbc[0] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[last_block_cbc_position + 0]; + last_block_cbc[1] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[last_block_cbc_position + 1]; + last_block_cbc[2] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[last_block_cbc_position + 2]; + last_block_cbc[3] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[last_block_cbc_position + 3]; + + // n-1 block is decrypted separately from the previous blocks which were cbc decrypted + block[0] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 0]; + block[1] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 1]; + block[2] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 2]; + block[3] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 3]; + + aes256_decrypt (aes_cts_decrypt_ks, block, decrypted_block, s_td0, s_td1, s_td2, s_td3, s_td4); + + u32 last_block[4]; + + int last_block_position = (edata2_len - last_block_size) / 4; + + u32 n_1_crafted[4]; + + u32 last_plaintext[4]; + + last_plaintext[0] = 0; + last_plaintext[1] = 0; + last_plaintext[2] = 0; + last_plaintext[3] = 0; + + /* + n-1 block is first computed as follows: + - fill n-1 block with the X first bytes of the encrypted last block (n) + with X == length of last block + - complete the rest of the block with + + Final block (n) is computed as follows: + - fill with the X first bytes from n-1 block decrypted and xor them with last block (n) + with X == length of last block + */ + int remaining_blocks = last_block_size / 4; + + /* + last block is not necessarily aligned on 4 bytes so we will have + to shift values for the CTS crap... + */ + u32 shift = last_block_size % 4; + + u32 mask; + + switch (remaining_blocks) + { + case 0: + + last_block[0] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[last_block_position + 0]; + + mask = (0xffffffff >> ((4 - last_block_size) * 8)); + + last_plaintext[0] = last_block[0] ^ (decrypted_block[0] & mask); + last_plaintext[0] = hc_swap32_S (last_plaintext[0]); + + n_1_crafted[0] = (last_block[0] & mask) | (decrypted_block[0] & (mask ^ 0xffffffff)); + n_1_crafted[1] = decrypted_block[1]; + n_1_crafted[2] = decrypted_block[2]; + n_1_crafted[3] = decrypted_block[3]; + break; + + case 1: + + last_block[0] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[last_block_position + 0]; + + if (shift == 0) + { + n_1_crafted[0] = last_block[0]; + n_1_crafted[1] = decrypted_block[1]; + n_1_crafted[2] = decrypted_block[2]; + n_1_crafted[3] = decrypted_block[3]; + + last_plaintext[0] = last_block[0] ^ decrypted_block[0]; + last_plaintext[0] = hc_swap32_S (last_plaintext[0]); + } + else + { + last_block[1] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[last_block_position + 1]; + + mask = (0xffffffff >> ((4 - (last_block_size % 4)) * 8)); + + last_plaintext[0] = last_block[0] ^ decrypted_block[0]; + last_plaintext[1] = last_block[1] ^ (decrypted_block[1] & mask); + + last_plaintext[0] = hc_swap32_S (last_plaintext[0]); + last_plaintext[1] = hc_swap32_S (last_plaintext[1]); + + n_1_crafted[0] = last_block[0]; + n_1_crafted[1] = (last_block[1] & mask) | (decrypted_block[1] & (mask ^ 0xffffffff)); + n_1_crafted[2] = decrypted_block[2]; + n_1_crafted[3] = decrypted_block[3]; + } + break; + + case 2: + + last_block[0] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[last_block_position + 0]; + last_block[1] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[last_block_position + 1]; + + if (shift == 0) + { + n_1_crafted[0] = last_block[0]; + n_1_crafted[1] = last_block[1]; + n_1_crafted[2] = decrypted_block[2]; + n_1_crafted[3] = decrypted_block[3]; + + last_plaintext[0] = last_block[0] ^ decrypted_block[0]; + last_plaintext[1] = last_block[1] ^ decrypted_block[1]; + + last_plaintext[0] = hc_swap32_S (last_plaintext[0]); + last_plaintext[1] = hc_swap32_S (last_plaintext[1]); + } + else + { + last_block[2] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[last_block_position + 2]; + + mask = (0xffffffff >> ((4 - (last_block_size % 4)) * 8)); + + last_plaintext[0] = last_block[0] ^ decrypted_block[0]; + last_plaintext[1] = last_block[1] ^ decrypted_block[1]; + last_plaintext[2] = last_block[2] ^ (decrypted_block[2] & mask); + + last_plaintext[0] = hc_swap32_S (last_plaintext[0]); + last_plaintext[1] = hc_swap32_S (last_plaintext[1]); + last_plaintext[2] = hc_swap32_S (last_plaintext[2]); + + n_1_crafted[0] = last_block[0]; + n_1_crafted[1] = last_block[1]; + n_1_crafted[2] = (last_block[2] & mask) | (decrypted_block[2] & (mask ^ 0xffffffff)); + n_1_crafted[3] = decrypted_block[3]; + } + break; + + case 3: + + last_block[0] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[last_block_position + 0]; + last_block[1] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[last_block_position + 1]; + last_block[2] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[last_block_position + 2]; + + if (shift == 0) + { + n_1_crafted[0] = last_block[0]; + n_1_crafted[1] = last_block[1]; + n_1_crafted[2] = last_block[2]; + n_1_crafted[3] = decrypted_block[3]; + + last_plaintext[0] = last_block[0] ^ decrypted_block[0]; + last_plaintext[1] = last_block[1] ^ decrypted_block[1]; + last_plaintext[2] = last_block[2] ^ decrypted_block[2]; + + last_plaintext[0] = hc_swap32_S (last_plaintext[0]); + last_plaintext[1] = hc_swap32_S (last_plaintext[1]); + last_plaintext[2] = hc_swap32_S (last_plaintext[2]); + } + else + { + last_block[3] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[last_block_position + 3]; + + mask = (0xffffffff >> ((4 - (last_block_size % 4)) * 8)); + + last_plaintext[0] = last_block[0] ^ decrypted_block[0]; + last_plaintext[1] = last_block[1] ^ decrypted_block[1]; + last_plaintext[2] = last_block[2] ^ decrypted_block[2]; + last_plaintext[3] = last_block[3] ^ (decrypted_block[3] & mask); + + last_plaintext[0] = hc_swap32_S (last_plaintext[0]); + last_plaintext[1] = hc_swap32_S (last_plaintext[1]); + last_plaintext[2] = hc_swap32_S (last_plaintext[2]); + last_plaintext[3] = hc_swap32_S (last_plaintext[3]); + + n_1_crafted[0] = last_block[0]; + n_1_crafted[1] = last_block[1]; + n_1_crafted[2] = last_block[2]; + n_1_crafted[3] = (last_block[3] & mask) | (decrypted_block[3] & (mask ^ 0xffffffff)); + } + break; + + case 4: + + last_block[0] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[last_block_position + 0]; + last_block[1] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[last_block_position + 1]; + last_block[2] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[last_block_position + 2]; + last_block[3] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[last_block_position + 3]; + + n_1_crafted[0] = last_block[0]; + n_1_crafted[1] = last_block[1]; + n_1_crafted[2] = last_block[2]; + n_1_crafted[3] = last_block[3]; + + last_plaintext[0] = last_block[0] ^ decrypted_block[0]; + last_plaintext[1] = last_block[1] ^ decrypted_block[1]; + last_plaintext[2] = last_block[2] ^ decrypted_block[2]; + last_plaintext[3] = last_block[3] ^ decrypted_block[3]; + + last_plaintext[0] = hc_swap32_S (last_plaintext[0]); + last_plaintext[1] = hc_swap32_S (last_plaintext[1]); + last_plaintext[2] = hc_swap32_S (last_plaintext[2]); + last_plaintext[3] = hc_swap32_S (last_plaintext[3]); + break; + + default: + return; + } + + + // then decrypt this newly created n-1 with 'ke' + aes256_decrypt (aes_cts_decrypt_ks, n_1_crafted, n_1_crafted, s_td0, s_td1, s_td2, s_td3, s_td4); + + // then xor with the encrypted n-2 block + n_1_crafted[0] ^= last_block_cbc[0]; + n_1_crafted[1] ^= last_block_cbc[1]; + n_1_crafted[2] ^= last_block_cbc[2]; + n_1_crafted[3] ^= last_block_cbc[3]; + + w0[0] = hc_swap32_S (n_1_crafted[0]); + w0[1] = hc_swap32_S (n_1_crafted[1]); + w0[2] = hc_swap32_S (n_1_crafted[2]); + w0[3] = hc_swap32_S (n_1_crafted[3]); + + w1[0] = last_plaintext[0]; + w1[1] = last_plaintext[1]; + w1[2] = last_plaintext[2]; + w1[3] = last_plaintext[3]; + + w2[0] = 0; + w2[1] = 0; + w2[2] = 0; + w2[3] = 0; + + w3[0] = 0; + w3[1] = 0; + w3[2] = 0; + w3[3] = 0; + + sha1_hmac_update_64 (&sha1_hmac_ctx, w0, w1, w2, w3, 16 + last_block_size); + + sha1_hmac_final (&sha1_hmac_ctx); + + if (sha1_hmac_ctx.opad.h[0] == esalt_bufs[DIGESTS_OFFSET_HOST].checksum[0] + && sha1_hmac_ctx.opad.h[1] == esalt_bufs[DIGESTS_OFFSET_HOST].checksum[1] + && sha1_hmac_ctx.opad.h[2] == esalt_bufs[DIGESTS_OFFSET_HOST].checksum[2]) + { + if (hc_atomic_inc (&hashes_shown[DIGESTS_OFFSET_HOST]) == 0) + { + #define il_pos 0 + mark_hash (plains_buf, d_return_buf, SALT_POS_HOST, DIGESTS_CNT, 0, DIGESTS_OFFSET_HOST + 0, gid, il_pos, 0, 0); + } + } + } +} diff --git a/src/modules/module_33100.c b/src/modules/module_33100.c new file mode 100755 index 000000000..e34a1a677 --- /dev/null +++ b/src/modules/module_33100.c @@ -0,0 +1,420 @@ +/** + * 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; +static const u32 HASH_CATEGORY = HASH_CATEGORY_NETWORK_PROTOCOL; +static const char *HASH_NAME = "Kerberos 5, etype 17, AS-REP"; +static const u64 KERN_TYPE = 33100; +static const u32 OPTI_TYPE = OPTI_TYPE_ZERO_BYTE + | OPTI_TYPE_NOT_ITERATED + | OPTI_TYPE_SLOW_HASH_SIMD_LOOP; +static const u64 OPTS_TYPE = OPTS_TYPE_STOCK_MODULE + | OPTS_TYPE_PT_GENERATE_LE; +static const u32 SALT_TYPE = SALT_TYPE_EMBEDDED; +static const char *ST_PASS = "hashcat"; +static const char *ST_HASH = "$krb5asrep$17$user$EXAMPLE.COM$a419c4030e555734b06c2629$c09a1421f96eb126c757a4b87830381f142477d9a85b2beb3093dbfd44f38ddb6016a479537fb7b36e046315869fe79187217971ff6a12c1e0a2df3f68045e03814b21f756d8981f781803d65e8572823c88979581d93cf7d768f2efced16f3719b8d1004d9e73d798de255383476bced47d1982f16be77d0feb55a1f44f58bd013fa4caee58ac614caf0f1cf9101ec9623c5b8c2a1491b73f134f074790088fdb360b5ebce0d32a8145ed00a81ddf77188e150b92d8e8ddd0285d27f1514253e5546e6bba864b362bb1e6483b26d08fa4cc268bfbefe0f690039bcc524b774599df3680c1c3431d891bfa99514a877f964e"; + +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; } + +// Struct to store the hash structure - same fields as TGS-REP type 17 +typedef struct krb5asrep_17 +{ + u32 user[128]; + u32 domain[128]; + u32 account_info[512]; + u32 account_info_len; + + u32 checksum[3]; + u32 edata2[5120]; + u32 edata2_len; + u32 format; + +} krb5asrep_17_t; + +typedef struct krb5asrep_17_tmp +{ + u32 ipad[5]; + u32 opad[5]; + u32 dgst[16]; + u32 out[16]; + +} krb5asrep_17_tmp_t; + +static const char *SIGNATURE_KRB5ASREP = "$krb5asrep$17$"; + +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 u64 tmp_size = (const u64) sizeof (krb5asrep_17_tmp_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) +{ + const u64 esalt_size = (const u64) sizeof (krb5asrep_17_t); + + return esalt_size; +} + +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; + + krb5asrep_17_t *krb5asrep = (krb5asrep_17_t *) esalt_buf; + + hc_token_t token; + + memset (&token, 0, sizeof (hc_token_t)); + + token.signatures_cnt = 1; + token.signatures_buf[0] = SIGNATURE_KRB5ASREP; + + token.len[0] = strlen (SIGNATURE_KRB5ASREP); + token.attr[0] = TOKEN_ATTR_FIXED_LENGTH + | TOKEN_ATTR_VERIFY_SIGNATURE; + + /** + * Haschat + * format 1: $krb5asrep$18$user$realm$checksum$edata2 + * + * JtR + * format 2: $krb5asrep$18$salt$edata2$checksum + */ + + if (line_len < (int) strlen (SIGNATURE_KRB5ASREP)) return (PARSER_SALT_LENGTH); + + memset (krb5asrep, 0, sizeof (krb5asrep_17_t)); + + /** + * JtR format has the checksum at the end, so can identify it based on the + * separator ('$') being at a fixed length from the end of the line. Checksum + * is 24 characters in length, so then there should be a '$' at line_len - 25 + */ + + if (line_buf[line_len - 25] == '$') + { + // JtR format + krb5asrep->format = 2; + } + else + { + // Hashcat format + krb5asrep->format = 1; + } + + token.token_cnt = 4; + + if (krb5asrep->format == 1) + { + token.token_cnt++; + + // user + token.sep[1] = '$'; + token.len_min[1] = 1; + token.len_max[1] = 512; + token.attr[1] = TOKEN_ATTR_VERIFY_LENGTH; + + // realm + token.sep[2] = '$'; + token.len_min[2] = 1; + token.len_max[2] = 512; + token.attr[2] = TOKEN_ATTR_VERIFY_LENGTH; + + // checksum + token.sep[3] = '$'; + // hmac-sha1 stripped to 12bytes + token.len[3] = 24; + token.attr[3] = TOKEN_ATTR_FIXED_LENGTH + | TOKEN_ATTR_VERIFY_HEX; + + // edata2 + token.sep[4] = '$'; + token.len_min[4] = 64; + token.len_max[4] = 40960; + token.attr[4] = TOKEN_ATTR_VERIFY_LENGTH + | TOKEN_ATTR_VERIFY_HEX; + } + else + { + // salt + token.sep[1] = '$'; + token.len_min[1] = 1; + token.len_max[1] = 512; + token.attr[1] = TOKEN_ATTR_VERIFY_LENGTH; + + // edata2 + token.sep[2] = '$'; + token.len_min[2] = 64; + token.len_max[2] = 40960; + token.attr[2] = TOKEN_ATTR_VERIFY_LENGTH + | TOKEN_ATTR_VERIFY_HEX; + + // checksum + token.sep[3] = '$'; + // hmac-sha1 stripped to 12bytes + token.len[3] = 24; + token.attr[3] = TOKEN_ATTR_FIXED_LENGTH + | TOKEN_ATTR_VERIFY_HEX; + } + + + const int rc_tokenizer = input_tokenizer ((const u8 *) line_buf, line_len, &token); + + if (rc_tokenizer != PARSER_OK) return (rc_tokenizer); + + const u8 *user_pos; + const u8 *domain_pos; + const u8 *salt_pos; + const u8 *checksum_pos; + const u8 *data_pos; + + int user_len; + int domain_len; + int data_len; + int account_info_len; + + if (krb5asrep->format == 1) + { + user_pos = token.buf[1]; + user_len = token.len[1]; + + memcpy (krb5asrep->user, user_pos, user_len); + + domain_pos = token.buf[2]; + domain_len = token.len[2]; + + memcpy (krb5asrep->domain, domain_pos, domain_len); + + checksum_pos = token.buf[3]; + + data_pos = token.buf[4]; + data_len = token.len[4]; + + account_info_len = token.len[2] + token.len[1]; + } + else + { + salt_pos = token.buf[1]; + account_info_len = token.len[1]; + + memcpy (krb5asrep->account_info, salt_pos, account_info_len); + + /** + * JtR format only has the final salt/account_info value (combination of + * user and domain), rather than separate "user" and "domain" values. Since + * user and domain won't be used for the JtR format, their values won't + * matter, so set them both to the same value as account_info. + */ + + user_pos = token.buf[1]; + user_len = token.len[1]; + + memcpy (krb5asrep->user, user_pos, user_len); + + domain_pos = token.buf[1]; + domain_len = token.len[1]; + + memcpy (krb5asrep->domain, domain_pos, domain_len); + + data_pos = token.buf[2]; + data_len = token.len[2]; + + checksum_pos = token.buf[3]; + } + + u8 *account_info_ptr = (u8 *) krb5asrep->account_info; + + // Domain must be uppercase + u8 domain[128]; + + if (krb5asrep->format == 1) + { + memcpy (domain, domain_pos, domain_len); + uppercase (domain, domain_len); + + memcpy (account_info_ptr, domain, domain_len); + memcpy (account_info_ptr + domain_len, user_pos, user_len); + } + + krb5asrep->account_info_len = account_info_len; + + // hmac-sha1 is reduced to 12 bytes + krb5asrep->checksum[0] = byte_swap_32 (hex_to_u32 (checksum_pos + 0)); + krb5asrep->checksum[1] = byte_swap_32 (hex_to_u32 (checksum_pos + 8)); + krb5asrep->checksum[2] = byte_swap_32 (hex_to_u32 (checksum_pos + 16)); + + u8 *edata_ptr = (u8 *) krb5asrep->edata2; + + for (int i = 0; i < data_len; i += 2) + { + const u8 p0 = data_pos[i + 0]; + const u8 p1 = data_pos[i + 1]; + + *edata_ptr++ = hex_convert (p1) << 0 + | hex_convert (p0) << 4; + } + + krb5asrep->edata2_len = data_len / 2; + + salt->salt_buf[0] = krb5asrep->checksum[0]; + salt->salt_buf[1] = krb5asrep->checksum[1]; + salt->salt_buf[2] = krb5asrep->checksum[2]; + + salt->salt_len = 12; + + salt->salt_iter = 4096 - 1; + + digest[0] = krb5asrep->checksum[0]; + digest[1] = krb5asrep->checksum[1]; + digest[2] = krb5asrep->checksum[2]; + 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 krb5asrep_17_t *krb5asrep = (const krb5asrep_17_t *) esalt_buf; + + char data[5120 * 4 * 2] = { 0 }; + + for (u32 i = 0, j = 0; i < krb5asrep->edata2_len; i += 1, j += 2) + { + u8 *ptr_edata2 = (u8 *) krb5asrep->edata2; + + sprintf (data + j, "%02x", ptr_edata2[i]); + } + + int line_len = 0; + + if (krb5asrep->format == 1) + { + line_len = snprintf (line_buf, line_size, "%s%s$%s$%08x%08x%08x$%s", + SIGNATURE_KRB5ASREP, + (char *) krb5asrep->user, + (char *) krb5asrep->domain, + krb5asrep->checksum[0], + krb5asrep->checksum[1], + krb5asrep->checksum[2], + data); + } + else + { + line_len = snprintf (line_buf, line_size, "%s%s$%s$%08x%08x%08x", + SIGNATURE_KRB5ASREP, + (char *) krb5asrep->account_info, + data, + krb5asrep->checksum[0], + krb5asrep->checksum[1], + krb5asrep->checksum[2]); + } + + 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_DEFAULT; + module_ctx->module_benchmark_charset = MODULE_DEFAULT; + 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_deprecated_notice = 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_extra_tuningdb_block = 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_postprocess = 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_DEFAULT; + module_ctx->module_kernel_loops_min = MODULE_DEFAULT; + module_ctx->module_kernel_threads_max = MODULE_DEFAULT; + 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_DEFAULT; + 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; +} diff --git a/src/modules/module_33200.c b/src/modules/module_33200.c new file mode 100755 index 000000000..508565136 --- /dev/null +++ b/src/modules/module_33200.c @@ -0,0 +1,419 @@ +/** + * 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; +static const u32 HASH_CATEGORY = HASH_CATEGORY_NETWORK_PROTOCOL; +static const char *HASH_NAME = "Kerberos 5, etype 18, AS-REP"; +static const u64 KERN_TYPE = 33200; +static const u32 OPTI_TYPE = OPTI_TYPE_ZERO_BYTE + | OPTI_TYPE_NOT_ITERATED + | OPTI_TYPE_SLOW_HASH_SIMD_LOOP; +static const u64 OPTS_TYPE = OPTS_TYPE_STOCK_MODULE + | OPTS_TYPE_PT_GENERATE_LE; +static const u32 SALT_TYPE = SALT_TYPE_EMBEDDED; +static const char *ST_PASS = "hashcat"; +static const char *ST_HASH = "$krb5asrep$18$user$EXAMPLE.COM$aa4c494f520b27873a4de8f7$ebc9976a77f62e8ccca02d43d68bafcc66a81fcbb44a336b00ce401982f32975a5f9bcdc752643252185866685b0a30aaf50e449e392a5994e6979f23aba25f7704c90b2efa03b703c3c2f9e3617cc588ed226d0417e7742d45407878fd946d046b4a9732b9a203cb857811714b009c195b7c96b9bccb7e48832b11a4e92ecf24c49e54de8d0d5d5351445b5126db90bb7eebc7861db1e61de1175824b0a45023a6fa06c2a9d3035fdcf863bea922648e3dc28b48e39b1dec0869e7fe4de399cb52dfcf2596599da54a4bb0169c72d9496de2e137a4594e0e8a69082fc558ac9ace65d32eae5e260a65ca3f2f5871aaeee7a3b090b50f39321d120c144421e0abe7d"; + +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; } + +// Struct to store the hash structure - same fields as TGS-REP type 18 +typedef struct krb5asrep_18 +{ + u32 user[128]; + u32 domain[128]; + u32 account_info[512]; + u32 account_info_len; + + u32 checksum[3]; + u32 edata2[5120]; + u32 edata2_len; + u32 format; + +} krb5asrep_18_t; + +typedef struct krb5asrep_18_tmp +{ + u32 ipad[5]; + u32 opad[5]; + u32 dgst[16]; + u32 out[16]; + +} krb5asrep_18_tmp_t; + +static const char *SIGNATURE_KRB5ASREP = "$krb5asrep$18$"; + +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 u64 tmp_size = (const u64) sizeof (krb5asrep_18_tmp_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) +{ + const u64 esalt_size = (const u64) sizeof (krb5asrep_18_t); + + return esalt_size; +} + +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; + + krb5asrep_18_t *krb5asrep = (krb5asrep_18_t *) esalt_buf; + + hc_token_t token; + + memset (&token, 0, sizeof (hc_token_t)); + + token.signatures_cnt = 1; + token.signatures_buf[0] = SIGNATURE_KRB5ASREP; + + token.len[0] = strlen (SIGNATURE_KRB5ASREP); + token.attr[0] = TOKEN_ATTR_FIXED_LENGTH + | TOKEN_ATTR_VERIFY_SIGNATURE; + + /** + * Haschat + * format 1: $krb5asrep$18$user$realm$checksum$edata2 + * + * JtR + * format 2: $krb5asrep$18$salt$edata2$checksum + */ + + if (line_len < (int) strlen (SIGNATURE_KRB5ASREP)) return (PARSER_SALT_LENGTH); + + memset (krb5asrep, 0, sizeof (krb5asrep_18_t)); + + /** + * JtR format has the checksum at the end, so can identify it based on the + * separator ('$') being at a fixed length from the end of the line. Checksum + * is 24 characters in length, so then there should be a '$' at line_len - 25 + */ + + if (line_buf[line_len - 25] == '$') + { + // JtR format + krb5asrep->format = 2; + } + else + { + // Hashcat format + krb5asrep->format = 1; + } + + token.token_cnt = 4; + + if (krb5asrep->format == 1) + { + token.token_cnt++; + + // user + token.sep[1] = '$'; + token.len_min[1] = 1; + token.len_max[1] = 512; + token.attr[1] = TOKEN_ATTR_VERIFY_LENGTH; + + // realm + token.sep[2] = '$'; + token.len_min[2] = 1; + token.len_max[2] = 512; + token.attr[2] = TOKEN_ATTR_VERIFY_LENGTH; + + // checksum + token.sep[3] = '$'; + // hmac-sha1 stripped to 12bytes + token.len[3] = 24; + token.attr[3] = TOKEN_ATTR_FIXED_LENGTH + | TOKEN_ATTR_VERIFY_HEX; + + // edata2 + token.sep[4] = '$'; + token.len_min[4] = 64; + token.len_max[4] = 40960; + token.attr[4] = TOKEN_ATTR_VERIFY_LENGTH + | TOKEN_ATTR_VERIFY_HEX; + } + else + { + // salt + token.sep[1] = '$'; + token.len_min[1] = 1; + token.len_max[1] = 512; + token.attr[1] = TOKEN_ATTR_VERIFY_LENGTH; + + // edata2 + token.sep[2] = '$'; + token.len_min[2] = 64; + token.len_max[2] = 40960; + token.attr[2] = TOKEN_ATTR_VERIFY_LENGTH + | TOKEN_ATTR_VERIFY_HEX; + + // checksum + token.sep[3] = '$'; + // hmac-sha1 stripped to 12bytes + token.len[3] = 24; + token.attr[3] = TOKEN_ATTR_FIXED_LENGTH + | TOKEN_ATTR_VERIFY_HEX; + } + + const int rc_tokenizer = input_tokenizer ((const u8 *) line_buf, line_len, &token); + + if (rc_tokenizer != PARSER_OK) return (rc_tokenizer); + + const u8 *user_pos; + const u8 *domain_pos; + const u8 *salt_pos; + const u8 *checksum_pos; + const u8 *data_pos; + + int user_len; + int domain_len; + int data_len; + int account_info_len; + + if (krb5asrep->format == 1) + { + user_pos = token.buf[1]; + user_len = token.len[1]; + + memcpy (krb5asrep->user, user_pos, user_len); + + domain_pos = token.buf[2]; + domain_len = token.len[2]; + + memcpy (krb5asrep->domain, domain_pos, domain_len); + + checksum_pos = token.buf[3]; + + data_pos = token.buf[4]; + data_len = token.len[4]; + + account_info_len = token.len[2] + token.len[1]; + } + else + { + salt_pos = token.buf[1]; + account_info_len = token.len[1]; + + memcpy (krb5asrep->account_info, salt_pos, account_info_len); + + /** + * JtR format only has the final salt/account_info value (combination of + * user and domain), rather than separate "user" and "domain" values. Since + * user and domain won't be used for the JtR format, their values won't + * matter, so set them both to the same value as account_info. + */ + + user_pos = token.buf[1]; + user_len = token.len[1]; + + memcpy (krb5asrep->user, user_pos, user_len); + + domain_pos = token.buf[1]; + domain_len = token.len[1]; + + memcpy (krb5asrep->domain, domain_pos, domain_len); + + data_pos = token.buf[2]; + data_len = token.len[2]; + + checksum_pos = token.buf[3]; + } + + u8 *account_info_ptr = (u8 *) krb5asrep->account_info; + + // Domain must be uppercase + u8 domain[128]; + + if (krb5asrep->format == 1) + { + memcpy (domain, domain_pos, domain_len); + uppercase (domain, domain_len); + + memcpy (account_info_ptr, domain, domain_len); + memcpy (account_info_ptr + domain_len, user_pos, user_len); + } + + krb5asrep->account_info_len = account_info_len; + + // hmac-sha1 is reduced to 12 bytes + krb5asrep->checksum[0] = byte_swap_32 (hex_to_u32 (checksum_pos + 0)); + krb5asrep->checksum[1] = byte_swap_32 (hex_to_u32 (checksum_pos + 8)); + krb5asrep->checksum[2] = byte_swap_32 (hex_to_u32 (checksum_pos + 16)); + + u8 *edata_ptr = (u8 *) krb5asrep->edata2; + + for (int i = 0; i < data_len; i += 2) + { + const u8 p0 = data_pos[i + 0]; + const u8 p1 = data_pos[i + 1]; + + *edata_ptr++ = hex_convert (p1) << 0 + | hex_convert (p0) << 4; + } + + krb5asrep->edata2_len = data_len / 2; + + salt->salt_buf[0] = krb5asrep->checksum[0]; + salt->salt_buf[1] = krb5asrep->checksum[1]; + salt->salt_buf[2] = krb5asrep->checksum[2]; + + salt->salt_len = 12; + + salt->salt_iter = 4096 - 1; + + digest[0] = krb5asrep->checksum[0]; + digest[1] = krb5asrep->checksum[1]; + digest[2] = krb5asrep->checksum[2]; + 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 krb5asrep_18_t *krb5asrep = (const krb5asrep_18_t *) esalt_buf; + + char data[5120 * 4 * 2] = { 0 }; + + for (u32 i = 0, j = 0; i < krb5asrep->edata2_len; i += 1, j += 2) + { + u8 *ptr_edata2 = (u8 *) krb5asrep->edata2; + + sprintf (data + j, "%02x", ptr_edata2[i]); + } + + int line_len = 0; + + if (krb5asrep->format == 1) + { + line_len = snprintf (line_buf, line_size, "%s%s$%s$%08x%08x%08x$%s", + SIGNATURE_KRB5ASREP, + (char *) krb5asrep->user, + (char *) krb5asrep->domain, + krb5asrep->checksum[0], + krb5asrep->checksum[1], + krb5asrep->checksum[2], + data); + } + else + { + line_len = snprintf (line_buf, line_size, "%s%s$%s$%08x%08x%08x", + SIGNATURE_KRB5ASREP, + (char *) krb5asrep->account_info, + data, + krb5asrep->checksum[0], + krb5asrep->checksum[1], + krb5asrep->checksum[2]); + } + + 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_DEFAULT; + module_ctx->module_benchmark_charset = MODULE_DEFAULT; + 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_deprecated_notice = 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_extra_tuningdb_block = 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_postprocess = 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_DEFAULT; + module_ctx->module_kernel_loops_min = MODULE_DEFAULT; + module_ctx->module_kernel_threads_max = MODULE_DEFAULT; + 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_DEFAULT; + 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; +} diff --git a/tools/test_modules/m33100.pm b/tools/test_modules/m33100.pm new file mode 100755 index 000000000..499eddd12 --- /dev/null +++ b/tools/test_modules/m33100.pm @@ -0,0 +1,217 @@ +#!/usr/bin/env perl + +## +## Author......: See docs/credits.txt +## License.....: MIT +## + +use strict; +use warnings; + +use Digest::SHA qw (hmac_sha1); +use Crypt::Mode::CBC; +use Crypt::PBKDF2; + +sub byte2hex +{ + my $input = shift; + return unpack ("H*", $input); +} + +sub hex2byte +{ + my $input = shift; + return pack ("H*", $input); +} + +sub pad +{ + my $n = shift; + my $size = shift; + + return (~$n + 1) & ($size - 1); +} + +sub module_constraints { [[0, 256], [16, 16], [-1, -1], [-1, -1], [-1, -1]] } + +sub module_generate_hash +{ + my $word = shift; + my $salt = shift; + my $user = shift // "user"; + my $realm = shift // "example.com"; + my $checksum = shift; + my $edata2 = shift; + + my $mysalt = uc $realm; + $mysalt = $mysalt . $user; + + # first we generate the 'seed' + my $iter = 4096; + my $pbkdf2 = Crypt::PBKDF2->new + ( + hash_class => 'HMACSHA1', + iterations => $iter, + output_len => 16 + ); + + my $b_seed = $pbkdf2->PBKDF2 ($mysalt, $word); + + # we can precompute this + my $b_kerberos_nfolded = hex2byte ('6b65726265726f737b9b5b2b93132b93'); + + my $b_iv = hex2byte ('0' x 32); + + # 'key_bytes' will be the AES key used to generate 'ki' (for final hmac-sha1) + # and 'ke' (AES key to decrypt/encrypt the ticket) + my $cbc = Crypt::Mode::CBC->new ('AES', 0); + my $b_key_bytes = $cbc->encrypt ($b_kerberos_nfolded, $b_seed, $b_iv); + + # precomputed stuff + my $b_nfolded1 = hex2byte ('6b60b0582a6ba80d5aad56ab55406ad5'); + my $b_nfolded2 = hex2byte ('be349a4d24be500eaf57abd5ea80757a'); + + my $b_ki = $cbc->encrypt ($b_nfolded1, $b_key_bytes, $b_iv); + my $b_ke = $cbc->encrypt ($b_nfolded2, $b_key_bytes, $b_iv); + + my $cleartext_ticket = '7981df3081dca01b3019a003020111a1120410e2aa1c894df7'. + '23b7277eef29700bf760a11c301a3018a003020100a111180f32303233303333313132303'. + '434355aa20602041d9d970ba311180f32303337303931343032343830355aa40703050040'. + 'c10000a511180f32303233303333313132303434355aa611180f323032333033333131323'. + '03434355aa711180f32303233303333313232303434355aa811180f323032333034303731'. + '32303434355aa90d1b0b4558414d504c452e434f4daa20301ea003020102a11730151b066'. + 'b72627467741b0b6578616d706c652e636f6d'; + + if (defined $edata2) + { + my $len_last_block = length ($edata2) % 32; + + my $tmp = $len_last_block + 32; + + my $b_truncated_enc_ticket = hex2byte (substr $edata2, 0, -$tmp); + + my $b_last_block = hex2byte (substr $edata2, -$len_last_block); + + my $b_n_1_block = hex2byte (substr (substr ($edata2, -$tmp), 0, 32)); + + my $b_truncated_ticket_decrypted = $cbc->decrypt ($b_truncated_enc_ticket, $b_ke, $b_iv); + + my $truncated_ticket_decrypted = byte2hex ($b_truncated_ticket_decrypted); + + my $check_correct = ((substr ($truncated_ticket_decrypted, 16, 4) eq "7981" || substr ($truncated_ticket_decrypted, 16, 4) eq "7a81") && (substr ($truncated_ticket_decrypted, 22, 2) eq "30")) || + ((substr ($truncated_ticket_decrypted, 16, 2) eq "79" || substr ($truncated_ticket_decrypted, 16, 2) eq "7a") && (substr ($truncated_ticket_decrypted, 20, 2) eq "30")) || + ((substr ($truncated_ticket_decrypted, 16, 4) eq "7982" || substr ($truncated_ticket_decrypted, 16, 4) eq "7a82") && (substr ($truncated_ticket_decrypted, 24, 2) eq "30")); + + if ($check_correct == 1) + { + my $b_n_2 = substr $b_truncated_enc_ticket, -16; + + my $b_n_1_decrypted = $cbc->decrypt ($b_n_1_block, $b_ke, $b_iv); + + my $b_last_plain = substr $b_n_1_decrypted, 0, $len_last_block / 2; + + $b_last_plain = $b_last_plain ^ $b_last_block; + + my $omitted = substr $b_n_1_decrypted, -(16 - $len_last_block / 2); + + my $b_n_1 = $b_last_block . $omitted; + + $b_n_1 = $cbc->decrypt ($b_n_1, $b_ke, $b_iv); + + $b_n_1 = $b_n_1 ^ $b_n_2; + + my $b_cleartext_ticket = $b_truncated_ticket_decrypted . $b_n_1 . $b_last_plain; + + $cleartext_ticket = byte2hex ($b_cleartext_ticket); + } + else # validation failed + { + # fake/wrong ticket (otherwise if we just decrypt/encrypt we end + #up with false positives all the time) + $cleartext_ticket = "0" x (length ($cleartext_ticket) + 32); + } + } + + if (defined $checksum) + { + $checksum = pack ("H*", $checksum); + } + else + { + if (!defined $edata2) + { + my $nonce = unpack ("H*", random_bytes (16)); + + $cleartext_ticket = $nonce . $cleartext_ticket; + } + # we have what is required to compute checksum + $checksum = hmac_sha1 (hex2byte ($cleartext_ticket), $b_ki); + + $checksum = substr $checksum, 0, 12; + } + + my $len_cleartext_last_block = length ($cleartext_ticket) % 32; + my $cleartext_last_block = substr $cleartext_ticket, -$len_cleartext_last_block; + + my $padding = pad (length ($cleartext_ticket), 32); + + my $b_cleartext_last_block_padded = hex2byte ($cleartext_last_block . '0' x $padding); + + # we will encrypt until n-1 block (included) + my $truncated_cleartext_ticket = substr $cleartext_ticket, 0, -$len_cleartext_last_block; + + my $b_truncated_enc_ticket = $cbc->encrypt (hex2byte ($truncated_cleartext_ticket), $b_ke, $b_iv); + + my $b_enc_ticket_n_1_block= substr $b_truncated_enc_ticket, -16; + + my $b_enc_last_block = substr $b_enc_ticket_n_1_block, 0, $len_cleartext_last_block / 2; + + # we now craft the new n-1 block + my $tmp = $b_enc_ticket_n_1_block ^ $b_cleartext_last_block_padded; + + $b_enc_ticket_n_1_block = $cbc->encrypt ($tmp, $b_ke, $b_iv); + + $tmp = substr $b_truncated_enc_ticket, 0, -16; + + $edata2 = $tmp . $b_enc_ticket_n_1_block . $b_enc_last_block; + + my $tmp_hash = sprintf ('$krb5asrep$17$%s$%s$%s$%s', $user, $realm, unpack ("H*", $checksum), unpack ("H*", $edata2)); + + return $tmp_hash; +} + +sub module_verify_hash +{ + my $line = shift; + + my ($hash, $word) = split (':', $line); + + return unless defined $hash; + return unless defined $word; + + my @data = split ('\$', $hash); + + return unless scalar @data == 7; + + shift @data; + + my $signature = shift @data; + my $algorithm = shift @data; + my $user = shift @data; + my $realm = shift @data; + my $checksum = shift @data; + my $edata2 = shift @data; + + return unless ($signature eq "krb5asrep"); + return unless ($algorithm eq "17"); + return unless (length ($checksum) == 24); + return unless (length ($edata2) >= 64); + + my $word_packed = pack_if_HEX_notation ($word); + + my $new_hash = module_generate_hash ($word_packed, undef, $user, $realm, $checksum, $edata2); + + return ($new_hash, $word); +} + +1; diff --git a/tools/test_modules/m33200.pm b/tools/test_modules/m33200.pm new file mode 100755 index 000000000..6a3710621 --- /dev/null +++ b/tools/test_modules/m33200.pm @@ -0,0 +1,224 @@ +#!/usr/bin/env perl + +## +## Author......: See docs/credits.txt +## License.....: MIT +## + +use strict; +use warnings; + +use Digest::SHA qw (hmac_sha1); +use Crypt::Mode::CBC; +use Crypt::PBKDF2; + +sub byte2hex +{ + my $input = shift; + return unpack ("H*", $input); +} + +sub hex2byte +{ + my $input = shift; + return pack ("H*", $input); +} + +sub pad +{ + my $n = shift; + my $size = shift; + + return (~$n + 1) & ($size - 1); +} + +sub module_constraints { [[0, 256], [16, 16], [-1, -1], [-1, -1], [-1, -1]] } + +sub module_generate_hash +{ + my $word = shift; + my $salt = shift; + my $user = shift // "user"; + my $realm = shift // "example.com"; + my $checksum = shift; + my $edata2 = shift; + + my $mysalt = uc $realm; + $mysalt = $mysalt . $user; + + # first we generate the 'seed' + my $iter = 4096; + my $pbkdf2 = Crypt::PBKDF2->new + ( + hash_class => 'HMACSHA1', + iterations => $iter, + output_len => 32 + ); + + my $b_seed = $pbkdf2->PBKDF2 ($mysalt, $word); + + # we can precompute this + my $b_kerberos_nfolded = hex2byte ('6b65726265726f737b9b5b2b93132b93'); + + my $b_iv = hex2byte ('0' x 32); + + # 'key_bytes' will be the AES key used to generate 'ki' (for final hmac-sha1) + # and 'ke' (AES key to decrypt/encrypt the ticket) + my $cbc = Crypt::Mode::CBC->new ('AES', 0); + my $b_key_bytes = $cbc->encrypt ($b_kerberos_nfolded, $b_seed, $b_iv); + + $b_key_bytes = $b_key_bytes . $cbc->encrypt ($b_key_bytes, $b_seed, $b_iv); + + # precomputed stuff + my $b_nfolded1 = hex2byte ('6b60b0582a6ba80d5aad56ab55406ad5'); + my $b_nfolded2 = hex2byte ('be349a4d24be500eaf57abd5ea80757a'); + + my $b_ki = $cbc->encrypt ($b_nfolded1, $b_key_bytes, $b_iv); + + $b_ki = $b_ki . $cbc->encrypt ($b_ki, $b_key_bytes, $b_iv); + + my $b_ke = $cbc->encrypt ($b_nfolded2, $b_key_bytes, $b_iv); + + $b_ke = $b_ke . $cbc->encrypt ($b_ke, $b_key_bytes, $b_iv); + + my $cleartext_ticket = '7981ef3081eca02b3029a003020112a12204200e97d1626616'. + '6e06252cbec52003e0f6b4f0280deec6dc58cdbf39845d6f0e77a11c301a3018a00302010'. + '0a111180f32303233303331363135353732315aa20602045b66ac3ea311180f3230333730'. + '3931343032343830355aa40703050050c10000a511180f323032333033313631353537323'. + '15aa611180f32303233303331363135353732315aa711180f323032333033313730313537'. + '32315aa811180f32303233303331373135353732315aa90d1b0b4558414d504c452e434f4'. + 'daa20301ea003020101a11730151b066b72627467741b0b4558414d504c452e434f4d'; + + if (defined $edata2) + { + my $len_last_block = length ($edata2) % 32; + + my $tmp = $len_last_block + 32; + + my $b_truncated_enc_ticket = hex2byte (substr $edata2, 0, -$tmp); + + my $b_last_block = hex2byte (substr $edata2, -$len_last_block); + + my $b_n_1_block = hex2byte (substr (substr ($edata2, -$tmp), 0, 32)); + + my $b_truncated_ticket_decrypted = $cbc->decrypt ($b_truncated_enc_ticket, $b_ke, $b_iv); + + my $truncated_ticket_decrypted = byte2hex ($b_truncated_ticket_decrypted); + + my $check_correct = ((substr ($truncated_ticket_decrypted, 16, 4) eq "7981" || substr ($truncated_ticket_decrypted, 16, 4) eq "7a81") && (substr ($truncated_ticket_decrypted, 22, 2) eq "30")) || + ((substr ($truncated_ticket_decrypted, 16, 2) eq "79" || substr ($truncated_ticket_decrypted, 16, 2) eq "7a") && (substr ($truncated_ticket_decrypted, 20, 2) eq "30")) || + ((substr ($truncated_ticket_decrypted, 16, 4) eq "7982" || substr ($truncated_ticket_decrypted, 16, 4) eq "7a82") && (substr ($truncated_ticket_decrypted, 24, 2) eq "30")); + + if ($check_correct == 1) + { + my $b_n_2 = substr $b_truncated_enc_ticket, -16; + + my $b_n_1_decrypted = $cbc->decrypt ($b_n_1_block, $b_ke, $b_iv); + + my $b_last_plain = substr $b_n_1_decrypted, 0, $len_last_block / 2; + + $b_last_plain = $b_last_plain ^ $b_last_block; + + my $omitted = substr $b_n_1_decrypted, -(16 - $len_last_block / 2); + + my $b_n_1 = $b_last_block . $omitted; + + $b_n_1 = $cbc->decrypt ($b_n_1, $b_ke, $b_iv); + + $b_n_1 = $b_n_1 ^ $b_n_2; + + my $b_cleartext_ticket = $b_truncated_ticket_decrypted . $b_n_1 . $b_last_plain; + + $cleartext_ticket = byte2hex ($b_cleartext_ticket); + } + else # validation failed + { + # fake/wrong ticket (otherwise if we just decrypt/encrypt we end + #up with false positives all the time) + $cleartext_ticket = "0" x (length ($cleartext_ticket) + 32); + } + } + + if (defined $checksum) + { + $checksum = pack ("H*", $checksum); + } + else + { + if (!defined $edata2) + { + my $nonce = unpack ("H*", random_bytes (16)); + + $cleartext_ticket = $nonce . $cleartext_ticket; + } + # we have what is required to compute checksum + $checksum = hmac_sha1 (hex2byte ($cleartext_ticket), $b_ki); + + $checksum = substr $checksum, 0, 12; + } + + my $len_cleartext_last_block = length ($cleartext_ticket) % 32; + my $cleartext_last_block = substr $cleartext_ticket, -$len_cleartext_last_block; + + my $padding = pad (length ($cleartext_ticket), 32); + + my $b_cleartext_last_block_padded = hex2byte ($cleartext_last_block . '0' x $padding); + + # we will encrypt until n-1 block (included) + my $truncated_cleartext_ticket = substr $cleartext_ticket, 0, -$len_cleartext_last_block; + + my $b_truncated_enc_ticket = $cbc->encrypt (hex2byte ($truncated_cleartext_ticket), $b_ke, $b_iv); + + my $b_enc_ticket_n_1_block= substr $b_truncated_enc_ticket, -16; + + my $b_enc_last_block = substr $b_enc_ticket_n_1_block, 0, $len_cleartext_last_block / 2; + + # we now craft the new n-1 block + my $tmp = $b_enc_ticket_n_1_block ^ $b_cleartext_last_block_padded; + + $b_enc_ticket_n_1_block = $cbc->encrypt ($tmp, $b_ke, $b_iv); + + $tmp = substr $b_truncated_enc_ticket, 0, -16; + + $edata2 = $tmp . $b_enc_ticket_n_1_block . $b_enc_last_block; + + my $tmp_hash = sprintf ('$krb5asrep$18$%s$%s$%s$%s', $user, $realm, unpack ("H*", $checksum), unpack ("H*", $edata2)); + + return $tmp_hash; +} + +sub module_verify_hash +{ + my $line = shift; + + my ($hash, $word) = split (':', $line); + + return unless defined $hash; + return unless defined $word; + + my @data = split ('\$', $hash); + + return unless scalar @data == 7; + + shift @data; + + my $signature = shift @data; + my $algorithm = shift @data; + my $user = shift @data; + my $realm = shift @data; + my $checksum = shift @data; + my $edata2 = shift @data; + + return unless ($signature eq "krb5asrep"); + return unless ($algorithm eq "18"); + return unless (length ($checksum) == 24); + return unless (length ($edata2) >= 64); + + my $word_packed = pack_if_HEX_notation ($word); + + my $new_hash = module_generate_hash ($word_packed, undef, $user, $realm, $checksum, $edata2); + + return ($new_hash, $word); +} + +1; From f126f3b19e022ca738656b3eaae9964ea83c3034 Mon Sep 17 00:00:00 2001 From: Gabriele Gristina Date: Tue, 16 May 2023 20:35:40 +0200 Subject: [PATCH 02/10] Added support for NetIQ SSPR hashes + Adobe AEM --- OpenCL/m32000-pure.cl | 127 ++++++++++++ OpenCL/m32010-pure.cl | 132 +++++++++++++ OpenCL/m32020-pure.cl | 134 +++++++++++++ OpenCL/m32030-pure.cl | 149 ++++++++++++++ OpenCL/m32040-pure.cl | 173 +++++++++++++++++ docs/changes.txt | 10 + docs/readme.txt | 10 + src/modules/module_32000.c | 211 ++++++++++++++++++++ src/modules/module_32010.c | 220 +++++++++++++++++++++ src/modules/module_32020.c | 255 ++++++++++++++++++++++++ src/modules/module_32030.c | 267 ++++++++++++++++++++++++++ src/modules/module_32031.c | 272 ++++++++++++++++++++++++++ src/modules/module_32040.c | 268 ++++++++++++++++++++++++++ src/modules/module_32041.c | 275 ++++++++++++++++++++++++++ src/modules/module_32050.c | 297 ++++++++++++++++++++++++++++ src/modules/module_32060.c | 362 +++++++++++++++++++++++++++++++++++ src/modules/module_32070.c | 310 ++++++++++++++++++++++++++++++ tools/test_modules/m32000.pm | 71 +++++++ tools/test_modules/m32010.pm | 71 +++++++ tools/test_modules/m32020.pm | 78 ++++++++ tools/test_modules/m32030.pm | 78 ++++++++ tools/test_modules/m32031.pm | 71 +++++++ tools/test_modules/m32040.pm | 78 ++++++++ tools/test_modules/m32041.pm | 71 +++++++ tools/test_modules/m32050.pm | 65 +++++++ tools/test_modules/m32060.pm | 80 ++++++++ tools/test_modules/m32070.pm | 68 +++++++ 27 files changed, 4203 insertions(+) create mode 100644 OpenCL/m32000-pure.cl create mode 100644 OpenCL/m32010-pure.cl create mode 100644 OpenCL/m32020-pure.cl create mode 100644 OpenCL/m32030-pure.cl create mode 100644 OpenCL/m32040-pure.cl create mode 100644 src/modules/module_32000.c create mode 100644 src/modules/module_32010.c create mode 100644 src/modules/module_32020.c create mode 100644 src/modules/module_32030.c create mode 100644 src/modules/module_32031.c create mode 100644 src/modules/module_32040.c create mode 100644 src/modules/module_32041.c create mode 100644 src/modules/module_32050.c create mode 100644 src/modules/module_32060.c create mode 100644 src/modules/module_32070.c create mode 100644 tools/test_modules/m32000.pm create mode 100644 tools/test_modules/m32010.pm create mode 100644 tools/test_modules/m32020.pm create mode 100644 tools/test_modules/m32030.pm create mode 100644 tools/test_modules/m32031.pm create mode 100644 tools/test_modules/m32040.pm create mode 100644 tools/test_modules/m32041.pm create mode 100644 tools/test_modules/m32050.pm create mode 100644 tools/test_modules/m32060.pm create mode 100644 tools/test_modules/m32070.pm diff --git a/OpenCL/m32000-pure.cl b/OpenCL/m32000-pure.cl new file mode 100644 index 000000000..e7d985b52 --- /dev/null +++ b/OpenCL/m32000-pure.cl @@ -0,0 +1,127 @@ +/** + * Author......: See docs/credits.txt + * License.....: MIT + */ + +#define NEW_SIMD_CODE + +#ifdef KERNEL_STATIC +#include M2S(INCLUDE_PATH/inc_vendor.h) +#include M2S(INCLUDE_PATH/inc_types.h) +#include M2S(INCLUDE_PATH/inc_platform.cl) +#include M2S(INCLUDE_PATH/inc_common.cl) +#include M2S(INCLUDE_PATH/inc_simd.cl) +#include M2S(INCLUDE_PATH/inc_hash_md5.cl) +#endif + +#define COMPARE_S M2S(INCLUDE_PATH/inc_comp_single.cl) +#define COMPARE_M M2S(INCLUDE_PATH/inc_comp_multi.cl) + +typedef struct netiq_sspr_md5_tmp +{ + u32 dgst[4]; + +} netiq_sspr_md5_tmp_t; + +KERNEL_FQ void m32000_init (KERN_ATTR_TMPS (netiq_sspr_md5_tmp_t)) +{ + /** + * base + */ + + const u64 gid = get_global_id (0); + + if (gid >= GID_CNT) return; + + md5_ctx_t ctx; + + md5_init (&ctx); + + md5_update_global (&ctx, pws[gid].i, pws[gid].pw_len); + + md5_final (&ctx); + + tmps[gid].dgst[0] = ctx.h[0]; + tmps[gid].dgst[1] = ctx.h[1]; + tmps[gid].dgst[2] = ctx.h[2]; + tmps[gid].dgst[3] = ctx.h[3]; +} + +KERNEL_FQ void m32000_loop (KERN_ATTR_TMPS (netiq_sspr_md5_tmp_t)) +{ + const u64 gid = get_global_id (0); + + if ((gid * VECT_SIZE) >= GID_CNT) return; + + for (u32 i = 0; i < 4; i += 4) + { + u32x dgst[4]; + + dgst[0] = packv (tmps, dgst, gid, i + 0); + dgst[1] = packv (tmps, dgst, gid, i + 1); + dgst[2] = packv (tmps, dgst, gid, i + 2); + dgst[3] = packv (tmps, dgst, gid, i + 3); + + for (u32 j = 0; j < LOOP_CNT; j++) + { + u32x h[4]; + + h[0] = MD5M_A; + h[1] = MD5M_B; + h[2] = MD5M_C; + h[3] = MD5M_D; + + u32x w0[4]; + u32x w1[4]; + u32x w2[4]; + u32x w3[4]; + + w0[0] = dgst[0]; + w0[1] = dgst[1]; + w0[2] = dgst[2]; + w0[3] = dgst[3]; + w1[0] = 0x00000080; + 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] = 16 * 8; + w3[3] = 0; + + md5_transform_vector (w0, w1, w2, w3, h); + + dgst[0] = h[0]; + dgst[1] = h[1]; + dgst[2] = h[2]; + dgst[3] = h[3]; + } + + unpackv (tmps, dgst, gid, i + 0, dgst[0]); + unpackv (tmps, dgst, gid, i + 1, dgst[1]); + unpackv (tmps, dgst, gid, i + 2, dgst[2]); + unpackv (tmps, dgst, gid, i + 3, dgst[3]); + } +} + +KERNEL_FQ void m32000_comp (KERN_ATTR_TMPS (netiq_sspr_md5_tmp_t)) +{ + const u64 gid = get_global_id (0); + + if (gid >= GID_CNT) return; + + const u32 r0 = tmps[gid].dgst[0]; + const u32 r1 = tmps[gid].dgst[1]; + const u32 r2 = tmps[gid].dgst[2]; + const u32 r3 = tmps[gid].dgst[3]; + + #define il_pos 0 + + #ifdef KERNEL_STATIC + #include COMPARE_M + #endif +} diff --git a/OpenCL/m32010-pure.cl b/OpenCL/m32010-pure.cl new file mode 100644 index 000000000..c806dce13 --- /dev/null +++ b/OpenCL/m32010-pure.cl @@ -0,0 +1,132 @@ +/** + * Author......: See docs/credits.txt + * License.....: MIT + */ + +#define NEW_SIMD_CODE + +#ifdef KERNEL_STATIC +#include M2S(INCLUDE_PATH/inc_vendor.h) +#include M2S(INCLUDE_PATH/inc_types.h) +#include M2S(INCLUDE_PATH/inc_platform.cl) +#include M2S(INCLUDE_PATH/inc_common.cl) +#include M2S(INCLUDE_PATH/inc_simd.cl) +#include M2S(INCLUDE_PATH/inc_hash_sha1.cl) +#endif + +#define COMPARE_S M2S(INCLUDE_PATH/inc_comp_single.cl) +#define COMPARE_M M2S(INCLUDE_PATH/inc_comp_multi.cl) + +typedef struct netiq_sspr_sha1_tmp +{ + u32 dgst[5]; + +} netiq_sspr_sha1_tmp_t; + +KERNEL_FQ void m32010_init (KERN_ATTR_TMPS (netiq_sspr_sha1_tmp_t)) +{ + /** + * base + */ + + const u64 gid = get_global_id (0); + + if (gid >= GID_CNT) return; + + sha1_ctx_t ctx; + + sha1_init (&ctx); + + sha1_update_global_swap (&ctx, pws[gid].i, pws[gid].pw_len); + + sha1_final (&ctx); + + tmps[gid].dgst[0] = ctx.h[0]; + tmps[gid].dgst[1] = ctx.h[1]; + tmps[gid].dgst[2] = ctx.h[2]; + tmps[gid].dgst[3] = ctx.h[3]; + tmps[gid].dgst[4] = ctx.h[4]; +} + +KERNEL_FQ void m32010_loop (KERN_ATTR_TMPS (netiq_sspr_sha1_tmp_t)) +{ + const u64 gid = get_global_id (0); + + if ((gid * VECT_SIZE) >= GID_CNT) return; + + for (u32 i = 0; i < 5; i += 5) + { + u32x dgst[5]; + + dgst[0] = packv (tmps, dgst, gid, i + 0); + dgst[1] = packv (tmps, dgst, gid, i + 1); + dgst[2] = packv (tmps, dgst, gid, i + 2); + dgst[3] = packv (tmps, dgst, gid, i + 3); + dgst[4] = packv (tmps, dgst, gid, i + 4); + + for (u32 j = 0; j < LOOP_CNT; j++) + { + u32x h[5]; + + h[0] = SHA1M_A; + h[1] = SHA1M_B; + h[2] = SHA1M_C; + h[3] = SHA1M_D; + h[4] = SHA1M_E; + + u32x w0[4]; + u32x w1[4]; + u32x w2[4]; + u32x w3[4]; + + w0[0] = dgst[0]; + w0[1] = dgst[1]; + w0[2] = dgst[2]; + w0[3] = dgst[3]; + w1[0] = dgst[4]; + w1[1] = 0x80000000; + 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] = 20 * 8; + + sha1_transform_vector (w0, w1, w2, w3, h); + + dgst[0] = h[0]; + dgst[1] = h[1]; + dgst[2] = h[2]; + dgst[3] = h[3]; + dgst[4] = h[4]; + } + + unpackv (tmps, dgst, gid, i + 0, dgst[0]); + unpackv (tmps, dgst, gid, i + 1, dgst[1]); + unpackv (tmps, dgst, gid, i + 2, dgst[2]); + unpackv (tmps, dgst, gid, i + 3, dgst[3]); + unpackv (tmps, dgst, gid, i + 4, dgst[4]); + } +} + +KERNEL_FQ void m32010_comp (KERN_ATTR_TMPS (netiq_sspr_sha1_tmp_t)) +{ + const u64 gid = get_global_id (0); + + if (gid >= GID_CNT) return; + + const u32 r0 = tmps[gid].dgst[DGST_R0]; + const u32 r1 = tmps[gid].dgst[DGST_R1]; + const u32 r2 = tmps[gid].dgst[DGST_R2]; + const u32 r3 = tmps[gid].dgst[DGST_R3]; + + #define il_pos 0 + + #ifdef KERNEL_STATIC + #include COMPARE_M + #endif +} diff --git a/OpenCL/m32020-pure.cl b/OpenCL/m32020-pure.cl new file mode 100644 index 000000000..b779676e2 --- /dev/null +++ b/OpenCL/m32020-pure.cl @@ -0,0 +1,134 @@ +/** + * Author......: See docs/credits.txt + * License.....: MIT + */ + +#define NEW_SIMD_CODE + +#ifdef KERNEL_STATIC +#include M2S(INCLUDE_PATH/inc_vendor.h) +#include M2S(INCLUDE_PATH/inc_types.h) +#include M2S(INCLUDE_PATH/inc_platform.cl) +#include M2S(INCLUDE_PATH/inc_common.cl) +#include M2S(INCLUDE_PATH/inc_simd.cl) +#include M2S(INCLUDE_PATH/inc_hash_sha1.cl) +#endif + +#define COMPARE_S M2S(INCLUDE_PATH/inc_comp_single.cl) +#define COMPARE_M M2S(INCLUDE_PATH/inc_comp_multi.cl) + +typedef struct netiq_sspr_sha1_tmp +{ + u32 dgst[5]; + +} netiq_sspr_sha1_tmp_t; + +KERNEL_FQ void m32020_init (KERN_ATTR_TMPS (netiq_sspr_sha1_tmp_t)) +{ + /** + * base + */ + + const u64 gid = get_global_id (0); + + if (gid >= GID_CNT) return; + + sha1_ctx_t ctx; + + sha1_init (&ctx); + + sha1_update_global_swap (&ctx, salt_bufs[SALT_POS_HOST].salt_buf, salt_bufs[SALT_POS_HOST].salt_len); + + sha1_update_global_swap (&ctx, pws[gid].i, pws[gid].pw_len); + + sha1_final (&ctx); + + tmps[gid].dgst[0] = ctx.h[0]; + tmps[gid].dgst[1] = ctx.h[1]; + tmps[gid].dgst[2] = ctx.h[2]; + tmps[gid].dgst[3] = ctx.h[3]; + tmps[gid].dgst[4] = ctx.h[4]; +} + +KERNEL_FQ void m32020_loop (KERN_ATTR_TMPS (netiq_sspr_sha1_tmp_t)) +{ + const u64 gid = get_global_id (0); + + if ((gid * VECT_SIZE) >= GID_CNT) return; + + for (u32 i = 0; i < 5; i += 5) + { + u32x dgst[5]; + + dgst[0] = packv (tmps, dgst, gid, i + 0); + dgst[1] = packv (tmps, dgst, gid, i + 1); + dgst[2] = packv (tmps, dgst, gid, i + 2); + dgst[3] = packv (tmps, dgst, gid, i + 3); + dgst[4] = packv (tmps, dgst, gid, i + 4); + + for (u32 j = 0; j < LOOP_CNT; j++) + { + u32x h[5]; + + h[0] = SHA1M_A; + h[1] = SHA1M_B; + h[2] = SHA1M_C; + h[3] = SHA1M_D; + h[4] = SHA1M_E; + + u32x w0[4]; + u32x w1[4]; + u32x w2[4]; + u32x w3[4]; + + w0[0] = dgst[0]; + w0[1] = dgst[1]; + w0[2] = dgst[2]; + w0[3] = dgst[3]; + w1[0] = dgst[4]; + w1[1] = 0x80000000; + 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] = 20 * 8; + + sha1_transform_vector (w0, w1, w2, w3, h); + + dgst[0] = h[0]; + dgst[1] = h[1]; + dgst[2] = h[2]; + dgst[3] = h[3]; + dgst[4] = h[4]; + } + + unpackv (tmps, dgst, gid, i + 0, dgst[0]); + unpackv (tmps, dgst, gid, i + 1, dgst[1]); + unpackv (tmps, dgst, gid, i + 2, dgst[2]); + unpackv (tmps, dgst, gid, i + 3, dgst[3]); + unpackv (tmps, dgst, gid, i + 4, dgst[4]); + } +} + +KERNEL_FQ void m32020_comp (KERN_ATTR_TMPS (netiq_sspr_sha1_tmp_t)) +{ + const u64 gid = get_global_id (0); + + if (gid >= GID_CNT) return; + + const u32 r0 = tmps[gid].dgst[DGST_R0]; + const u32 r1 = tmps[gid].dgst[DGST_R1]; + const u32 r2 = tmps[gid].dgst[DGST_R2]; + const u32 r3 = tmps[gid].dgst[DGST_R3]; + + #define il_pos 0 + + #ifdef KERNEL_STATIC + #include COMPARE_M + #endif +} diff --git a/OpenCL/m32030-pure.cl b/OpenCL/m32030-pure.cl new file mode 100644 index 000000000..78ea30d56 --- /dev/null +++ b/OpenCL/m32030-pure.cl @@ -0,0 +1,149 @@ +/** + * Author......: See docs/credits.txt + * License.....: MIT + */ + +#define NEW_SIMD_CODE + +#ifdef KERNEL_STATIC +#include M2S(INCLUDE_PATH/inc_vendor.h) +#include M2S(INCLUDE_PATH/inc_types.h) +#include M2S(INCLUDE_PATH/inc_platform.cl) +#include M2S(INCLUDE_PATH/inc_common.cl) +#include M2S(INCLUDE_PATH/inc_simd.cl) +#include M2S(INCLUDE_PATH/inc_hash_sha256.cl) +#endif + +#define COMPARE_S M2S(INCLUDE_PATH/inc_comp_single.cl) +#define COMPARE_M M2S(INCLUDE_PATH/inc_comp_multi.cl) + +typedef struct netiq_sspr_sha256_tmp +{ + u32 dgst[8]; + +} netiq_sspr_sha256_tmp_t; + +KERNEL_FQ void m32030_init (KERN_ATTR_TMPS (netiq_sspr_sha256_tmp_t)) +{ + /** + * base + */ + + const u64 gid = get_global_id (0); + + if (gid >= GID_CNT) return; + + sha256_ctx_t ctx; + + sha256_init (&ctx); + + sha256_update_global_swap (&ctx, salt_bufs[SALT_POS_HOST].salt_buf, salt_bufs[SALT_POS_HOST].salt_len); + + sha256_update_global_swap (&ctx, pws[gid].i, pws[gid].pw_len); + + sha256_final (&ctx); + + tmps[gid].dgst[0] = ctx.h[0]; + tmps[gid].dgst[1] = ctx.h[1]; + tmps[gid].dgst[2] = ctx.h[2]; + tmps[gid].dgst[3] = ctx.h[3]; + tmps[gid].dgst[4] = ctx.h[4]; + tmps[gid].dgst[5] = ctx.h[5]; + tmps[gid].dgst[6] = ctx.h[6]; + tmps[gid].dgst[7] = ctx.h[7]; +} + +KERNEL_FQ void m32030_loop (KERN_ATTR_TMPS (netiq_sspr_sha256_tmp_t)) +{ + const u64 gid = get_global_id (0); + + if ((gid * VECT_SIZE) >= GID_CNT) return; + + for (u32 i = 0; i < 8; i += 8) + { + u32x dgst[8]; + + dgst[0] = packv (tmps, dgst, gid, i + 0); + dgst[1] = packv (tmps, dgst, gid, i + 1); + dgst[2] = packv (tmps, dgst, gid, i + 2); + dgst[3] = packv (tmps, dgst, gid, i + 3); + dgst[4] = packv (tmps, dgst, gid, i + 4); + dgst[5] = packv (tmps, dgst, gid, i + 5); + dgst[6] = packv (tmps, dgst, gid, i + 6); + dgst[7] = packv (tmps, dgst, gid, i + 7); + + for (u32 j = 0; j < LOOP_CNT; j++) + { + u32x h[8]; + + h[0] = SHA256M_A; + h[1] = SHA256M_B; + h[2] = SHA256M_C; + h[3] = SHA256M_D; + h[4] = SHA256M_E; + h[5] = SHA256M_F; + h[6] = SHA256M_G; + h[7] = SHA256M_H; + + u32x w0[4]; + u32x w1[4]; + u32x w2[4]; + u32x w3[4]; + + w0[0] = dgst[0]; + w0[1] = dgst[1]; + w0[2] = dgst[2]; + w0[3] = dgst[3]; + w1[0] = dgst[4]; + w1[1] = dgst[5]; + w1[2] = dgst[6]; + w1[3] = dgst[7]; + w2[0] = 0x80000000; + w2[1] = 0; + w2[2] = 0; + w2[3] = 0; + w3[0] = 0; + w3[1] = 0; + w3[2] = 0; + w3[3] = 32 * 8; + + sha256_transform_vector (w0, w1, w2, w3, h); + + dgst[0] = h[0]; + dgst[1] = h[1]; + dgst[2] = h[2]; + dgst[3] = h[3]; + dgst[4] = h[4]; + dgst[5] = h[5]; + dgst[6] = h[6]; + dgst[7] = h[7]; + } + + unpackv (tmps, dgst, gid, i + 0, dgst[0]); + unpackv (tmps, dgst, gid, i + 1, dgst[1]); + unpackv (tmps, dgst, gid, i + 2, dgst[2]); + unpackv (tmps, dgst, gid, i + 3, dgst[3]); + unpackv (tmps, dgst, gid, i + 4, dgst[4]); + unpackv (tmps, dgst, gid, i + 5, dgst[5]); + unpackv (tmps, dgst, gid, i + 6, dgst[6]); + unpackv (tmps, dgst, gid, i + 7, dgst[7]); + } +} + +KERNEL_FQ void m32030_comp (KERN_ATTR_TMPS (netiq_sspr_sha256_tmp_t)) +{ + const u64 gid = get_global_id (0); + + if (gid >= GID_CNT) return; + + const u32 r0 = tmps[gid].dgst[DGST_R0]; + const u32 r1 = tmps[gid].dgst[DGST_R1]; + const u32 r2 = tmps[gid].dgst[DGST_R2]; + const u32 r3 = tmps[gid].dgst[DGST_R3]; + + #define il_pos 0 + + #ifdef KERNEL_STATIC + #include COMPARE_M + #endif +} diff --git a/OpenCL/m32040-pure.cl b/OpenCL/m32040-pure.cl new file mode 100644 index 000000000..66611bd98 --- /dev/null +++ b/OpenCL/m32040-pure.cl @@ -0,0 +1,173 @@ +/** + * Author......: See docs/credits.txt + * License.....: MIT + */ + +#define NEW_SIMD_CODE + +#ifdef KERNEL_STATIC +#include M2S(INCLUDE_PATH/inc_vendor.h) +#include M2S(INCLUDE_PATH/inc_types.h) +#include M2S(INCLUDE_PATH/inc_platform.cl) +#include M2S(INCLUDE_PATH/inc_common.cl) +#include M2S(INCLUDE_PATH/inc_simd.cl) +#include M2S(INCLUDE_PATH/inc_hash_sha512.cl) +#endif + +#define COMPARE_S M2S(INCLUDE_PATH/inc_comp_single.cl) +#define COMPARE_M M2S(INCLUDE_PATH/inc_comp_multi.cl) + +typedef struct netiq_sspr_sha512_tmp +{ + u64 dgst[8]; + +} netiq_sspr_sha512_tmp_t; + +KERNEL_FQ void m32040_init (KERN_ATTR_TMPS (netiq_sspr_sha512_tmp_t)) +{ + /** + * base + */ + + const u64 gid = get_global_id (0); + + if (gid >= GID_CNT) return; + + sha512_ctx_t ctx; + + sha512_init (&ctx); + + sha512_update_global_swap (&ctx, salt_bufs[SALT_POS_HOST].salt_buf, salt_bufs[SALT_POS_HOST].salt_len); + + sha512_update_global_swap (&ctx, pws[gid].i, pws[gid].pw_len); + + sha512_final (&ctx); + + tmps[gid].dgst[0] = ctx.h[0]; + tmps[gid].dgst[1] = ctx.h[1]; + tmps[gid].dgst[2] = ctx.h[2]; + tmps[gid].dgst[3] = ctx.h[3]; + tmps[gid].dgst[4] = ctx.h[4]; + tmps[gid].dgst[5] = ctx.h[5]; + tmps[gid].dgst[6] = ctx.h[6]; + tmps[gid].dgst[7] = ctx.h[7]; +} + +KERNEL_FQ void m32040_loop (KERN_ATTR_TMPS (netiq_sspr_sha512_tmp_t)) +{ + const u64 gid = get_global_id (0); + + if ((gid * VECT_SIZE) >= GID_CNT) return; + + for (u32 i = 0; i < 8; i += 8) + { + u64x dgst[8]; + + dgst[0] = pack64v (tmps, dgst, gid, i + 0); + dgst[1] = pack64v (tmps, dgst, gid, i + 1); + dgst[2] = pack64v (tmps, dgst, gid, i + 2); + dgst[3] = pack64v (tmps, dgst, gid, i + 3); + dgst[4] = pack64v (tmps, dgst, gid, i + 4); + dgst[5] = pack64v (tmps, dgst, gid, i + 5); + dgst[6] = pack64v (tmps, dgst, gid, i + 6); + dgst[7] = pack64v (tmps, dgst, gid, i + 7); + + for (u32 j = 0; j < LOOP_CNT; j++) + { + u64x h[8]; + + h[0] = SHA512M_A; + h[1] = SHA512M_B; + h[2] = SHA512M_C; + h[3] = SHA512M_D; + h[4] = SHA512M_E; + h[5] = SHA512M_F; + h[6] = SHA512M_G; + h[7] = SHA512M_H; + + u32x w0[4]; + u32x w1[4]; + u32x w2[4]; + u32x w3[4]; + u32x w4[4]; + u32x w5[4]; + u32x w6[4]; + u32x w7[4]; + + w0[0] = h32_from_64 (dgst[0]); + w0[1] = l32_from_64 (dgst[0]); + w0[2] = h32_from_64 (dgst[1]); + w0[3] = l32_from_64 (dgst[1]); + w1[0] = h32_from_64 (dgst[2]); + w1[1] = l32_from_64 (dgst[2]); + w1[2] = h32_from_64 (dgst[3]); + w1[3] = l32_from_64 (dgst[3]); + w2[0] = h32_from_64 (dgst[4]); + w2[1] = l32_from_64 (dgst[4]); + w2[2] = h32_from_64 (dgst[5]); + w2[3] = l32_from_64 (dgst[5]); + w3[0] = h32_from_64 (dgst[6]); + w3[1] = l32_from_64 (dgst[6]); + w3[2] = h32_from_64 (dgst[7]); + w3[3] = l32_from_64 (dgst[7]); + w4[0] = 0x80000000; + w4[1] = 0; + w4[2] = 0; + w4[3] = 0; + w5[0] = 0; + w5[1] = 0; + w5[2] = 0; + w5[3] = 0; + w6[0] = 0; + w6[1] = 0; + w6[2] = 0; + w6[3] = 0; + w7[0] = 0; + w7[1] = 0; + w7[2] = 0; + w7[3] = 64 * 8; + + sha512_transform_vector (w0, w1, w2, w3, w4, w5, w6, w7, h); + + dgst[0] = h[0]; + dgst[1] = h[1]; + dgst[2] = h[2]; + dgst[3] = h[3]; + dgst[4] = h[4]; + dgst[5] = h[5]; + dgst[6] = h[6]; + dgst[7] = h[7]; + } + + unpack64v (tmps, dgst, gid, i + 0, dgst[0]); + unpack64v (tmps, dgst, gid, i + 1, dgst[1]); + unpack64v (tmps, dgst, gid, i + 2, dgst[2]); + unpack64v (tmps, dgst, gid, i + 3, dgst[3]); + unpack64v (tmps, dgst, gid, i + 4, dgst[4]); + unpack64v (tmps, dgst, gid, i + 5, dgst[5]); + unpack64v (tmps, dgst, gid, i + 6, dgst[6]); + unpack64v (tmps, dgst, gid, i + 7, dgst[7]); + } +} + +KERNEL_FQ void m32040_comp (KERN_ATTR_TMPS (netiq_sspr_sha512_tmp_t)) +{ + const u64 gid = get_global_id (0); + const u64 lid = get_local_id (0); + + if (gid >= GID_CNT) return; + + const u64 a = tmps[gid].dgst[7]; + const u64 b = tmps[gid].dgst[3]; + + const u32 r0 = l32_from_64_S (a); + const u32 r1 = h32_from_64_S (a); + const u32 r2 = l32_from_64_S (b); + const u32 r3 = h32_from_64_S (b); + + #define il_pos 0 + + #ifdef KERNEL_STATIC + #include COMPARE_M + #endif +} diff --git a/docs/changes.txt b/docs/changes.txt index 7196734d3..8df583920 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -5,6 +5,8 @@ ## - Added hash-mode: 1Password, mobilekeychain (1Password 8) +- Added hash-mode: Adobe AEM (SSPR, SHA-256 with Salt) +- Added hash-mode: Adobe AEM (SSPR, SHA-512 with Salt) - Added hash-mode: Anope IRC Services (enc_sha256) - Added hash-mode: Bisq .wallet (scrypt) - Added hash-mode: Bitcoin raw private key (P2PKH) @@ -22,6 +24,14 @@ - Added hash-mode: GPG (AES-128/AES-256 (SHA-512($pass))) - Added hash-mode: MetaMask Mobile Wallet - Added hash-mode: MetaMask Wallet (short hash, plaintext check) +- Added hash-mode: NetIQ SSPR (MD5) +- Added hash-mode: NetIQ SSPR (PBKDF2WithHmacSHA1) +- Added hash-mode: NetIQ SSPR (PBKDF2WithHmacSHA256) +- Added hash-mode: NetIQ SSPR (PBKDF2WithHmacSHA512) +- Added hash-mode: NetIQ SSPR (SHA-1 with Salt) +- Added hash-mode: NetIQ SSPR (SHA-256 with Salt) +- Added hash-mode: NetIQ SSPR (SHA-512 with Salt) +- Added hash-mode: NetIQ SSPR (SHA1) - Added hash-mode: SecureCRT MasterPassphrase v2 - Added hash-mode: Veeam VB - Added hash-mode: bcrypt(sha256($pass)) diff --git a/docs/readme.txt b/docs/readme.txt index 7f2db3af1..23a468335 100644 --- a/docs/readme.txt +++ b/docs/readme.txt @@ -288,8 +288,18 @@ NVIDIA GPUs require "NVIDIA Driver" (440.64 or later) and "CUDA Toolkit" (9.0 or - SAP CODVN F/G (PASSCODE) - SAP CODVN F/G (PASSCODE) from RFC_READ_TABLE - SAP CODVN H (PWDSALTEDHASH) iSSHA-1 +- Adobe AEM (SSPR, SHA-256 with Salt) +- Adobe AEM (SSPR, SHA-512 with Salt) - PeopleSoft - PeopleSoft PS_TOKEN +- NetIQ SSPR (MD5) +- NetIQ SSPR (PBKDF2WithHmacSHA1) +- NetIQ SSPR (PBKDF2WithHmacSHA256) +- NetIQ SSPR (PBKDF2WithHmacSHA512) +- NetIQ SSPR (SHA-1 with Salt) +- NetIQ SSPR (SHA-256 with Salt) +- NetIQ SSPR (SHA-512 with Salt) +- NetIQ SSPR (SHA1) - SolarWinds Orion - SolarWinds Orion v2 - SolarWinds Serv-U diff --git a/src/modules/module_32000.c b/src/modules/module_32000.c new file mode 100644 index 000000000..f1e17711a --- /dev/null +++ b/src/modules/module_32000.c @@ -0,0 +1,211 @@ +/** + * 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_5; +static const u32 HASH_CATEGORY = HASH_CATEGORY_EAS; +static const char *HASH_NAME = "NetIQ SSPR (MD5)"; +static const u64 KERN_TYPE = 32000; +static const u32 OPTI_TYPE = OPTI_TYPE_ZERO_BYTE + | OPTI_TYPE_SLOW_HASH_SIMD_LOOP; +static const u64 OPTS_TYPE = OPTS_TYPE_STOCK_MODULE + | OPTS_TYPE_PT_GENERATE_LE + | OPTS_TYPE_PT_ADD80 + | OPTS_TYPE_PT_ADDBITS14; +static const u32 SALT_TYPE = SALT_TYPE_VIRTUAL; +static const char *ST_PASS = "hashcat"; +static const char *ST_HASH = "$sspr$0$100000$NONE$2c8586ef492e3c3dd3795395507dc14f"; + +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 netiq_sspr_md5_tmp +{ + u32 dgst[4]; + +} netiq_sspr_md5_tmp_t; + +static const char *SIGNATURE_NETIQ_SSPR_MD5 = "$sspr$0$100000$NONE$"; + +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 u64 tmp_size = (const u64) sizeof (netiq_sspr_md5_tmp_t); + + return tmp_size; +} + +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; + + hc_token_t token; + + memset (&token, 0, sizeof (hc_token_t)); + + token.token_cnt = 2; + + token.signatures_cnt = 1; + token.signatures_buf[0] = SIGNATURE_NETIQ_SSPR_MD5; + + token.len[0] = strlen (SIGNATURE_NETIQ_SSPR_MD5); + token.attr[0] = TOKEN_ATTR_FIXED_LENGTH + | TOKEN_ATTR_VERIFY_SIGNATURE; + + token.sep[1] = '$'; + token.len[1] = 32; + token.attr[1] = TOKEN_ATTR_FIXED_LENGTH + | TOKEN_ATTR_VERIFY_HEX; + + const int rc_tokenizer = input_tokenizer ((const u8 *) line_buf, line_len, &token); + + if (rc_tokenizer != PARSER_OK) return (rc_tokenizer); + + // iter + + salt->salt_iter = 100000 - 1; + + // digest + + const u8 *hash_pos = token.buf[1]; + + digest[0] = hex_to_u32 (hash_pos + 0); + digest[1] = hex_to_u32 (hash_pos + 8); + digest[2] = hex_to_u32 (hash_pos + 16); + digest[3] = hex_to_u32 (hash_pos + 24); + + 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; + + // digest + + u32 tmp[4]; + + tmp[0] = digest[0]; + tmp[1] = digest[1]; + tmp[2] = digest[2]; + tmp[3] = digest[3]; + + u8 *out_buf = (u8 *) line_buf; + + int out_len = snprintf ((char *) out_buf, line_size, "%s", SIGNATURE_NETIQ_SSPR_MD5); + + out_buf += out_len; + + u32_to_hex (tmp[0], out_buf + 0); + u32_to_hex (tmp[1], out_buf + 8); + u32_to_hex (tmp[2], out_buf + 16); + u32_to_hex (tmp[3], out_buf + 24); + + out_len += 32; + + return out_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_DEFAULT; + module_ctx->module_benchmark_charset = MODULE_DEFAULT; + 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_deprecated_notice = 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_DEFAULT; + module_ctx->module_extra_buffer_size = MODULE_DEFAULT; + module_ctx->module_extra_tmp_size = MODULE_DEFAULT; + module_ctx->module_extra_tuningdb_block = 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_postprocess = 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_DEFAULT; + module_ctx->module_kernel_loops_min = MODULE_DEFAULT; + module_ctx->module_kernel_threads_max = MODULE_DEFAULT; + 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_DEFAULT; + 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; +} diff --git a/src/modules/module_32010.c b/src/modules/module_32010.c new file mode 100644 index 000000000..d82e5ca6a --- /dev/null +++ b/src/modules/module_32010.c @@ -0,0 +1,220 @@ +/** + * 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 = 3; +static const u32 DGST_POS1 = 4; +static const u32 DGST_POS2 = 2; +static const u32 DGST_POS3 = 1; +static const u32 DGST_SIZE = DGST_SIZE_4_5; +static const u32 HASH_CATEGORY = HASH_CATEGORY_EAS; +static const char *HASH_NAME = "NetIQ SSPR (SHA1)"; +static const u64 KERN_TYPE = 32010; +static const u32 OPTI_TYPE = OPTI_TYPE_ZERO_BYTE + | OPTI_TYPE_SLOW_HASH_SIMD_LOOP; +static const u64 OPTS_TYPE = OPTS_TYPE_STOCK_MODULE + | OPTS_TYPE_PT_GENERATE_LE + | OPTS_TYPE_PT_ADD80 + | OPTS_TYPE_PT_ADDBITS15; +static const u32 SALT_TYPE = SALT_TYPE_VIRTUAL; +static const char *ST_PASS = "hashcat"; +static const char *ST_HASH = "$sspr$1$100000$NONE$b3485214dfa55b038a606a183a560dab7db4ecf1"; + +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 netiq_sspr_sha1_tmp +{ + u32 dgst[5]; + +} netiq_sspr_sha1_tmp_t; + +static const char *SIGNATURE_NETIQ_SSPR_SHA1 = "$sspr$1$100000$NONE$"; + +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 u64 tmp_size = (const u64) sizeof (netiq_sspr_sha1_tmp_t); + + return tmp_size; +} + +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; + + hc_token_t token; + + memset (&token, 0, sizeof (hc_token_t)); + + token.token_cnt = 2; + + token.signatures_cnt = 1; + token.signatures_buf[0] = SIGNATURE_NETIQ_SSPR_SHA1; + + token.len[0] = strlen (SIGNATURE_NETIQ_SSPR_SHA1); + token.attr[0] = TOKEN_ATTR_FIXED_LENGTH + | TOKEN_ATTR_VERIFY_SIGNATURE; + + token.sep[1] = '$'; + token.len[1] = 40; + token.attr[1] = TOKEN_ATTR_FIXED_LENGTH + | TOKEN_ATTR_VERIFY_HEX; + + const int rc_tokenizer = input_tokenizer ((const u8 *) line_buf, line_len, &token); + + if (rc_tokenizer != PARSER_OK) return (rc_tokenizer); + + // iter + + salt->salt_iter = 100000 - 1; + + // digest + + const u8 *hash_pos = token.buf[1]; + + digest[0] = hex_to_u32 (hash_pos + 0); + digest[1] = hex_to_u32 (hash_pos + 8); + digest[2] = hex_to_u32 (hash_pos + 16); + digest[3] = hex_to_u32 (hash_pos + 24); + digest[4] = hex_to_u32 (hash_pos + 32); + + digest[0] = byte_swap_32 (digest[0]); + digest[1] = byte_swap_32 (digest[1]); + digest[2] = byte_swap_32 (digest[2]); + digest[3] = byte_swap_32 (digest[3]); + digest[4] = byte_swap_32 (digest[4]); + + 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; + + // digest + + u32 tmp[5]; + + tmp[0] = byte_swap_32 (digest[0]); + tmp[1] = byte_swap_32 (digest[1]); + tmp[2] = byte_swap_32 (digest[2]); + tmp[3] = byte_swap_32 (digest[3]); + tmp[4] = byte_swap_32 (digest[4]); + + u8 *out_buf = (u8 *) line_buf; + + int out_len = snprintf ((char *) out_buf, line_size, "%s", SIGNATURE_NETIQ_SSPR_SHA1); + + out_buf += out_len; + + u32_to_hex (tmp[0], out_buf + 0); + u32_to_hex (tmp[1], out_buf + 8); + u32_to_hex (tmp[2], out_buf + 16); + u32_to_hex (tmp[3], out_buf + 24); + u32_to_hex (tmp[4], out_buf + 32); + + out_len += 40; + + return out_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_DEFAULT; + module_ctx->module_benchmark_charset = MODULE_DEFAULT; + 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_deprecated_notice = 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_DEFAULT; + module_ctx->module_extra_buffer_size = MODULE_DEFAULT; + module_ctx->module_extra_tmp_size = MODULE_DEFAULT; + module_ctx->module_extra_tuningdb_block = 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_postprocess = 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_DEFAULT; + module_ctx->module_kernel_loops_min = MODULE_DEFAULT; + module_ctx->module_kernel_threads_max = MODULE_DEFAULT; + 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_DEFAULT; + 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; +} diff --git a/src/modules/module_32020.c b/src/modules/module_32020.c new file mode 100644 index 000000000..6b35439b2 --- /dev/null +++ b/src/modules/module_32020.c @@ -0,0 +1,255 @@ +/** + * 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 = 3; +static const u32 DGST_POS1 = 4; +static const u32 DGST_POS2 = 2; +static const u32 DGST_POS3 = 1; +static const u32 DGST_SIZE = DGST_SIZE_4_5; +static const u32 HASH_CATEGORY = HASH_CATEGORY_EAS; +static const char *HASH_NAME = "NetIQ SSPR (SHA-1 with Salt)"; +static const u64 KERN_TYPE = 32020; +static const u32 OPTI_TYPE = OPTI_TYPE_ZERO_BYTE + | OPTI_TYPE_SLOW_HASH_SIMD_LOOP; +static const u64 OPTS_TYPE = OPTS_TYPE_STOCK_MODULE + | OPTS_TYPE_ST_BASE64 + | OPTS_TYPE_PT_GENERATE_LE + | OPTS_TYPE_PT_ADD80 + | OPTS_TYPE_PT_ADDBITS15; +static const u32 SALT_TYPE = SALT_TYPE_EMBEDDED; +static const char *ST_PASS = "hashcat"; +static const char *ST_HASH = "$sspr$2$100000$CxCpGqosk9PkCBcoRFp6DLjjRhVEJKK8$a33283d71c2ecaf4f3017b0a89feca2fc879221c"; + +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 netiq_sspr_sha1_tmp +{ + u32 dgst[5]; + +} netiq_sspr_sha1_tmp_t; + +static const char *SIGNATURE_NETIQ_SSPR_SHA1_SALTED = "$sspr$2$100000$"; + +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 u64 tmp_size = (const u64) sizeof (netiq_sspr_sha1_tmp_t); + + return tmp_size; +} + +u32 module_salt_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 salt_min = 32; + + return salt_min; +} + +u32 module_salt_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 salt_max = 32; + + return salt_max; +} + +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; + + hc_token_t token; + + memset (&token, 0, sizeof (hc_token_t)); + + token.token_cnt = 3; + + token.signatures_cnt = 1; + token.signatures_buf[0] = SIGNATURE_NETIQ_SSPR_SHA1_SALTED; + + token.len[0] = strlen (SIGNATURE_NETIQ_SSPR_SHA1_SALTED); + token.attr[0] = TOKEN_ATTR_FIXED_LENGTH + | TOKEN_ATTR_VERIFY_SIGNATURE; + + token.sep[1] = '$'; + token.len[1] = 32; + token.attr[1] = TOKEN_ATTR_FIXED_LENGTH + | TOKEN_ATTR_VERIFY_BASE64A; + + token.sep[2] = '$'; + token.len[2] = 40; + token.attr[2] = TOKEN_ATTR_FIXED_LENGTH + | TOKEN_ATTR_VERIFY_HEX; + + const int rc_tokenizer = input_tokenizer ((const u8 *) line_buf, line_len, &token); + + if (rc_tokenizer != PARSER_OK) return (rc_tokenizer); + + // iter + + salt->salt_iter = 100000 - 1; + + // salt + + const u8 *salt_pos = token.buf[1]; + const int salt_len = token.len[1]; + + salt->salt_len = salt_len; + + memcpy ((u8 *) salt->salt_buf, salt_pos, salt->salt_len); + + // digest + + const u8 *hash_pos = token.buf[2]; + + digest[0] = hex_to_u32 (hash_pos + 0); + digest[1] = hex_to_u32 (hash_pos + 8); + digest[2] = hex_to_u32 (hash_pos + 16); + digest[3] = hex_to_u32 (hash_pos + 24); + digest[4] = hex_to_u32 (hash_pos + 32); + + digest[0] = byte_swap_32 (digest[0]); + digest[1] = byte_swap_32 (digest[1]); + digest[2] = byte_swap_32 (digest[2]); + digest[3] = byte_swap_32 (digest[3]); + digest[4] = byte_swap_32 (digest[4]); + + 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; + + // salt + + u8 *salt_buf = (u8 *) salt->salt_buf; + + // digest + + u32 tmp[5]; + + tmp[0] = byte_swap_32 (digest[0]); + tmp[1] = byte_swap_32 (digest[1]); + tmp[2] = byte_swap_32 (digest[2]); + tmp[3] = byte_swap_32 (digest[3]); + tmp[4] = byte_swap_32 (digest[4]); + + u8 *out_buf = (u8 *) line_buf; + + int out_len = snprintf ((char *) out_buf, line_size, "%s%s$", + SIGNATURE_NETIQ_SSPR_SHA1_SALTED, + salt_buf); + + out_buf += out_len; + + u32_to_hex (tmp[0], out_buf + 0); + u32_to_hex (tmp[1], out_buf + 8); + u32_to_hex (tmp[2], out_buf + 16); + u32_to_hex (tmp[3], out_buf + 24); + u32_to_hex (tmp[4], out_buf + 32); + + out_len += 40; + + return out_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_DEFAULT; + module_ctx->module_benchmark_charset = MODULE_DEFAULT; + 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_deprecated_notice = 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_DEFAULT; + module_ctx->module_extra_buffer_size = MODULE_DEFAULT; + module_ctx->module_extra_tmp_size = MODULE_DEFAULT; + module_ctx->module_extra_tuningdb_block = 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_postprocess = 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_DEFAULT; + module_ctx->module_kernel_loops_min = MODULE_DEFAULT; + module_ctx->module_kernel_threads_max = MODULE_DEFAULT; + 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_DEFAULT; + module_ctx->module_pw_min = MODULE_DEFAULT; + module_ctx->module_salt_max = module_salt_max; + module_ctx->module_salt_min = module_salt_min; + 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; +} diff --git a/src/modules/module_32030.c b/src/modules/module_32030.c new file mode 100644 index 000000000..d2a28f172 --- /dev/null +++ b/src/modules/module_32030.c @@ -0,0 +1,267 @@ +/** + * 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 = 3; +static const u32 DGST_POS1 = 7; +static const u32 DGST_POS2 = 2; +static const u32 DGST_POS3 = 6; +static const u32 DGST_SIZE = DGST_SIZE_4_8; +static const u32 HASH_CATEGORY = HASH_CATEGORY_EAS; +static const char *HASH_NAME = "NetIQ SSPR (SHA-256 with Salt)"; +static const u64 KERN_TYPE = 32030; +static const u32 OPTI_TYPE = OPTI_TYPE_ZERO_BYTE + | OPTI_TYPE_SLOW_HASH_SIMD_LOOP; +static const u64 OPTS_TYPE = OPTS_TYPE_STOCK_MODULE + | OPTS_TYPE_ST_BASE64 + | OPTS_TYPE_PT_GENERATE_LE + | OPTS_TYPE_PT_ADD80 + | OPTS_TYPE_PT_ADDBITS15; +static const u32 SALT_TYPE = SALT_TYPE_EMBEDDED; +static const char *ST_PASS = "hashcat"; +static const char *ST_HASH = "$sspr$3$100000$ODk2NDA5Mjc2NDIwMjMwMjQyMTQ1NzMz$7195873d47c7e3627510862e37fe7cab9bc83b91feecb9864841bf80cff92419"; + +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 netiq_sspr_sha256_tmp +{ + u32 dgst[8]; + +} netiq_sspr_sha256_tmp_t; + +static const char *SIGNATURE_NETIQ_SSPR_SHA256_SALTED = "$sspr$3$100000$"; + +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 u64 tmp_size = (const u64) sizeof (netiq_sspr_sha256_tmp_t); + + return tmp_size; +} + +u32 module_salt_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 salt_min = 32; + + return salt_min; +} + +u32 module_salt_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 salt_max = 32; + + return salt_max; +} + +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; + + hc_token_t token; + + memset (&token, 0, sizeof (hc_token_t)); + + token.token_cnt = 3; + + token.signatures_cnt = 1; + token.signatures_buf[0] = SIGNATURE_NETIQ_SSPR_SHA256_SALTED; + + token.len[0] = strlen (SIGNATURE_NETIQ_SSPR_SHA256_SALTED); + token.attr[0] = TOKEN_ATTR_FIXED_LENGTH + | TOKEN_ATTR_VERIFY_SIGNATURE; + + token.sep[1] = '$'; + token.len[1] = 32; + token.attr[1] = TOKEN_ATTR_FIXED_LENGTH + | TOKEN_ATTR_VERIFY_BASE64A; + + token.sep[2] = '$'; + token.len[2] = 64; + token.attr[2] = TOKEN_ATTR_FIXED_LENGTH + | TOKEN_ATTR_VERIFY_HEX; + + const int rc_tokenizer = input_tokenizer ((const u8 *) line_buf, line_len, &token); + + if (rc_tokenizer != PARSER_OK) return (rc_tokenizer); + + // iter + + salt->salt_iter = 100000 - 1; + + // salt + + const u8 *salt_pos = token.buf[1]; + const int salt_len = token.len[1]; + + salt->salt_len = salt_len; + + memcpy ((u8 *) salt->salt_buf, salt_pos, salt->salt_len); + + // digest + + const u8 *hash_pos = token.buf[2]; + + digest[0] = hex_to_u32 (hash_pos + 0); + digest[1] = hex_to_u32 (hash_pos + 8); + digest[2] = hex_to_u32 (hash_pos + 16); + digest[3] = hex_to_u32 (hash_pos + 24); + digest[4] = hex_to_u32 (hash_pos + 32); + digest[5] = hex_to_u32 (hash_pos + 40); + digest[6] = hex_to_u32 (hash_pos + 48); + digest[7] = hex_to_u32 (hash_pos + 56); + + digest[0] = byte_swap_32 (digest[0]); + digest[1] = byte_swap_32 (digest[1]); + digest[2] = byte_swap_32 (digest[2]); + digest[3] = byte_swap_32 (digest[3]); + digest[4] = byte_swap_32 (digest[4]); + digest[5] = byte_swap_32 (digest[5]); + digest[6] = byte_swap_32 (digest[6]); + digest[7] = byte_swap_32 (digest[7]); + + 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; + + // salt + + u8 *salt_buf = (u8 *) salt->salt_buf; + + // digest + + u32 tmp[8]; + + tmp[0] = byte_swap_32 (digest[0]); + tmp[1] = byte_swap_32 (digest[1]); + tmp[2] = byte_swap_32 (digest[2]); + tmp[3] = byte_swap_32 (digest[3]); + tmp[4] = byte_swap_32 (digest[4]); + tmp[5] = byte_swap_32 (digest[5]); + tmp[6] = byte_swap_32 (digest[6]); + tmp[7] = byte_swap_32 (digest[7]); + + u8 *out_buf = (u8 *) line_buf; + + int out_len = snprintf ((char *) out_buf, line_size, "%s%s$", + SIGNATURE_NETIQ_SSPR_SHA256_SALTED, + salt_buf); + + out_buf += out_len; + + u32_to_hex (tmp[0], out_buf + 0); + u32_to_hex (tmp[1], out_buf + 8); + u32_to_hex (tmp[2], out_buf + 16); + u32_to_hex (tmp[3], out_buf + 24); + u32_to_hex (tmp[4], out_buf + 32); + u32_to_hex (tmp[5], out_buf + 40); + u32_to_hex (tmp[6], out_buf + 48); + u32_to_hex (tmp[7], out_buf + 56); + + out_len += 64; + + return out_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_DEFAULT; + module_ctx->module_benchmark_charset = MODULE_DEFAULT; + 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_deprecated_notice = 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_DEFAULT; + module_ctx->module_extra_buffer_size = MODULE_DEFAULT; + module_ctx->module_extra_tmp_size = MODULE_DEFAULT; + module_ctx->module_extra_tuningdb_block = 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_postprocess = 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_DEFAULT; + module_ctx->module_kernel_loops_min = MODULE_DEFAULT; + module_ctx->module_kernel_threads_max = MODULE_DEFAULT; + 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_DEFAULT; + module_ctx->module_pw_min = MODULE_DEFAULT; + module_ctx->module_salt_max = module_salt_max; + module_ctx->module_salt_min = module_salt_min; + 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; +} diff --git a/src/modules/module_32031.c b/src/modules/module_32031.c new file mode 100644 index 000000000..2ce2cf719 --- /dev/null +++ b/src/modules/module_32031.c @@ -0,0 +1,272 @@ +/** + * 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 = 3; +static const u32 DGST_POS1 = 7; +static const u32 DGST_POS2 = 2; +static const u32 DGST_POS3 = 6; +static const u32 DGST_SIZE = DGST_SIZE_4_8; +static const u32 HASH_CATEGORY = HASH_CATEGORY_EAS; +static const char *HASH_NAME = "Adobe AEM (SSPR, SHA-256 with Salt)"; +static const u64 KERN_TYPE = 32030; +static const u32 OPTI_TYPE = OPTI_TYPE_ZERO_BYTE + | OPTI_TYPE_SLOW_HASH_SIMD_LOOP; +static const u64 OPTS_TYPE = OPTS_TYPE_STOCK_MODULE + | OPTS_TYPE_PT_GENERATE_LE + | OPTS_TYPE_PT_ADD80 + | OPTS_TYPE_PT_ADDBITS15; +static const u32 SALT_TYPE = SALT_TYPE_EMBEDDED; +static const char *ST_PASS = "hashcat"; +static const char *ST_HASH = "$sspr$3$1000$f9bbf1381f481427$a1b45fd7eb190cc7f0bf831698cb777207eebbb4b7ea2abd6fff84be539aae62"; + +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 netiq_sspr_sha256_tmp +{ + u32 dgst[8]; + +} netiq_sspr_sha256_tmp_t; + +static const char *SIGNATURE_ADOBE_AES_SHA256_SALTED = "$sspr$3$1000$"; + +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 u64 tmp_size = (const u64) sizeof (netiq_sspr_sha256_tmp_t); + + return tmp_size; +} + +u32 module_salt_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 salt_min = 16; + + return salt_min; +} + +u32 module_salt_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 salt_max = 16; + + return salt_max; +} + +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; + + hc_token_t token; + + memset (&token, 0, sizeof (hc_token_t)); + + token.token_cnt = 3; + + token.signatures_cnt = 1; + token.signatures_buf[0] = SIGNATURE_ADOBE_AES_SHA256_SALTED; + + token.len[0] = strlen (SIGNATURE_ADOBE_AES_SHA256_SALTED); + token.attr[0] = TOKEN_ATTR_FIXED_LENGTH + | TOKEN_ATTR_VERIFY_SIGNATURE; + + token.sep[1] = '$'; + token.len[1] = 16; + token.attr[1] = TOKEN_ATTR_FIXED_LENGTH; + + if (hashconfig->opts_type & OPTS_TYPE_ST_HEX) + { + token.attr[1] |= TOKEN_ATTR_VERIFY_HEX; + } + + token.sep[2] = '$'; + token.len[2] = 64; + token.attr[2] = TOKEN_ATTR_FIXED_LENGTH + | TOKEN_ATTR_VERIFY_HEX; + + const int rc_tokenizer = input_tokenizer ((const u8 *) line_buf, line_len, &token); + + if (rc_tokenizer != PARSER_OK) return (rc_tokenizer); + + // iter + + salt->salt_iter = 1000 - 1; + + // salt + + const u8 *salt_pos = token.buf[1]; + const int salt_len = token.len[1]; + + const bool parse_rc = generic_salt_decode (hashconfig, salt_pos, salt_len, (u8 *) salt->salt_buf, (int *) &salt->salt_len); + + if (parse_rc == false) return (PARSER_SALT_LENGTH); + + // digest + + const u8 *hash_pos = token.buf[2]; + + digest[0] = hex_to_u32 (hash_pos + 0); + digest[1] = hex_to_u32 (hash_pos + 8); + digest[2] = hex_to_u32 (hash_pos + 16); + digest[3] = hex_to_u32 (hash_pos + 24); + digest[4] = hex_to_u32 (hash_pos + 32); + digest[5] = hex_to_u32 (hash_pos + 40); + digest[6] = hex_to_u32 (hash_pos + 48); + digest[7] = hex_to_u32 (hash_pos + 56); + + digest[0] = byte_swap_32 (digest[0]); + digest[1] = byte_swap_32 (digest[1]); + digest[2] = byte_swap_32 (digest[2]); + digest[3] = byte_swap_32 (digest[3]); + digest[4] = byte_swap_32 (digest[4]); + digest[5] = byte_swap_32 (digest[5]); + digest[6] = byte_swap_32 (digest[6]); + digest[7] = byte_swap_32 (digest[7]); + + 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; + + // salt + + u8 salt_buf[16 + 1]; + + memset (salt_buf, 0, sizeof (salt_buf)); + + generic_salt_encode (hashconfig, (const u8 *) salt->salt_buf, (const int) salt->salt_len, salt_buf); + + // digest + + u32 tmp[8]; + + tmp[0] = byte_swap_32 (digest[0]); + tmp[1] = byte_swap_32 (digest[1]); + tmp[2] = byte_swap_32 (digest[2]); + tmp[3] = byte_swap_32 (digest[3]); + tmp[4] = byte_swap_32 (digest[4]); + tmp[5] = byte_swap_32 (digest[5]); + tmp[6] = byte_swap_32 (digest[6]); + tmp[7] = byte_swap_32 (digest[7]); + + u8 *out_buf = (u8 *) line_buf; + + int out_len = snprintf ((char *) out_buf, line_size, "%s%s$", SIGNATURE_ADOBE_AES_SHA256_SALTED, salt_buf); + + out_buf += out_len; + + u32_to_hex (tmp[0], out_buf + 0); + u32_to_hex (tmp[1], out_buf + 8); + u32_to_hex (tmp[2], out_buf + 16); + u32_to_hex (tmp[3], out_buf + 24); + u32_to_hex (tmp[4], out_buf + 32); + u32_to_hex (tmp[5], out_buf + 40); + u32_to_hex (tmp[6], out_buf + 48); + u32_to_hex (tmp[7], out_buf + 56); + + out_len += 64; + + return out_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_DEFAULT; + module_ctx->module_benchmark_charset = MODULE_DEFAULT; + 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_deprecated_notice = 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_DEFAULT; + module_ctx->module_extra_buffer_size = MODULE_DEFAULT; + module_ctx->module_extra_tmp_size = MODULE_DEFAULT; + module_ctx->module_extra_tuningdb_block = 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_postprocess = 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_DEFAULT; + module_ctx->module_kernel_loops_min = MODULE_DEFAULT; + module_ctx->module_kernel_threads_max = MODULE_DEFAULT; + 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_DEFAULT; + module_ctx->module_pw_min = MODULE_DEFAULT; + module_ctx->module_salt_max = module_salt_max; + module_ctx->module_salt_min = module_salt_min; + 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; +} diff --git a/src/modules/module_32040.c b/src/modules/module_32040.c new file mode 100644 index 000000000..2a8f248af --- /dev/null +++ b/src/modules/module_32040.c @@ -0,0 +1,268 @@ +/** + * 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 = 14; +static const u32 DGST_POS1 = 15; +static const u32 DGST_POS2 = 6; +static const u32 DGST_POS3 = 7; +static const u32 DGST_SIZE = DGST_SIZE_8_8; +static const u32 HASH_CATEGORY = HASH_CATEGORY_EAS; +static const char *HASH_NAME = "NetIQ SSPR (SHA-512 with Salt)"; +static const u64 KERN_TYPE = 32040; +static const u32 OPTI_TYPE = OPTI_TYPE_ZERO_BYTE + | OPTI_TYPE_USES_BITS_64 + | OPTI_TYPE_SLOW_HASH_SIMD_LOOP; +static const u64 OPTS_TYPE = OPTS_TYPE_STOCK_MODULE + | OPTS_TYPE_ST_BASE64 + | OPTS_TYPE_PT_GENERATE_LE + | OPTS_TYPE_PT_ADD80 + | OPTS_TYPE_PT_ADDBITS15; +static const u32 SALT_TYPE = SALT_TYPE_EMBEDDED; +static const char *ST_PASS = "hashcat"; +static const char *ST_HASH = "$sspr$4$100000$NzYwNjMyNDc2MTQ2OTE4NTUzODAyODE3$0ce2e8b8efa4280e6e003d77cb45d45300dff3960c5c073f68303565fe62fe4ff3ada8cee7d3b87d0457335ab0df73c5c64ee1f71ccf6b8bd43a316ecb42ecd4"; + +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 netiq_sspr_sha512_tmp +{ + u64 dgst[8]; + +} netiq_sspr_sha512_tmp_t; + +static const char *SIGNATURE_NETIQ_SSPR_SHA512_SALTED = "$sspr$4$100000$"; + +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 u64 tmp_size = (const u64) sizeof (netiq_sspr_sha512_tmp_t); + + return tmp_size; +} + +u32 module_salt_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 salt_min = 32; + + return salt_min; +} + +u32 module_salt_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 salt_max = 32; + + return salt_max; +} + +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) +{ + u64 *digest = (u64 *) digest_buf; + + hc_token_t token; + + memset (&token, 0, sizeof (hc_token_t)); + + token.token_cnt = 3; + + token.signatures_cnt = 1; + token.signatures_buf[0] = SIGNATURE_NETIQ_SSPR_SHA512_SALTED; + + token.len[0] = strlen (SIGNATURE_NETIQ_SSPR_SHA512_SALTED); + token.attr[0] = TOKEN_ATTR_FIXED_LENGTH + | TOKEN_ATTR_VERIFY_SIGNATURE; + + token.sep[1] = '$'; + token.len[1] = 32; + token.attr[1] = TOKEN_ATTR_FIXED_LENGTH + | TOKEN_ATTR_VERIFY_BASE64A; + + token.sep[2] = '$'; + token.len[2] = 128; + token.attr[2] = TOKEN_ATTR_FIXED_LENGTH + | TOKEN_ATTR_VERIFY_HEX; + + const int rc_tokenizer = input_tokenizer ((const u8 *) line_buf, line_len, &token); + + if (rc_tokenizer != PARSER_OK) return (rc_tokenizer); + + // iter + + salt->salt_iter = 100000 - 1; + + // salt + + const u8 *salt_pos = token.buf[1]; + const int salt_len = token.len[1]; + + salt->salt_len = salt_len; + + memcpy ((u8 *) salt->salt_buf, salt_pos, salt->salt_len); + + // digest + + const u8 *hash_pos = token.buf[2]; + + digest[0] = hex_to_u64 (hash_pos + 0); + digest[1] = hex_to_u64 (hash_pos + 16); + digest[2] = hex_to_u64 (hash_pos + 32); + digest[3] = hex_to_u64 (hash_pos + 48); + digest[4] = hex_to_u64 (hash_pos + 64); + digest[5] = hex_to_u64 (hash_pos + 80); + digest[6] = hex_to_u64 (hash_pos + 96); + digest[7] = hex_to_u64 (hash_pos + 112); + + digest[0] = byte_swap_64 (digest[0]); + digest[1] = byte_swap_64 (digest[1]); + digest[2] = byte_swap_64 (digest[2]); + digest[3] = byte_swap_64 (digest[3]); + digest[4] = byte_swap_64 (digest[4]); + digest[5] = byte_swap_64 (digest[5]); + digest[6] = byte_swap_64 (digest[6]); + digest[7] = byte_swap_64 (digest[7]); + + 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 u64 *digest = (const u64 *) digest_buf; + + // salt + + u8 *salt_buf = (u8 *) salt->salt_buf; + + // digest + + u64 tmp[8]; + + tmp[0] = byte_swap_64 (digest[0]); + tmp[1] = byte_swap_64 (digest[1]); + tmp[2] = byte_swap_64 (digest[2]); + tmp[3] = byte_swap_64 (digest[3]); + tmp[4] = byte_swap_64 (digest[4]); + tmp[5] = byte_swap_64 (digest[5]); + tmp[6] = byte_swap_64 (digest[6]); + tmp[7] = byte_swap_64 (digest[7]); + + u8 *out_buf = (u8 *) line_buf; + + int out_len = snprintf ((char *) out_buf, line_size, "%s%s$", + SIGNATURE_NETIQ_SSPR_SHA512_SALTED, + salt_buf); + + out_buf += out_len; + + u64_to_hex (tmp[0], out_buf + 0); + u64_to_hex (tmp[1], out_buf + 16); + u64_to_hex (tmp[2], out_buf + 32); + u64_to_hex (tmp[3], out_buf + 48); + u64_to_hex (tmp[4], out_buf + 64); + u64_to_hex (tmp[5], out_buf + 80); + u64_to_hex (tmp[6], out_buf + 96); + u64_to_hex (tmp[7], out_buf + 112); + + out_len += 128; + + return out_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_DEFAULT; + module_ctx->module_benchmark_charset = MODULE_DEFAULT; + 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_deprecated_notice = 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_DEFAULT; + module_ctx->module_extra_buffer_size = MODULE_DEFAULT; + module_ctx->module_extra_tmp_size = MODULE_DEFAULT; + module_ctx->module_extra_tuningdb_block = 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_postprocess = 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_DEFAULT; + module_ctx->module_kernel_loops_min = MODULE_DEFAULT; + module_ctx->module_kernel_threads_max = MODULE_DEFAULT; + 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_DEFAULT; + module_ctx->module_pw_min = MODULE_DEFAULT; + module_ctx->module_salt_max = module_salt_max; + module_ctx->module_salt_min = module_salt_min; + 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; +} diff --git a/src/modules/module_32041.c b/src/modules/module_32041.c new file mode 100644 index 000000000..445562e30 --- /dev/null +++ b/src/modules/module_32041.c @@ -0,0 +1,275 @@ +/** + * 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 = 14; +static const u32 DGST_POS1 = 15; +static const u32 DGST_POS2 = 6; +static const u32 DGST_POS3 = 7; +static const u32 DGST_SIZE = DGST_SIZE_8_8; +static const u32 HASH_CATEGORY = HASH_CATEGORY_EAS; +static const char *HASH_NAME = "Adobe AEM (SSPR, SHA-512 with Salt)"; +static const u64 KERN_TYPE = 32040; +static const u32 OPTI_TYPE = OPTI_TYPE_ZERO_BYTE + | OPTI_TYPE_USES_BITS_64 + | OPTI_TYPE_SLOW_HASH_SIMD_LOOP; +static const u64 OPTS_TYPE = OPTS_TYPE_STOCK_MODULE + | OPTS_TYPE_PT_GENERATE_LE + | OPTS_TYPE_PT_ADD80 + | OPTS_TYPE_PT_ADDBITS15; +static const u32 SALT_TYPE = SALT_TYPE_EMBEDDED; +static const char *ST_PASS = "hashcat"; +static const char *ST_HASH = "$sspr$4$1000$9ad596c50a5c9acd$d4cdc3c7d227e3cc57a9c9014b1eff1684808ef40191482cd8ae6e9d7b66211a5f04e4b34f494b0513a5f67b9614c5ff16e95e624a60f41b16b90533f305146e"; + +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 netiq_sspr_sha512_tmp +{ + u64 dgst[8]; + +} netiq_sspr_sha512_tmp_t; + +static const char *SIGNATURE_ADOBE_AEM_SHA512_SALTED = "$sspr$4$1000$"; + +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 u64 tmp_size = (const u64) sizeof (netiq_sspr_sha512_tmp_t); + + return tmp_size; +} + +u32 module_salt_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 salt_min = 16; + + return salt_min; +} + +u32 module_salt_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 salt_max = 16; + + return salt_max; +} + +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) +{ + u64 *digest = (u64 *) digest_buf; + + hc_token_t token; + + memset (&token, 0, sizeof (hc_token_t)); + + token.token_cnt = 3; + + token.signatures_cnt = 1; + token.signatures_buf[0] = SIGNATURE_ADOBE_AEM_SHA512_SALTED; + + token.len[0] = strlen (SIGNATURE_ADOBE_AEM_SHA512_SALTED); + token.attr[0] = TOKEN_ATTR_FIXED_LENGTH + | TOKEN_ATTR_VERIFY_SIGNATURE; + + token.sep[1] = '$'; + token.len[1] = 16; + token.attr[1] = TOKEN_ATTR_FIXED_LENGTH; + + if (hashconfig->opts_type & OPTS_TYPE_ST_HEX) + { + token.attr[1] |= TOKEN_ATTR_VERIFY_HEX; + } + + token.sep[2] = '$'; + token.len[2] = 128; + token.attr[2] = TOKEN_ATTR_FIXED_LENGTH + | TOKEN_ATTR_VERIFY_HEX; + + const int rc_tokenizer = input_tokenizer ((const u8 *) line_buf, line_len, &token); + + if (rc_tokenizer != PARSER_OK) return (rc_tokenizer); + + // iter + + salt->salt_iter = 1000 - 1; + + // salt + + const u8 *salt_pos = token.buf[1]; + const int salt_len = token.len[1]; + + const bool parse_rc = generic_salt_decode (hashconfig, salt_pos, salt_len, (u8 *) salt->salt_buf, (int *) &salt->salt_len); + + if (parse_rc == false) return (PARSER_SALT_LENGTH); + + // digest + + const u8 *hash_pos = token.buf[2]; + + digest[0] = hex_to_u64 (hash_pos + 0); + digest[1] = hex_to_u64 (hash_pos + 16); + digest[2] = hex_to_u64 (hash_pos + 32); + digest[3] = hex_to_u64 (hash_pos + 48); + digest[4] = hex_to_u64 (hash_pos + 64); + digest[5] = hex_to_u64 (hash_pos + 80); + digest[6] = hex_to_u64 (hash_pos + 96); + digest[7] = hex_to_u64 (hash_pos + 112); + + digest[0] = byte_swap_64 (digest[0]); + digest[1] = byte_swap_64 (digest[1]); + digest[2] = byte_swap_64 (digest[2]); + digest[3] = byte_swap_64 (digest[3]); + digest[4] = byte_swap_64 (digest[4]); + digest[5] = byte_swap_64 (digest[5]); + digest[6] = byte_swap_64 (digest[6]); + digest[7] = byte_swap_64 (digest[7]); + + 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 u64 *digest = (const u64 *) digest_buf; + + // salt + + u8 salt_buf[16 + 1]; + + memset (salt_buf, 0, sizeof (salt_buf)); + + generic_salt_encode (hashconfig, (const u8 *) salt->salt_buf, (const int) salt->salt_len, salt_buf); + + // digest + + u64 tmp[8]; + + tmp[0] = byte_swap_64 (digest[0]); + tmp[1] = byte_swap_64 (digest[1]); + tmp[2] = byte_swap_64 (digest[2]); + tmp[3] = byte_swap_64 (digest[3]); + tmp[4] = byte_swap_64 (digest[4]); + tmp[5] = byte_swap_64 (digest[5]); + tmp[6] = byte_swap_64 (digest[6]); + tmp[7] = byte_swap_64 (digest[7]); + + u8 *out_buf = (u8 *) line_buf; + + int out_len = snprintf ((char *) out_buf, line_size, "%s%s$", + SIGNATURE_ADOBE_AEM_SHA512_SALTED, + salt_buf); + + out_buf += out_len; + + u64_to_hex (tmp[0], out_buf + 0); + u64_to_hex (tmp[1], out_buf + 16); + u64_to_hex (tmp[2], out_buf + 32); + u64_to_hex (tmp[3], out_buf + 48); + u64_to_hex (tmp[4], out_buf + 64); + u64_to_hex (tmp[5], out_buf + 80); + u64_to_hex (tmp[6], out_buf + 96); + u64_to_hex (tmp[7], out_buf + 112); + + out_len += 128; + + return out_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_DEFAULT; + module_ctx->module_benchmark_charset = MODULE_DEFAULT; + 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_deprecated_notice = 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_DEFAULT; + module_ctx->module_extra_buffer_size = MODULE_DEFAULT; + module_ctx->module_extra_tmp_size = MODULE_DEFAULT; + module_ctx->module_extra_tuningdb_block = 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_postprocess = 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_DEFAULT; + module_ctx->module_kernel_loops_min = MODULE_DEFAULT; + module_ctx->module_kernel_threads_max = MODULE_DEFAULT; + 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_DEFAULT; + module_ctx->module_pw_min = MODULE_DEFAULT; + module_ctx->module_salt_max = module_salt_max; + module_ctx->module_salt_min = module_salt_min; + 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; +} diff --git a/src/modules/module_32050.c b/src/modules/module_32050.c new file mode 100644 index 000000000..47e0b2c6d --- /dev/null +++ b/src/modules/module_32050.c @@ -0,0 +1,297 @@ +/** + * 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_5; +static const u32 HASH_CATEGORY = HASH_CATEGORY_EAS; +static const char *HASH_NAME = "NetIQ SSPR (PBKDF2WithHmacSHA1)"; +static const u64 KERN_TYPE = 12000; +static const u32 OPTI_TYPE = OPTI_TYPE_ZERO_BYTE + | OPTI_TYPE_SLOW_HASH_SIMD_LOOP; +static const u64 OPTS_TYPE = OPTS_TYPE_STOCK_MODULE + | OPTS_TYPE_PT_GENERATE_LE; +static const u32 SALT_TYPE = SALT_TYPE_EMBEDDED; +static const char *ST_PASS = "hashcat"; +static const char *ST_HASH = "$pbkdf2-hmac-sha1$100000$7134180503252384106490944216249411431665011151428170747164626720$990e0c5f62b1384d48cbe3660329b9741c4a8473"; + +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 pbkdf2_sha1_tmp +{ + u32 ipad[5]; + u32 opad[5]; + + u32 dgst[32]; + u32 out[32]; + +} pbkdf2_sha1_tmp_t; + +typedef struct pbkdf2_sha1 +{ + u32 salt_buf[64]; + +} pbkdf2_sha1_t; + +static const char *SIGNATURE_NETIQ_PBKDF2_HMAC_SHA1 = "$pbkdf2-hmac-sha1$100000$"; + +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) +{ + const u64 esalt_size = (const u64) sizeof (pbkdf2_sha1_t); + + return esalt_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 u64 tmp_size = (const u64) sizeof (pbkdf2_sha1_tmp_t); + + return tmp_size; +} + +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) +{ + // this overrides the reductions of PW_MAX in case optimized kernel is selected + // IOW, even in optimized kernel mode it support length 256 + + const u32 pw_max = PW_MAX; + + return pw_max; +} + +u32 module_salt_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 salt_min = 64; + + return salt_min; +} + +u32 module_salt_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 salt_max = 64; + + return salt_max; +} + +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; + + pbkdf2_sha1_t *pbkdf2_sha1 = (pbkdf2_sha1_t *) esalt_buf; + + hc_token_t token; + + memset (&token, 0, sizeof (hc_token_t)); + + token.token_cnt = 3; + + token.signatures_cnt = 1; + token.signatures_buf[0] = SIGNATURE_NETIQ_PBKDF2_HMAC_SHA1; + + token.len[0] = strlen (SIGNATURE_NETIQ_PBKDF2_HMAC_SHA1); + token.attr[0] = TOKEN_ATTR_FIXED_LENGTH + | TOKEN_ATTR_VERIFY_SIGNATURE; + + token.sep[1] = '$'; + token.len[1] = 64; + token.attr[1] = TOKEN_ATTR_FIXED_LENGTH; + + if (hashconfig->opts_type & OPTS_TYPE_ST_HEX) + { + token.attr[1] |= TOKEN_ATTR_VERIFY_HEX; + } + + token.sep[2] = '$'; + token.len[2] = 40; + token.attr[2] = TOKEN_ATTR_FIXED_LENGTH + | TOKEN_ATTR_VERIFY_HEX; + + const int rc_tokenizer = input_tokenizer ((const u8 *) line_buf, line_len, &token); + + if (rc_tokenizer != PARSER_OK) return (rc_tokenizer); + + // iter + + salt->salt_iter = 100000 - 1; + + // salt + + const u8 *salt_pos = token.buf[1]; + const int salt_len = token.len[1]; + + u8 *salt_ptr = (u8 *) pbkdf2_sha1->salt_buf; + + salt->salt_len = hex_decode (salt_pos, salt_len, salt_ptr); + + salt->salt_buf[0] = pbkdf2_sha1->salt_buf[0]; + salt->salt_buf[1] = pbkdf2_sha1->salt_buf[1]; + salt->salt_buf[2] = pbkdf2_sha1->salt_buf[2]; + salt->salt_buf[3] = pbkdf2_sha1->salt_buf[3]; + salt->salt_buf[4] = salt->salt_iter; + + // hash + + const u8 *hash_pos = token.buf[2]; + + digest[0] = hex_to_u32 (hash_pos + 0); + digest[1] = hex_to_u32 (hash_pos + 8); + digest[2] = hex_to_u32 (hash_pos + 16); + digest[3] = hex_to_u32 (hash_pos + 24); + digest[4] = hex_to_u32 (hash_pos + 32); + + digest[0] = byte_swap_32 (digest[0]); + digest[1] = byte_swap_32 (digest[1]); + digest[2] = byte_swap_32 (digest[2]); + digest[3] = byte_swap_32 (digest[3]); + digest[4] = byte_swap_32 (digest[4]); + + 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; + + pbkdf2_sha1_t *pbkdf2_sha1 = (pbkdf2_sha1_t *) esalt_buf; + + // salt + + u8 salt_buf[64 + 1]; + + memset (salt_buf, 0, sizeof (salt_buf)); + + hex_encode ((u8 *) pbkdf2_sha1->salt_buf, salt->salt_len, salt_buf); + + // digest + + u32 tmp[5]; + + tmp[0] = byte_swap_32 (digest[0]); + tmp[1] = byte_swap_32 (digest[1]); + tmp[2] = byte_swap_32 (digest[2]); + tmp[3] = byte_swap_32 (digest[3]); + tmp[4] = byte_swap_32 (digest[4]); + + u8 *out_buf = (u8 *) line_buf; + + int out_len = snprintf ((char *) out_buf, line_size, "%s%s$", + SIGNATURE_NETIQ_PBKDF2_HMAC_SHA1, + salt_buf); + + out_buf += out_len; + + u32_to_hex (tmp[0], out_buf + 0); + u32_to_hex (tmp[1], out_buf + 8); + u32_to_hex (tmp[2], out_buf + 16); + u32_to_hex (tmp[3], out_buf + 24); + u32_to_hex (tmp[4], out_buf + 32); + + out_len += 40; + + return out_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_DEFAULT; + module_ctx->module_benchmark_charset = MODULE_DEFAULT; + 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_deprecated_notice = 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_extra_tuningdb_block = 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_postprocess = 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_DEFAULT; + module_ctx->module_kernel_loops_min = MODULE_DEFAULT; + module_ctx->module_kernel_threads_max = MODULE_DEFAULT; + 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_salt_max; + module_ctx->module_salt_min = module_salt_min; + 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; +} diff --git a/src/modules/module_32060.c b/src/modules/module_32060.c new file mode 100644 index 000000000..8933dc487 --- /dev/null +++ b/src/modules/module_32060.c @@ -0,0 +1,362 @@ +/** + * 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_64; +static const u32 HASH_CATEGORY = HASH_CATEGORY_EAS; +static const char *HASH_NAME = "NetIQ SSPR (PBKDF2WithHmacSHA256)"; +static const u64 KERN_TYPE = 10900; +static const u32 OPTI_TYPE = OPTI_TYPE_ZERO_BYTE + | OPTI_TYPE_SLOW_HASH_SIMD_LOOP; +static const u64 OPTS_TYPE = OPTS_TYPE_STOCK_MODULE + | OPTS_TYPE_ST_BASE64 + | OPTS_TYPE_PT_GENERATE_LE + | OPTS_TYPE_ST_BASE64; +static const u32 SALT_TYPE = SALT_TYPE_EMBEDDED; +static const char *ST_PASS = "hashcat"; +static const char *ST_HASH = "$pbkdf2-sha256$100000$MDUzMTE4NjQyNDc5NTQxMjAwMjg1OTYxNjAxNDgzNzc$bwYpAyQ2g5PqdnMj8mJ46mkwQbyztw8gEQqnhDHj48c"; + +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 pbkdf2_sha256_tmp +{ + u32 ipad[8]; + u32 opad[8]; + + u32 dgst[32]; + u32 out[32]; + +} pbkdf2_sha256_tmp_t; + +typedef struct pbkdf2_sha256 +{ + u32 salt_buf[64]; + +} pbkdf2_sha256_t; + +static const char *SIGNATURE_NETIQ_PBKDF2_HMAC_SHA256 = "$pbkdf2-sha256$100000$"; + +char *module_jit_build_options (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 hashes_t *hashes, MAYBE_UNUSED const hc_device_param_t *device_param) +{ + char *jit_build_options = NULL; + + // Extra treatment for Apple systems + if (device_param->opencl_platform_vendor_id == VENDOR_ID_APPLE) + { + return jit_build_options; + } + + // NVIDIA GPU + if (device_param->opencl_device_vendor_id == VENDOR_ID_NV) + { + hc_asprintf (&jit_build_options, "-D _unroll"); + } + + // HIP + if (device_param->opencl_device_vendor_id == VENDOR_ID_AMD_USE_HIP) + { + hc_asprintf (&jit_build_options, "-D _unroll"); + } + + // ROCM + if ((device_param->opencl_device_vendor_id == VENDOR_ID_AMD) && (device_param->has_vperm == true)) + { + hc_asprintf (&jit_build_options, "-D _unroll"); + } + + return jit_build_options; +} + +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) +{ + const u64 esalt_size = (const u64) sizeof (pbkdf2_sha256_t); + + return esalt_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 u64 tmp_size = (const u64) sizeof (pbkdf2_sha256_tmp_t); + + return tmp_size; +} + +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) +{ + // this overrides the reductions of PW_MAX in case optimized kernel is selected + // IOW, even in optimized kernel mode it support length 256 + + const u32 pw_max = PW_MAX; + + return pw_max; +} + +u32 module_salt_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 salt_min = 43; + + return salt_min; +} + +u32 module_salt_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 salt_max = 43; + + return salt_max; +} + +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; + + pbkdf2_sha256_t *pbkdf2_sha256 = (pbkdf2_sha256_t *) esalt_buf; + + hc_token_t token; + + memset (&token, 0, sizeof (hc_token_t)); + + token.token_cnt = 3; + + token.signatures_cnt = 1; + token.signatures_buf[0] = SIGNATURE_NETIQ_PBKDF2_HMAC_SHA256; + + token.len[0] = strlen (SIGNATURE_NETIQ_PBKDF2_HMAC_SHA256); + token.attr[0] = TOKEN_ATTR_FIXED_LENGTH + | TOKEN_ATTR_VERIFY_SIGNATURE; + + token.sep[1] = '$'; + token.len[1] = 43; + token.attr[1] = TOKEN_ATTR_FIXED_LENGTH + | TOKEN_ATTR_VERIFY_BASE64B; + + token.sep[2] = '$'; + token.len[2] = 43; + token.attr[2] = TOKEN_ATTR_FIXED_LENGTH + | TOKEN_ATTR_VERIFY_BASE64B; + + const int rc_tokenizer = input_tokenizer ((const u8 *) line_buf, line_len, &token); + + if (rc_tokenizer != PARSER_OK) return (rc_tokenizer); + + u8 tmp_buf[32 + 1]; + int tmp_len; + + // iter + + salt->salt_iter = 100000 - 1; + + // salt + + const u8 *salt_pos = token.buf[1]; + const int salt_len = token.len[1]; + + memset (tmp_buf, 0, sizeof (tmp_buf)); + + tmp_len = base64_decode (ab64_to_int, salt_pos, salt_len, tmp_buf); + + if (tmp_len != 32) return (PARSER_SALT_LENGTH); + + memcpy (pbkdf2_sha256->salt_buf, tmp_buf, tmp_len); + + salt->salt_len = tmp_len; + + salt->salt_buf[0] = pbkdf2_sha256->salt_buf[0]; + salt->salt_buf[1] = pbkdf2_sha256->salt_buf[1]; + salt->salt_buf[2] = pbkdf2_sha256->salt_buf[2]; + salt->salt_buf[3] = pbkdf2_sha256->salt_buf[3]; + salt->salt_buf[4] = salt->salt_iter; + + // hash + + const u8 *hash_pos = token.buf[2]; + const int hash_len = token.len[2]; + + memset (tmp_buf, 0, sizeof (tmp_buf)); + + tmp_len = base64_decode (ab64_to_int, hash_pos, hash_len, tmp_buf); + + if (tmp_len != 32) return (PARSER_HASH_LENGTH); + + memcpy (digest, tmp_buf, tmp_len); + + digest[0] = byte_swap_32 (digest[0]); + digest[1] = byte_swap_32 (digest[1]); + digest[2] = byte_swap_32 (digest[2]); + digest[3] = byte_swap_32 (digest[3]); + digest[4] = byte_swap_32 (digest[4]); + digest[5] = byte_swap_32 (digest[5]); + digest[6] = byte_swap_32 (digest[6]); + digest[7] = byte_swap_32 (digest[7]); + + 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) +{ + u32 *digest = (u32 *) digest_buf; + + pbkdf2_sha256_t *pbkdf2_sha256 = (pbkdf2_sha256_t *) esalt_buf; + + // salt + + u8 salt_buf[44 + 1]; + + memset (salt_buf, 0, sizeof (salt_buf)); + + const size_t salt_len_enc = base64_encode (int_to_ab64, (const u8 *) pbkdf2_sha256->salt_buf, salt->salt_len, salt_buf); + + // remove padding + + for (size_t i = 0; i < salt_len_enc; i++) + { + if (salt_buf[i] == '=') + { + salt_buf[i] = '\0'; + } + } + + // digest + + u32 tmp[9]; + + tmp[0] = byte_swap_32 (digest[0]); + tmp[1] = byte_swap_32 (digest[1]); + tmp[2] = byte_swap_32 (digest[2]); + tmp[3] = byte_swap_32 (digest[3]); + tmp[4] = byte_swap_32 (digest[4]); + tmp[5] = byte_swap_32 (digest[5]); + tmp[6] = byte_swap_32 (digest[6]); + tmp[7] = byte_swap_32 (digest[7]); + tmp[8] = 0; + + u8 hash_buf[44 + 1]; + + memset (hash_buf, 0, sizeof (hash_buf)); + + const size_t hash_len_enc = base64_encode (int_to_ab64, (const u8 *) tmp, 32, hash_buf); + + // remove padding + + for (size_t i = 0; i < hash_len_enc; i++) + { + if (hash_buf[i] == '=') + { + hash_buf[i] = '\0'; + } + } + + u8 *out_buf = (u8 *) line_buf; + + int out_len = snprintf ((char *) out_buf, line_size, "%s%s$%s", + SIGNATURE_NETIQ_PBKDF2_HMAC_SHA256, + salt_buf, + hash_buf); + + return out_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_DEFAULT; + module_ctx->module_benchmark_charset = MODULE_DEFAULT; + 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_deprecated_notice = 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_extra_tuningdb_block = 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_postprocess = 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_jit_build_options; + 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_DEFAULT; + module_ctx->module_kernel_loops_min = MODULE_DEFAULT; + module_ctx->module_kernel_threads_max = MODULE_DEFAULT; + 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_salt_max; + module_ctx->module_salt_min = module_salt_min; + 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; +} diff --git a/src/modules/module_32070.c b/src/modules/module_32070.c new file mode 100644 index 000000000..391f993c4 --- /dev/null +++ b/src/modules/module_32070.c @@ -0,0 +1,310 @@ +/** + * 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_8_16; +static const u32 HASH_CATEGORY = HASH_CATEGORY_EAS; +static const char *HASH_NAME = "NetIQ SSPR (PBKDF2WithHmacSHA512)"; +static const u64 KERN_TYPE = 7100; +static const u32 OPTI_TYPE = OPTI_TYPE_ZERO_BYTE + | OPTI_TYPE_USES_BITS_64 + | OPTI_TYPE_SLOW_HASH_SIMD_LOOP; +static const u64 OPTS_TYPE = OPTS_TYPE_STOCK_MODULE + | OPTS_TYPE_PT_GENERATE_LE; +static const u32 SALT_TYPE = SALT_TYPE_EMBEDDED; +static const char *ST_PASS = "hashcat"; +static const char *ST_HASH = "$pbkdf2-hmac-sha512$100000.0211258841559010919749469547425215185689838310218571790549787198.1659e40e64daf84d635a5f1ed2f5708f6735233bed471994bdc0307b3c5f77597f79bdcdd088d1e79357b383809ddfd84379006b49e14f4ff45c449071478777"; + +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 pbkdf2_sha512_tmp +{ + u64 ipad[8]; + u64 opad[8]; + + u64 dgst[16]; + u64 out[16]; + +} pbkdf2_sha512_tmp_t; + +typedef struct pbkdf2_sha512 +{ + u32 salt_buf[64]; + +} pbkdf2_sha512_t; + +static const char *SIGNATURE_NETIQ_PBKDF2_HMAC_SHA512 = "$pbkdf2-hmac-sha512$100000."; + +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) +{ + const u64 esalt_size = (const u64) sizeof (pbkdf2_sha512_t); + + return esalt_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 u64 tmp_size = (const u64) sizeof (pbkdf2_sha512_tmp_t); + + return tmp_size; +} + +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) +{ + // this overrides the reductions of PW_MAX in case optimized kernel is selected + // IOW, even in optimized kernel mode it support length 256 + + const u32 pw_max = PW_MAX; + + return pw_max; +} + +u32 module_salt_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 salt_min = 64; + + return salt_min; +} + +u32 module_salt_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 salt_max = 64; + + return salt_max; +} + +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) +{ + u64 *digest = (u64 *) digest_buf; + + pbkdf2_sha512_t *pbkdf2_sha512 = (pbkdf2_sha512_t *) esalt_buf; + + hc_token_t token; + + memset (&token, 0, sizeof (hc_token_t)); + + token.token_cnt = 3; + + token.signatures_cnt = 1; + token.signatures_buf[0] = SIGNATURE_NETIQ_PBKDF2_HMAC_SHA512; + + token.len[0] = strlen (SIGNATURE_NETIQ_PBKDF2_HMAC_SHA512); + token.attr[0] = TOKEN_ATTR_FIXED_LENGTH + | TOKEN_ATTR_VERIFY_SIGNATURE; + + token.sep[1] = '.'; + token.len[1] = 64; + token.attr[1] = TOKEN_ATTR_FIXED_LENGTH; + + if (hashconfig->opts_type & OPTS_TYPE_ST_HEX) + { + token.attr[1] |= TOKEN_ATTR_VERIFY_HEX; + } + + token.sep[2] = '.'; + token.len[2] = 128; + token.attr[2] = TOKEN_ATTR_FIXED_LENGTH + | TOKEN_ATTR_VERIFY_HEX; + + const int rc_tokenizer = input_tokenizer ((const u8 *) line_buf, line_len, &token); + + if (rc_tokenizer != PARSER_OK) return (rc_tokenizer); + + // iter + + salt->salt_iter = 100000 - 1; + + // salt + + const u8 *salt_pos = token.buf[1]; + const int salt_len = token.len[1]; + + u8 *salt_ptr = (u8 *) pbkdf2_sha512->salt_buf; + + salt->salt_len = hex_decode (salt_pos, salt_len, salt_ptr); + + salt->salt_buf[0] = pbkdf2_sha512->salt_buf[0]; + salt->salt_buf[1] = pbkdf2_sha512->salt_buf[1]; + salt->salt_buf[2] = pbkdf2_sha512->salt_buf[2]; + salt->salt_buf[3] = pbkdf2_sha512->salt_buf[3]; + salt->salt_buf[4] = salt->salt_iter; + + // hash + + const u8 *hash_pos = token.buf[2]; + + digest[0] = hex_to_u64 (hash_pos + 0); + digest[1] = hex_to_u64 (hash_pos + 16); + digest[2] = hex_to_u64 (hash_pos + 32); + digest[3] = hex_to_u64 (hash_pos + 48); + digest[4] = hex_to_u64 (hash_pos + 64); + digest[5] = hex_to_u64 (hash_pos + 80); + digest[6] = hex_to_u64 (hash_pos + 96); + digest[7] = hex_to_u64 (hash_pos + 112); + + digest[0] = byte_swap_64 (digest[0]); + digest[1] = byte_swap_64 (digest[1]); + digest[2] = byte_swap_64 (digest[2]); + digest[3] = byte_swap_64 (digest[3]); + digest[4] = byte_swap_64 (digest[4]); + digest[5] = byte_swap_64 (digest[5]); + digest[6] = byte_swap_64 (digest[6]); + digest[7] = byte_swap_64 (digest[7]); + + 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) +{ + u64 *digest = (u64 *) digest_buf; + + pbkdf2_sha512_t *pbkdf2_sha512 = (pbkdf2_sha512_t *) esalt_buf; + + // salt + + u8 salt_buf[64 + 1]; + + memset (salt_buf, 0, sizeof (salt_buf)); + + hex_encode ((u8 *) pbkdf2_sha512->salt_buf, salt->salt_len, salt_buf); + + // digest + + u64 tmp[8]; + + tmp[0] = byte_swap_64 (digest[0]); + tmp[1] = byte_swap_64 (digest[1]); + tmp[2] = byte_swap_64 (digest[2]); + tmp[3] = byte_swap_64 (digest[3]); + tmp[4] = byte_swap_64 (digest[4]); + tmp[5] = byte_swap_64 (digest[5]); + tmp[6] = byte_swap_64 (digest[6]); + tmp[7] = byte_swap_64 (digest[7]); + + u8 *out_buf = (u8 *) line_buf; + + int out_len = snprintf ((char *) out_buf, line_size, "%s%s.", + SIGNATURE_NETIQ_PBKDF2_HMAC_SHA512, + salt_buf); + + out_buf += out_len; + + u64_to_hex (tmp[0], out_buf + 0); + u64_to_hex (tmp[1], out_buf + 16); + u64_to_hex (tmp[2], out_buf + 32); + u64_to_hex (tmp[3], out_buf + 48); + u64_to_hex (tmp[4], out_buf + 64); + u64_to_hex (tmp[5], out_buf + 80); + u64_to_hex (tmp[6], out_buf + 96); + u64_to_hex (tmp[7], out_buf + 112); + + out_len += 128; + + return out_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_DEFAULT; + module_ctx->module_benchmark_charset = MODULE_DEFAULT; + 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_deprecated_notice = 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_extra_tuningdb_block = 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_postprocess = 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_DEFAULT; + module_ctx->module_kernel_loops_min = MODULE_DEFAULT; + module_ctx->module_kernel_threads_max = MODULE_DEFAULT; + 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_salt_max; + module_ctx->module_salt_min = module_salt_min; + 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; +} diff --git a/tools/test_modules/m32000.pm b/tools/test_modules/m32000.pm new file mode 100644 index 000000000..44f016466 --- /dev/null +++ b/tools/test_modules/m32000.pm @@ -0,0 +1,71 @@ +#!/usr/bin/env perl + +## +## Author......: See docs/credits.txt +## License.....: MIT +## + +use strict; +use warnings; + +use Digest::MD5; + +sub module_constraints { [[0, 256], [-1, -1], [-1, -1], [-1, -1], [-1, -1]] } + +sub module_generate_hash +{ + my $word = shift; + my $salt = shift; + + my $md5 = Digest::MD5->new; + + $md5->add ($word); + + for (my $i = 1; $i < 100000; $i++) + { + my $tmp = $md5->digest; + + $md5->reset; + + $md5->add ($tmp); + } + + my $digest = $md5->digest; + + my $hash = sprintf ('$sspr$0$100000$NONE$%s', unpack ("H*", $digest)); + + return $hash; +} + +sub module_verify_hash +{ + my $line = shift; + + my $idx = index ($line, ':'); + + return unless $idx >= 0; + + my $hash = substr ($line, 0, $idx); + my $word = substr ($line, $idx + 1); + + return unless substr ($hash, 0, 20) eq '$sspr$0$100000$NONE$'; + + my (undef, $signature, $version, $iter, $salt) = split '\$', $hash; + + return unless defined $signature; + return unless defined $version; + return unless defined $iter; + return unless defined $salt; + + return unless $version == 0; + return unless $iter == 100000; + return unless $salt eq "NONE"; + + my $word_packed = pack_if_HEX_notation ($word); + + my $new_hash = module_generate_hash ($word_packed, $salt); + + return ($new_hash, $word); +} + +1; diff --git a/tools/test_modules/m32010.pm b/tools/test_modules/m32010.pm new file mode 100644 index 000000000..5c472658c --- /dev/null +++ b/tools/test_modules/m32010.pm @@ -0,0 +1,71 @@ +#!/usr/bin/env perl + +## +## Author......: See docs/credits.txt +## License.....: MIT +## + +use strict; +use warnings; + +use Digest::SHA1; + +sub module_constraints { [[0, 256], [-1, -1], [-1, -1], [-1, -1], [-1, -1]] } + +sub module_generate_hash +{ + my $word = shift; + my $salt = shift; + + my $sha1 = Digest::SHA1->new; + + $sha1->add ($word); + + for (my $i = 1; $i < 100000; $i++) + { + my $tmp = $sha1->digest; + + $sha1->reset; + + $sha1->add ($tmp); + } + + my $digest = $sha1->digest; + + my $hash = sprintf ('$sspr$1$100000$NONE$%s', unpack ("H*", $digest)); + + return $hash; +} + +sub module_verify_hash +{ + my $line = shift; + + my $idx = index ($line, ':'); + + return unless $idx >= 0; + + my $hash = substr ($line, 0, $idx); + my $word = substr ($line, $idx + 1); + + return unless substr ($hash, 0, 20) eq '$sspr$1$100000$NONE$'; + + my (undef, $signature, $version, $iter, $salt) = split '\$', $hash; + + return unless defined $signature; + return unless defined $version; + return unless defined $iter; + return unless defined $salt; + + return unless $version == 1; + return unless $iter == 100000; + return unless $salt eq "NONE"; + + my $word_packed = pack_if_HEX_notation ($word); + + my $new_hash = module_generate_hash ($word_packed, $salt); + + return ($new_hash, $word); +} + +1; diff --git a/tools/test_modules/m32020.pm b/tools/test_modules/m32020.pm new file mode 100644 index 000000000..eac5a5ec1 --- /dev/null +++ b/tools/test_modules/m32020.pm @@ -0,0 +1,78 @@ +#!/usr/bin/env perl + +## +## Author......: See docs/credits.txt +## License.....: MIT +## + +use strict; +use warnings; + +use Digest::SHA1; +use MIME::Base64 qw (decode_base64 encode_base64); + +sub module_constraints { [[0, 256], [24, 24], [-1, -1], [-1, -1], [-1, -1]] } + +sub module_generate_hash +{ + my $word = shift; + my $salt = shift; + + my $salt_b64 = encode_base64 ($salt, ""); + + my $sha1 = Digest::SHA1->new; + + $sha1->add ($salt_b64 . $word); + + for (my $i = 1; $i < 100000; $i++) + { + my $tmp = $sha1->digest; + + $sha1->reset; + + $sha1->add ($tmp); + } + + my $digest = $sha1->digest; + + my $hash = sprintf ('$sspr$2$100000$%s$%s', $salt_b64, unpack ("H*", $digest)); + + return $hash; +} + +sub module_verify_hash +{ + my $line = shift; + + my $idx = index ($line, ':'); + + return unless $idx >= 0; + + my $hash = substr ($line, 0, $idx); + my $word = substr ($line, $idx + 1); + + return unless substr ($hash, 0, 15) eq '$sspr$2$100000$'; + + my (undef, $signature, $version, $iter, $salt) = split '\$', $hash; + + return unless defined $signature; + return unless defined $version; + return unless defined $iter; + return unless defined $salt; + + return unless $version == 2; + return unless $iter == 100000; + return unless length $salt == 32; + + my $salt_b64 = decode_base64 ($salt); + + return unless length $salt_b64 == 24; + + my $word_packed = pack_if_HEX_notation ($word); + + my $new_hash = module_generate_hash ($word_packed, $salt_b64); + + return ($new_hash, $word); +} + +1; diff --git a/tools/test_modules/m32030.pm b/tools/test_modules/m32030.pm new file mode 100644 index 000000000..e077f4eca --- /dev/null +++ b/tools/test_modules/m32030.pm @@ -0,0 +1,78 @@ +#!/usr/bin/env perl + +## +## Author......: See docs/credits.txt +## License.....: MIT +## + +use strict; +use warnings; + +use Digest::SHA; +use MIME::Base64 qw (decode_base64 encode_base64); + +sub module_constraints { [[0, 256], [24, 24], [-1, -1], [-1, -1], [-1, -1]] } + +sub module_generate_hash +{ + my $word = shift; + my $salt = shift; + + my $salt_b64 = encode_base64 ($salt, ""); + + my $sha256 = Digest::SHA->new(256); + + $sha256->add ($salt_b64 . $word); + + for (my $i = 1; $i < 100000; $i++) + { + my $tmp = $sha256->digest; + + $sha256->reset; + + $sha256->add ($tmp); + } + + my $digest = $sha256->digest; + + my $hash = sprintf ('$sspr$3$100000$%s$%s', $salt_b64, unpack ("H*", $digest)); + + return $hash; +} + +sub module_verify_hash +{ + my $line = shift; + + my $idx = index ($line, ':'); + + return unless $idx >= 0; + + my $hash = substr ($line, 0, $idx); + my $word = substr ($line, $idx + 1); + + return unless substr ($hash, 0, 15) eq '$sspr$3$100000$'; + + my (undef, $signature, $version, $iter, $salt) = split '\$', $hash; + + return unless defined $signature; + return unless defined $version; + return unless defined $iter; + return unless defined $salt; + + return unless $version == 3; + return unless $iter == 100000; + return unless length $salt == 32; + + my $salt_b64 = decode_base64 ($salt); + + return unless length $salt_b64 == 24; + + my $word_packed = pack_if_HEX_notation ($word); + + my $new_hash = module_generate_hash ($word_packed, $salt_b64); + + return ($new_hash, $word); +} + +1; diff --git a/tools/test_modules/m32031.pm b/tools/test_modules/m32031.pm new file mode 100644 index 000000000..e7f39fc8e --- /dev/null +++ b/tools/test_modules/m32031.pm @@ -0,0 +1,71 @@ +#!/usr/bin/env perl + +## +## Author......: See docs/credits.txt +## License.....: MIT +## + +use strict; +use warnings; + +use Digest::SHA; + +sub module_constraints { [[0, 256], [16, 16], [-1, -1], [-1, -1], [-1, -1]] } + +sub module_generate_hash +{ + my $word = shift; + my $salt = shift; + + my $sha256 = Digest::SHA->new(256); + + $sha256->add ($salt . $word); + + for (my $i = 1; $i < 1000; $i++) + { + my $tmp = $sha256->digest; + + $sha256->reset; + + $sha256->add ($tmp); + } + + my $digest = $sha256->digest; + + my $hash = sprintf ('$sspr$3$1000$%s$%s', $salt, unpack ("H*", $digest)); + + return $hash; +} + +sub module_verify_hash +{ + my $line = shift; + + my $idx = index ($line, ':'); + + return unless $idx >= 0; + + my $hash = substr ($line, 0, $idx); + my $word = substr ($line, $idx + 1); + + return unless substr ($hash, 0, 13) eq '$sspr$3$1000$'; + + my (undef, $signature, $version, $iter, $salt) = split '\$', $hash; + + return unless defined $signature; + return unless defined $version; + return unless defined $iter; + return unless defined $salt; + + return unless $version == 3; + return unless $iter == 1000; + return unless length $salt == 16; + + my $word_packed = pack_if_HEX_notation ($word); + + my $new_hash = module_generate_hash ($word_packed, $salt); + + return ($new_hash, $word); +} + +1; diff --git a/tools/test_modules/m32040.pm b/tools/test_modules/m32040.pm new file mode 100644 index 000000000..5446fa01d --- /dev/null +++ b/tools/test_modules/m32040.pm @@ -0,0 +1,78 @@ +#!/usr/bin/env perl + +## +## Author......: See docs/credits.txt +## License.....: MIT +## + +use strict; +use warnings; + +use Digest::SHA; +use MIME::Base64 qw (decode_base64 encode_base64); + +sub module_constraints { [[0, 256], [24, 24], [-1, -1], [-1, -1], [-1, -1]] } + +sub module_generate_hash +{ + my $word = shift; + my $salt = shift; + + my $salt_b64 = encode_base64 ($salt, ""); + + my $sha512 = Digest::SHA->new(512); + + $sha512->add ($salt_b64 . $word); + + for (my $i = 1; $i < 100000; $i++) + { + my $tmp = $sha512->digest; + + $sha512->reset; + + $sha512->add ($tmp); + } + + my $digest = $sha512->digest; + + my $hash = sprintf ('$sspr$4$100000$%s$%s', $salt_b64, unpack ("H*", $digest)); + + return $hash; +} + +sub module_verify_hash +{ + my $line = shift; + + my $idx = index ($line, ':'); + + return unless $idx >= 0; + + my $hash = substr ($line, 0, $idx); + my $word = substr ($line, $idx + 1); + + return unless substr ($hash, 0, 15) eq '$sspr$4$100000$'; + + my (undef, $signature, $version, $iter, $salt) = split '\$', $hash; + + return unless defined $signature; + return unless defined $version; + return unless defined $iter; + return unless defined $salt; + + return unless $version == 4; + return unless $iter == 100000; + return unless length $salt == 32; + + my $salt_b64 = decode_base64 ($salt); + + return unless length $salt_b64 == 24; + + my $word_packed = pack_if_HEX_notation ($word); + + my $new_hash = module_generate_hash ($word_packed, $salt_b64); + + return ($new_hash, $word); +} + +1; diff --git a/tools/test_modules/m32041.pm b/tools/test_modules/m32041.pm new file mode 100644 index 000000000..380ccabf2 --- /dev/null +++ b/tools/test_modules/m32041.pm @@ -0,0 +1,71 @@ +#!/usr/bin/env perl + +## +## Author......: See docs/credits.txt +## License.....: MIT +## + +use strict; +use warnings; + +use Digest::SHA; + +sub module_constraints { [[0, 256], [16, 16], [-1, -1], [-1, -1], [-1, -1]] } + +sub module_generate_hash +{ + my $word = shift; + my $salt = shift; + + my $sha512 = Digest::SHA->new(512); + + $sha512->add ($salt . $word); + + for (my $i = 1; $i < 1000; $i++) + { + my $tmp = $sha512->digest; + + $sha512->reset; + + $sha512->add ($tmp); + } + + my $digest = $sha512->digest; + + my $hash = sprintf ('$sspr$4$1000$%s$%s', $salt, unpack ("H*", $digest)); + + return $hash; +} + +sub module_verify_hash +{ + my $line = shift; + + my $idx = index ($line, ':'); + + return unless $idx >= 0; + + my $hash = substr ($line, 0, $idx); + my $word = substr ($line, $idx + 1); + + return unless substr ($hash, 0, 13) eq '$sspr$4$1000$'; + + my (undef, $signature, $version, $iter, $salt) = split '\$', $hash; + + return unless defined $signature; + return unless defined $version; + return unless defined $iter; + return unless defined $salt; + + return unless $version == 4; + return unless $iter == 1000; + return unless length $salt == 16; + + my $word_packed = pack_if_HEX_notation ($word); + + my $new_hash = module_generate_hash ($word_packed, $salt); + + return ($new_hash, $word); +} + +1; diff --git a/tools/test_modules/m32050.pm b/tools/test_modules/m32050.pm new file mode 100644 index 000000000..e24e5298b --- /dev/null +++ b/tools/test_modules/m32050.pm @@ -0,0 +1,65 @@ +#!/usr/bin/env perl + +## +## Author......: See docs/credits.txt +## License.....: MIT +## + +use strict; +use warnings; + +use Crypt::PBKDF2; + +sub module_constraints { [[0, 256], [64, 64], [-1, -1], [-1, -1], [-1, -1]] } + +sub module_generate_hash +{ + my $word = shift; + my $salt = shift; + + $salt = pack ("H*", $salt); + + my $kdf = Crypt::PBKDF2->new + ( + hash_class => 'HMACSHA1', + iterations => 100000, + output_len => 20 + ); + + my $key = $kdf->PBKDF2_hex ($salt, $word); + + my $hash = sprintf ('$pbkdf2-hmac-sha1$100000$%s$%s', unpack ("H*", $salt), $key); + + return $hash; +} + +sub module_verify_hash +{ + my $line = shift; + + my $idx = index ($line, ':'); + + return unless $idx >= 0; + + my $hash = substr ($line, 0, $idx); + my $word = substr ($line, $idx + 1); + + return unless substr ($hash, 0, 25) eq '$pbkdf2-hmac-sha1$100000$'; + + my (undef, $signature, $iter, $salt) = split '\$', $hash; + + return unless defined $signature; + return unless defined $iter; + return unless defined $salt; + + return unless $iter == 100000; + return unless length $salt == 64; + + my $word_packed = pack_if_HEX_notation ($word); + + my $new_hash = module_generate_hash ($word_packed, $salt); + + return ($new_hash, $word); +} + +1; diff --git a/tools/test_modules/m32060.pm b/tools/test_modules/m32060.pm new file mode 100644 index 000000000..09f55a781 --- /dev/null +++ b/tools/test_modules/m32060.pm @@ -0,0 +1,80 @@ +#!/usr/bin/env perl + +## +## Author......: See docs/credits.txt +## License.....: MIT +## + +use strict; +use warnings; + +use Crypt::PBKDF2; +use MIME::Base64 qw (encode_base64 decode_base64); + +sub module_constraints { [[0, 256], [32, 32], [-1, -1], [-1, -1], [-1, -1]] } + +sub module_generate_hash +{ + my $word = shift; + my $salt = shift; + + my $pbkdf2 = Crypt::PBKDF2->new + ( + hasher => Crypt::PBKDF2->hasher_from_algorithm ('HMACSHA2', 256), + iterations => 100000, + ); + + my $hash_buf = encode_base64 ($pbkdf2->PBKDF2 ($salt, $word), ""); + + my $salt_buf = encode_base64 ($salt, ""); + + # replace + with . + $hash_buf =~ s/\+/\./g; + $salt_buf =~ s/\+/\./g; + + # remove padding = + $hash_buf =~ s/\=+$//; + $salt_buf =~ s/\=+$//; + + my $hash = sprintf ('$pbkdf2-sha256$100000$%s$%s', $salt_buf, $hash_buf); + + return $hash; +} + +sub module_verify_hash +{ + my $line = shift; + + my $idx = index ($line, ':'); + + return unless $idx >= 0; + + my $hash = substr ($line, 0, $idx); + my $word = substr ($line, $idx + 1); + + return unless substr ($hash, 0, 22) eq '$pbkdf2-sha256$100000$'; + + my (undef, $signature, $iter, $salt) = split '\$', $hash; + + return unless defined $signature; + return unless defined $iter; + return unless defined $salt; + + return unless $iter == 100000; + return unless length $salt == 43; + + $salt =~ s/\./\+/g; + $salt .= '=='; + + my $salt_b64 = decode_base64 ($salt); + + return unless length $salt_b64 == 32; + + my $word_packed = pack_if_HEX_notation ($word); + + my $new_hash = module_generate_hash ($word_packed, $salt_b64); + + return ($new_hash, $word); +} + +1; diff --git a/tools/test_modules/m32070.pm b/tools/test_modules/m32070.pm new file mode 100644 index 000000000..83083f295 --- /dev/null +++ b/tools/test_modules/m32070.pm @@ -0,0 +1,68 @@ +#!/usr/bin/env perl + +## +## Author......: See docs/credits.txt +## License.....: MIT +## + +use strict; +use warnings; + +use Crypt::PBKDF2; + +sub module_constraints { [[0, 256], [64, 64], [-1, -1], [-1, -1], [-1, -1]] } + +sub module_generate_hash +{ + my $word = shift; + my $salt = shift; + + $salt = pack ("H*", $salt); + + my $kdf = Crypt::PBKDF2->new + ( + hasher => Crypt::PBKDF2->hasher_from_algorithm ('HMACSHA2', 512), + iterations => 100000, + ); + + my $key = $kdf->PBKDF2_hex ($salt, $word); + + my $hash = sprintf ('$pbkdf2-hmac-sha512$100000.%s.%s', unpack ("H*", $salt), $key); + + return $hash; +} + +sub module_verify_hash +{ + my $line = shift; + + my $idx = index ($line, ':'); + + return unless $idx >= 0; + + my $hash = substr ($line, 0, $idx); + my $word = substr ($line, $idx + 1); + + return unless substr ($hash, 0, 27) eq '$pbkdf2-hmac-sha512$100000.'; + + my (undef, $signature, $tmp) = split '\$', $hash; + + return unless defined $signature; + return unless defined $tmp; + + my ($iter, $salt) = split '\.', $tmp; + + return unless defined $iter; + return unless defined $salt; + + return unless $iter == 100000; + return unless length $salt == 64; + + my $word_packed = pack_if_HEX_notation ($word); + + my $new_hash = module_generate_hash ($word_packed, $salt); + + return ($new_hash, $word); +} + +1; From 2dd820a084f6bf6f17f9b0c01badd085970cacf8 Mon Sep 17 00:00:00 2001 From: Gabriele Gristina Date: Tue, 16 May 2023 21:19:46 +0200 Subject: [PATCH 03/10] Makefile: prevent make failure with Apple Silicon in case of partial rebuild --- docs/changes.txt | 1 + src/Makefile | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/docs/changes.txt b/docs/changes.txt index 17d4bf2a3..707a631f3 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -93,6 +93,7 @@ - User Options: added --metal-compiler-runtime option - Hardware Monitor: avoid sprintf in src/ext_iokit.c - Help: show supported hash-modes only with -hh +- Makefile: prevent make failure with Apple Silicon in case of partial rebuild * changes v6.2.5 -> v6.2.6 diff --git a/src/Makefile b/src/Makefile index 04c1f7a0b..1e60bfdc7 100644 --- a/src/Makefile +++ b/src/Makefile @@ -646,6 +646,11 @@ endif endif obj/combined.NATIVE.a: $(NATIVE_OBJS) +ifeq ($(UNAME),Darwin) +ifeq ($(IS_APPLE_SILICON),1) + $(RM) -f obj/combined.NATIVE.a +endif +endif $(AR) rcs $@ $^ ifeq ($(UNAME),Darwin) From b865c55ab4af7f938895c4546fb82c7bbee44303 Mon Sep 17 00:00:00 2001 From: Gabriele Gristina Date: Tue, 16 May 2023 21:40:44 +0200 Subject: [PATCH 04/10] Unit Test: removes salt constraints if no salt is used --- tools/test_modules/m00070.pm | 2 +- tools/test_modules/m00170.pm | 2 +- tools/test_modules/m01470.pm | 2 +- tools/test_modules/m01770.pm | 2 +- tools/test_modules/m10870.pm | 2 +- tools/test_modules/m11700.pm | 2 +- tools/test_modules/m24800.pm | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tools/test_modules/m00070.pm b/tools/test_modules/m00070.pm index 9cb545327..7edcbe1ee 100644 --- a/tools/test_modules/m00070.pm +++ b/tools/test_modules/m00070.pm @@ -11,7 +11,7 @@ use warnings; use Digest::MD5 qw (md5_hex); use Encode; -sub module_constraints { [[0, 256], [0, 256], [0, 27], [0, 27], [0, 27]] } +sub module_constraints { [[0, 256], [-1, -1], [0, 27], [-1, -1], [-1, -1]] } sub module_generate_hash { diff --git a/tools/test_modules/m00170.pm b/tools/test_modules/m00170.pm index da8fb866f..45b6eaa10 100644 --- a/tools/test_modules/m00170.pm +++ b/tools/test_modules/m00170.pm @@ -11,7 +11,7 @@ use warnings; use Digest::SHA1 qw (sha1_hex); use Encode; -sub module_constraints { [[0, 256], [0, 256], [0, 27], [0, 27], [0, 27]] } +sub module_constraints { [[0, 256], [-1, -1], [0, 27], [-1, -1], [-1, -1]] } sub module_generate_hash { diff --git a/tools/test_modules/m01470.pm b/tools/test_modules/m01470.pm index 4d7c6182c..1e1469309 100644 --- a/tools/test_modules/m01470.pm +++ b/tools/test_modules/m01470.pm @@ -11,7 +11,7 @@ use warnings; use Digest::SHA qw (sha256_hex); use Encode; -sub module_constraints { [[0, 256], [0, 256], [0, 27], [0, 27], [0, 27]] } +sub module_constraints { [[0, 256], [-1, -1], [0, 27], [-1, -1], [-1, -1]] } sub module_generate_hash { diff --git a/tools/test_modules/m01770.pm b/tools/test_modules/m01770.pm index b50644b97..6b9c63de7 100644 --- a/tools/test_modules/m01770.pm +++ b/tools/test_modules/m01770.pm @@ -11,7 +11,7 @@ use warnings; use Digest::SHA qw (sha512_hex); use Encode; -sub module_constraints { [[0, 256], [0, 256], [0, 27], [0, 27], [0, 27]] } +sub module_constraints { [[0, 256], [-1, -1], [0, 27], [-1, -1], [-1, -1]] } sub module_generate_hash { diff --git a/tools/test_modules/m10870.pm b/tools/test_modules/m10870.pm index 9aaf01efe..53c074c5b 100644 --- a/tools/test_modules/m10870.pm +++ b/tools/test_modules/m10870.pm @@ -11,7 +11,7 @@ use warnings; use Digest::SHA qw (sha384_hex); use Encode; -sub module_constraints { [[0, 256], [0, 256], [0, 27], [0, 27], [0, 27]] } +sub module_constraints { [[0, 256], [-1, -1], [0, 27], [-1, -1], [-1, -1]] } sub module_generate_hash { diff --git a/tools/test_modules/m11700.pm b/tools/test_modules/m11700.pm index 8a0c250f6..0b3b19e3e 100644 --- a/tools/test_modules/m11700.pm +++ b/tools/test_modules/m11700.pm @@ -8,7 +8,7 @@ use strict; use warnings; -sub module_constraints { [[0, 256], [0, 256], [0, 55], [0, 55], [-1, -1]] } +sub module_constraints { [[0, 256], [-1, -1], [0, 55], [-1, -1], [-1, -1]] } sub module_generate_hash { diff --git a/tools/test_modules/m24800.pm b/tools/test_modules/m24800.pm index 00de6fced..e00bf9b83 100644 --- a/tools/test_modules/m24800.pm +++ b/tools/test_modules/m24800.pm @@ -13,7 +13,7 @@ use Digest::HMAC qw (hmac); use Encode qw (encode); use MIME::Base64 qw (encode_base64); -sub module_constraints { [[0, 256], [0, 256], [0, 27], [0, 27], [0, 27]] } +sub module_constraints { [[0, 256], [-1, -1], [0, 27], [-1, -1], [-1, -1]] } sub module_generate_hash { From 7ab1110907d7a6bd0228bf7fe4e26af988af0446 Mon Sep 17 00:00:00 2001 From: Gabriele Gristina Date: Sat, 20 May 2023 03:54:06 +0200 Subject: [PATCH 05/10] Fixed build failure for almost all hash modes that make use of hc_swap64 and/or hc_swap64_S with Apple Metal --- OpenCL/inc_common.cl | 22 ++++++++++++++++++++++ docs/changes.txt | 1 + 2 files changed, 23 insertions(+) diff --git a/OpenCL/inc_common.cl b/OpenCL/inc_common.cl index 0de9924ef..8f1eab60a 100644 --- a/OpenCL/inc_common.cl +++ b/OpenCL/inc_common.cl @@ -1317,6 +1317,16 @@ DECLSPEC u64x hc_swap64 (const u64x v) asm volatile ("mov.b64 %0, {%1, %2};" : "=l"(r.sf) : "r"(tr.sf), "r"(tl.sf)); #endif + #elif defined IS_METAL + + const u32x a0 = h32_from_64 (v); + const u32x a1 = l32_from_64 (v); + + u32x t0 = hc_swap32 (a0); + u32x t1 = hc_swap32 (a1); + + r = hl32_to_64 (t1, t0); + #else #if defined USE_BITSELECT && defined USE_ROTATE @@ -1380,7 +1390,19 @@ DECLSPEC u64 hc_swap64_S (const u64 v) asm volatile ("prmt.b32 %0, %1, 0, 0x0123;" : "=r"(tr) : "r"(ir)); asm volatile ("mov.b64 %0, {%1, %2};" : "=l"(r) : "r"(tr), "r"(tl)); + + #elif defined IS_METAL + + const u32 v0 = h32_from_64_S (v); + const u32 v1 = l32_from_64_S (v); + + u32 t0 = hc_swap32_S (v0); + u32 t1 = hc_swap32_S (v1); + + r = hl32_to_64_S (t1, t0); + #else + #ifdef USE_SWIZZLE r = as_ulong (as_uchar8 (v).s76543210); #else diff --git a/docs/changes.txt b/docs/changes.txt index 9dbe1a5f1..3b9890c83 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -65,6 +65,7 @@ - Fixed build failed for 31700 with Apple Metal - Fixed build failed for 31300 with vector width > 1 - Fixed build failed for 31000/Blake2s with vector width > 1 +- Fixed build failure for almost all hash modes that make use of hc_swap64 and/or hc_swap64_S with Apple Metal - Fixed display problem of the "Optimizers applied" list for algorithms using OPTI_TYPE_SLOW_HASH_SIMD_INIT2 and/or OPTI_TYPE_SLOW_HASH_SIMD_LOOP2 - Fixed incompatible pointer types (salt1 and salt2 buf) in 31700 a3 kernel - Fixed incompatible pointer types (salt1 and salt2 buf) in 3730 a3 kernel From d4a58b5fe538e21c003a9f768a12a7a29b1c377d Mon Sep 17 00:00:00 2001 From: Flagg <97263107+Flaggx1@users.noreply.github.com> Date: Fri, 19 May 2023 23:44:32 -0400 Subject: [PATCH 06/10] Fix get_random_num function to be inclusive of max parameter The get_random_num function does not currently include the max parameter. This causes issues such as the tilde character not being generated with random rule generation. This makes the max parameter value inclusive. --- src/shared.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/shared.c b/src/shared.c index ddfc35848..e301523da 100644 --- a/src/shared.c +++ b/src/shared.c @@ -622,11 +622,11 @@ u32 get_random_num (const u32 min, const u32 max) #if defined (_WIN) - return (((u32) rand () % (max - min)) + min); + return (((u32) rand () % (max - min + 1)) + min); #else - return (((u32) random () % (max - min)) + min); + return (((u32) random () % (max - min + 1)) + min); #endif } From 44d58f9a450a7bca44ce6b1e86e2521b25c0c8eb Mon Sep 17 00:00:00 2001 From: Gabriele Gristina Date: Sat, 20 May 2023 14:02:25 +0200 Subject: [PATCH 07/10] Fixed build failed for 13772 and 13773 with Apple Metal --- OpenCL/m13772-pure.cl | 140 +++++++++++++++++++++----------- OpenCL/m13773-pure.cl | 184 +++++++++++++++++++++++++++++++----------- docs/changes.txt | 1 + 3 files changed, 229 insertions(+), 96 deletions(-) diff --git a/OpenCL/m13772-pure.cl b/OpenCL/m13772-pure.cl index f1fce4e9a..c4b870208 100644 --- a/OpenCL/m13772-pure.cl +++ b/OpenCL/m13772-pure.cl @@ -357,54 +357,98 @@ KERNEL_FQ void m13772_init (KERN_ATTR_TMPS_ESALT (vc64_sbog_tmp_t, vc_t)) streebog512_hmac_update_global_swap (&streebog512_hmac_ctx, salt_bufs[SALT_POS_HOST].salt_buf, 64); - for (u32 i = 0, j = 1; i < 16; i += 8, j += 1) - { - streebog512_hmac_ctx_t streebog512_hmac_ctx2 = streebog512_hmac_ctx; - - u32 w0[4]; - u32 w1[4]; - u32 w2[4]; - u32 w3[4]; - - w0[0] = j; - 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] = 0; - - streebog512_hmac_update_64 (&streebog512_hmac_ctx2, w0, w1, w2, w3, 4); - - streebog512_hmac_final (&streebog512_hmac_ctx2); - - tmps[gid].dgst[i + 0] = streebog512_hmac_ctx2.opad.h[0]; - tmps[gid].dgst[i + 1] = streebog512_hmac_ctx2.opad.h[1]; - tmps[gid].dgst[i + 2] = streebog512_hmac_ctx2.opad.h[2]; - tmps[gid].dgst[i + 3] = streebog512_hmac_ctx2.opad.h[3]; - tmps[gid].dgst[i + 4] = streebog512_hmac_ctx2.opad.h[4]; - tmps[gid].dgst[i + 5] = streebog512_hmac_ctx2.opad.h[5]; - tmps[gid].dgst[i + 6] = streebog512_hmac_ctx2.opad.h[6]; - tmps[gid].dgst[i + 7] = streebog512_hmac_ctx2.opad.h[7]; - - tmps[gid].out[i + 0] = tmps[gid].dgst[i + 0]; - tmps[gid].out[i + 1] = tmps[gid].dgst[i + 1]; - tmps[gid].out[i + 2] = tmps[gid].dgst[i + 2]; - tmps[gid].out[i + 3] = tmps[gid].dgst[i + 3]; - tmps[gid].out[i + 4] = tmps[gid].dgst[i + 4]; - tmps[gid].out[i + 5] = tmps[gid].dgst[i + 5]; - tmps[gid].out[i + 6] = tmps[gid].dgst[i + 6]; - tmps[gid].out[i + 7] = tmps[gid].dgst[i + 7]; - } + u32 i = 0; + u32 j = 1; + + u32 w0[4]; + u32 w1[4]; + u32 w2[4]; + u32 w3[4]; + + streebog512_hmac_ctx_t streebog512_hmac_ctx_v1 = streebog512_hmac_ctx; + + w0[0] = j; + 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] = 0; + + streebog512_hmac_update_64 (&streebog512_hmac_ctx_v1, w0, w1, w2, w3, 4); + + streebog512_hmac_final (&streebog512_hmac_ctx_v1); + + tmps[gid].dgst[i + 0] = streebog512_hmac_ctx_v1.opad.h[0]; + tmps[gid].dgst[i + 1] = streebog512_hmac_ctx_v1.opad.h[1]; + tmps[gid].dgst[i + 2] = streebog512_hmac_ctx_v1.opad.h[2]; + tmps[gid].dgst[i + 3] = streebog512_hmac_ctx_v1.opad.h[3]; + tmps[gid].dgst[i + 4] = streebog512_hmac_ctx_v1.opad.h[4]; + tmps[gid].dgst[i + 5] = streebog512_hmac_ctx_v1.opad.h[5]; + tmps[gid].dgst[i + 6] = streebog512_hmac_ctx_v1.opad.h[6]; + tmps[gid].dgst[i + 7] = streebog512_hmac_ctx_v1.opad.h[7]; + + tmps[gid].out[i + 0] = tmps[gid].dgst[i + 0]; + tmps[gid].out[i + 1] = tmps[gid].dgst[i + 1]; + tmps[gid].out[i + 2] = tmps[gid].dgst[i + 2]; + tmps[gid].out[i + 3] = tmps[gid].dgst[i + 3]; + tmps[gid].out[i + 4] = tmps[gid].dgst[i + 4]; + tmps[gid].out[i + 5] = tmps[gid].dgst[i + 5]; + tmps[gid].out[i + 6] = tmps[gid].dgst[i + 6]; + tmps[gid].out[i + 7] = tmps[gid].dgst[i + 7]; + + i=8; + j=2; + + streebog512_hmac_ctx_t streebog512_hmac_ctx_v2 = streebog512_hmac_ctx; + + w0[0] = j; + 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] = 0; + + streebog512_hmac_update_64 (&streebog512_hmac_ctx_v2, w0, w1, w2, w3, 4); + + streebog512_hmac_final (&streebog512_hmac_ctx_v2); + + tmps[gid].dgst[i + 0] = streebog512_hmac_ctx_v2.opad.h[0]; + tmps[gid].dgst[i + 1] = streebog512_hmac_ctx_v2.opad.h[1]; + tmps[gid].dgst[i + 2] = streebog512_hmac_ctx_v2.opad.h[2]; + tmps[gid].dgst[i + 3] = streebog512_hmac_ctx_v2.opad.h[3]; + tmps[gid].dgst[i + 4] = streebog512_hmac_ctx_v2.opad.h[4]; + tmps[gid].dgst[i + 5] = streebog512_hmac_ctx_v2.opad.h[5]; + tmps[gid].dgst[i + 6] = streebog512_hmac_ctx_v2.opad.h[6]; + tmps[gid].dgst[i + 7] = streebog512_hmac_ctx_v2.opad.h[7]; + + tmps[gid].out[i + 0] = tmps[gid].dgst[i + 0]; + tmps[gid].out[i + 1] = tmps[gid].dgst[i + 1]; + tmps[gid].out[i + 2] = tmps[gid].dgst[i + 2]; + tmps[gid].out[i + 3] = tmps[gid].dgst[i + 3]; + tmps[gid].out[i + 4] = tmps[gid].dgst[i + 4]; + tmps[gid].out[i + 5] = tmps[gid].dgst[i + 5]; + tmps[gid].out[i + 6] = tmps[gid].dgst[i + 6]; + tmps[gid].out[i + 7] = tmps[gid].dgst[i + 7]; } KERNEL_FQ void m13772_loop (KERN_ATTR_TMPS_ESALT (vc64_sbog_tmp_t, vc_t)) diff --git a/OpenCL/m13773-pure.cl b/OpenCL/m13773-pure.cl index 3551d5560..55f14890c 100644 --- a/OpenCL/m13773-pure.cl +++ b/OpenCL/m13773-pure.cl @@ -422,54 +422,142 @@ KERNEL_FQ void m13773_init (KERN_ATTR_TMPS_ESALT (vc64_sbog_tmp_t, vc_t)) streebog512_hmac_update_global_swap (&streebog512_hmac_ctx, salt_bufs[SALT_POS_HOST].salt_buf, 64); - for (u32 i = 0, j = 1; i < 24; i += 8, j += 1) - { - streebog512_hmac_ctx_t streebog512_hmac_ctx2 = streebog512_hmac_ctx; - - u32 w0[4]; - u32 w1[4]; - u32 w2[4]; - u32 w3[4]; - - w0[0] = j; - 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] = 0; - - streebog512_hmac_update_64 (&streebog512_hmac_ctx2, w0, w1, w2, w3, 4); - - streebog512_hmac_final (&streebog512_hmac_ctx2); - - tmps[gid].dgst[i + 0] = streebog512_hmac_ctx2.opad.h[0]; - tmps[gid].dgst[i + 1] = streebog512_hmac_ctx2.opad.h[1]; - tmps[gid].dgst[i + 2] = streebog512_hmac_ctx2.opad.h[2]; - tmps[gid].dgst[i + 3] = streebog512_hmac_ctx2.opad.h[3]; - tmps[gid].dgst[i + 4] = streebog512_hmac_ctx2.opad.h[4]; - tmps[gid].dgst[i + 5] = streebog512_hmac_ctx2.opad.h[5]; - tmps[gid].dgst[i + 6] = streebog512_hmac_ctx2.opad.h[6]; - tmps[gid].dgst[i + 7] = streebog512_hmac_ctx2.opad.h[7]; - - tmps[gid].out[i + 0] = tmps[gid].dgst[i + 0]; - tmps[gid].out[i + 1] = tmps[gid].dgst[i + 1]; - tmps[gid].out[i + 2] = tmps[gid].dgst[i + 2]; - tmps[gid].out[i + 3] = tmps[gid].dgst[i + 3]; - tmps[gid].out[i + 4] = tmps[gid].dgst[i + 4]; - tmps[gid].out[i + 5] = tmps[gid].dgst[i + 5]; - tmps[gid].out[i + 6] = tmps[gid].dgst[i + 6]; - tmps[gid].out[i + 7] = tmps[gid].dgst[i + 7]; - } + u32 i = 0; + u32 j = 1; + + u32 w0[4]; + u32 w1[4]; + u32 w2[4]; + u32 w3[4]; + + streebog512_hmac_ctx_t streebog512_hmac_ctx_v1 = streebog512_hmac_ctx; + + w0[0] = j; + 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] = 0; + + streebog512_hmac_update_64 (&streebog512_hmac_ctx_v1, w0, w1, w2, w3, 4); + + streebog512_hmac_final (&streebog512_hmac_ctx_v1); + + tmps[gid].dgst[i + 0] = streebog512_hmac_ctx_v1.opad.h[0]; + tmps[gid].dgst[i + 1] = streebog512_hmac_ctx_v1.opad.h[1]; + tmps[gid].dgst[i + 2] = streebog512_hmac_ctx_v1.opad.h[2]; + tmps[gid].dgst[i + 3] = streebog512_hmac_ctx_v1.opad.h[3]; + tmps[gid].dgst[i + 4] = streebog512_hmac_ctx_v1.opad.h[4]; + tmps[gid].dgst[i + 5] = streebog512_hmac_ctx_v1.opad.h[5]; + tmps[gid].dgst[i + 6] = streebog512_hmac_ctx_v1.opad.h[6]; + tmps[gid].dgst[i + 7] = streebog512_hmac_ctx_v1.opad.h[7]; + + tmps[gid].out[i + 0] = tmps[gid].dgst[i + 0]; + tmps[gid].out[i + 1] = tmps[gid].dgst[i + 1]; + tmps[gid].out[i + 2] = tmps[gid].dgst[i + 2]; + tmps[gid].out[i + 3] = tmps[gid].dgst[i + 3]; + tmps[gid].out[i + 4] = tmps[gid].dgst[i + 4]; + tmps[gid].out[i + 5] = tmps[gid].dgst[i + 5]; + tmps[gid].out[i + 6] = tmps[gid].dgst[i + 6]; + tmps[gid].out[i + 7] = tmps[gid].dgst[i + 7]; + + i = 8; + j = 2; + + streebog512_hmac_ctx_t streebog512_hmac_ctx_v2 = streebog512_hmac_ctx; + + w0[0] = j; + 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] = 0; + + streebog512_hmac_update_64 (&streebog512_hmac_ctx_v2, w0, w1, w2, w3, 4); + + streebog512_hmac_final (&streebog512_hmac_ctx_v2); + + tmps[gid].dgst[i + 0] = streebog512_hmac_ctx_v2.opad.h[0]; + tmps[gid].dgst[i + 1] = streebog512_hmac_ctx_v2.opad.h[1]; + tmps[gid].dgst[i + 2] = streebog512_hmac_ctx_v2.opad.h[2]; + tmps[gid].dgst[i + 3] = streebog512_hmac_ctx_v2.opad.h[3]; + tmps[gid].dgst[i + 4] = streebog512_hmac_ctx_v2.opad.h[4]; + tmps[gid].dgst[i + 5] = streebog512_hmac_ctx_v2.opad.h[5]; + tmps[gid].dgst[i + 6] = streebog512_hmac_ctx_v2.opad.h[6]; + tmps[gid].dgst[i + 7] = streebog512_hmac_ctx_v2.opad.h[7]; + + tmps[gid].out[i + 0] = tmps[gid].dgst[i + 0]; + tmps[gid].out[i + 1] = tmps[gid].dgst[i + 1]; + tmps[gid].out[i + 2] = tmps[gid].dgst[i + 2]; + tmps[gid].out[i + 3] = tmps[gid].dgst[i + 3]; + tmps[gid].out[i + 4] = tmps[gid].dgst[i + 4]; + tmps[gid].out[i + 5] = tmps[gid].dgst[i + 5]; + tmps[gid].out[i + 6] = tmps[gid].dgst[i + 6]; + tmps[gid].out[i + 7] = tmps[gid].dgst[i + 7]; + + i = 16; + j = 3; + + streebog512_hmac_ctx_t streebog512_hmac_ctx_v3 = streebog512_hmac_ctx; + + w0[0] = j; + 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] = 0; + + streebog512_hmac_update_64 (&streebog512_hmac_ctx_v3, w0, w1, w2, w3, 4); + + streebog512_hmac_final (&streebog512_hmac_ctx_v3); + + tmps[gid].dgst[i + 0] = streebog512_hmac_ctx_v3.opad.h[0]; + tmps[gid].dgst[i + 1] = streebog512_hmac_ctx_v3.opad.h[1]; + tmps[gid].dgst[i + 2] = streebog512_hmac_ctx_v3.opad.h[2]; + tmps[gid].dgst[i + 3] = streebog512_hmac_ctx_v3.opad.h[3]; + tmps[gid].dgst[i + 4] = streebog512_hmac_ctx_v3.opad.h[4]; + tmps[gid].dgst[i + 5] = streebog512_hmac_ctx_v3.opad.h[5]; + tmps[gid].dgst[i + 6] = streebog512_hmac_ctx_v3.opad.h[6]; + tmps[gid].dgst[i + 7] = streebog512_hmac_ctx_v3.opad.h[7]; + + tmps[gid].out[i + 0] = tmps[gid].dgst[i + 0]; + tmps[gid].out[i + 1] = tmps[gid].dgst[i + 1]; + tmps[gid].out[i + 2] = tmps[gid].dgst[i + 2]; + tmps[gid].out[i + 3] = tmps[gid].dgst[i + 3]; + tmps[gid].out[i + 4] = tmps[gid].dgst[i + 4]; + tmps[gid].out[i + 5] = tmps[gid].dgst[i + 5]; + tmps[gid].out[i + 6] = tmps[gid].dgst[i + 6]; + tmps[gid].out[i + 7] = tmps[gid].dgst[i + 7]; } KERNEL_FQ void m13773_loop (KERN_ATTR_TMPS_ESALT (vc64_sbog_tmp_t, vc_t)) diff --git a/docs/changes.txt b/docs/changes.txt index 9dbe1a5f1..e96a0836b 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -60,6 +60,7 @@ - Fixed bug in input_tokenizer when TOKEN_ATTR_FIXED_LENGTH is used and refactor modules - Added verification of token buffer length when using TOKEN_ATTR_FIXED_LENGTH - Fixed build failed for 4410 with vector width > 1 +- Fixed build failed for 13772 and 13773 with Apple Metal - Fixed build failed for 18400 with Apple Metal - Fixed build failed for 18600 with Apple Metal - Fixed build failed for 31700 with Apple Metal From 5ceb8c7688692d5a0ddc0179c00107cb794022b0 Mon Sep 17 00:00:00 2001 From: jsteube Date: Sun, 21 May 2023 11:07:33 +0000 Subject: [PATCH 08/10] Add SCRYPT 16k:8:1 tunings for 4090 --- tunings/Module_08900.hctune | 1 + tunings/Module_15700.hctune | 1 + tunings/Module_22700.hctune | 1 + tunings/Module_27700.hctune | 1 + tunings/Module_28200.hctune | 1 + 5 files changed, 5 insertions(+) diff --git a/tunings/Module_08900.hctune b/tunings/Module_08900.hctune index e9ed6e64d..8aabacba9 100644 --- a/tunings/Module_08900.hctune +++ b/tunings/Module_08900.hctune @@ -29,6 +29,7 @@ GeForce_RTX_3060_Ti * 8900 1 51 GeForce_RTX_3070 * 8900 1 46 A GeForce_RTX_3090 * 8900 1 82 A GeForce_RTX_3090_Ti * 8900 1 84 A +GeForce_RTX_4090 * 8900 1 180 A NVS_510 * 8900 1 12 A ALIAS_AMD_RX480 * 8900 1 15 A ALIAS_AMD_Vega64 * 8900 1 30 A diff --git a/tunings/Module_15700.hctune b/tunings/Module_15700.hctune index fca474826..2e99098ee 100644 --- a/tunings/Module_15700.hctune +++ b/tunings/Module_15700.hctune @@ -29,6 +29,7 @@ GeForce_RTX_3060_Ti * 15700 1 11 GeForce_RTX_3070 * 15700 1 22 A GeForce_RTX_3090 * 15700 1 82 A GeForce_RTX_3090_Ti * 15700 1 84 A +GeForce_RTX_4090 * 15700 1 180 A ALIAS_AMD_RX480 * 15700 1 58 A ALIAS_AMD_Vega64 * 15700 1 53 A ALIAS_AMD_MI100 * 15700 1 120 A diff --git a/tunings/Module_22700.hctune b/tunings/Module_22700.hctune index 1b9b35414..2409eefff 100644 --- a/tunings/Module_22700.hctune +++ b/tunings/Module_22700.hctune @@ -29,6 +29,7 @@ GeForce_RTX_3060_Ti * 22700 1 51 GeForce_RTX_3070 * 22700 1 46 A GeForce_RTX_3090 * 22700 1 82 A GeForce_RTX_3090_Ti * 22700 1 84 A +GeForce_RTX_4090 * 22700 1 180 A NVS_510 * 22700 1 12 A ALIAS_AMD_RX480 * 22700 1 15 A ALIAS_AMD_Vega64 * 22700 1 30 A diff --git a/tunings/Module_27700.hctune b/tunings/Module_27700.hctune index d94f61094..4121ae1a4 100644 --- a/tunings/Module_27700.hctune +++ b/tunings/Module_27700.hctune @@ -29,6 +29,7 @@ GeForce_RTX_3060_Ti * 27700 1 51 GeForce_RTX_3070 * 27700 1 46 A GeForce_RTX_3090 * 27700 1 82 A GeForce_RTX_3090_Ti * 27700 1 84 A +GeForce_RTX_4090 * 27700 1 180 A NVS_510 * 27700 1 12 A ALIAS_AMD_RX480 * 27700 1 15 A ALIAS_AMD_Vega64 * 27700 1 30 A diff --git a/tunings/Module_28200.hctune b/tunings/Module_28200.hctune index 98b4c27e6..a01f9a24d 100644 --- a/tunings/Module_28200.hctune +++ b/tunings/Module_28200.hctune @@ -29,6 +29,7 @@ GeForce_RTX_3060_Ti * 28200 1 51 GeForce_RTX_3070 * 28200 1 46 A GeForce_RTX_3090 * 28200 1 82 A GeForce_RTX_3090_Ti * 28200 1 84 A +GeForce_RTX_4090 * 28200 1 180 A NVS_510 * 28200 1 12 A ALIAS_AMD_RX480 * 28200 1 15 A ALIAS_AMD_Vega64 * 28200 1 30 A From 5dcc9a5d8b53ddd18c1329e27f4eb5623fb3c774 Mon Sep 17 00:00:00 2001 From: jsteube Date: Tue, 23 May 2023 12:31:54 +0000 Subject: [PATCH 09/10] Rename hash-modes 33100, 33200 to 32100, 32200 --- OpenCL/{m33100-pure.cl => m32100-pure.cl} | 10 +++++----- OpenCL/{m33200-pure.cl => m32200-pure.cl} | 12 ++++++------ docs/changes.txt | 2 ++ docs/readme.txt | 2 ++ src/modules/{module_33100.c => module_32100.c} | 2 +- src/modules/{module_33200.c => module_32200.c} | 2 +- tools/test_modules/{m33100.pm => m32100.pm} | 0 tools/test_modules/{m33200.pm => m32200.pm} | 0 8 files changed, 17 insertions(+), 13 deletions(-) rename OpenCL/{m33100-pure.cl => m32100-pure.cl} (99%) rename OpenCL/{m33200-pure.cl => m32200-pure.cl} (99%) rename src/modules/{module_33100.c => module_32100.c} (99%) rename src/modules/{module_33200.c => module_32200.c} (99%) rename tools/test_modules/{m33100.pm => m32100.pm} (100%) rename tools/test_modules/{m33200.pm => m32200.pm} (100%) diff --git a/OpenCL/m33100-pure.cl b/OpenCL/m32100-pure.cl similarity index 99% rename from OpenCL/m33100-pure.cl rename to OpenCL/m32100-pure.cl index a7869ea33..a1e9fe227 100755 --- a/OpenCL/m33100-pure.cl +++ b/OpenCL/m32100-pure.cl @@ -116,7 +116,7 @@ DECLSPEC void hmac_sha1_run_V (PRIVATE_AS u32x *w0, PRIVATE_AS u32x *w1, PRIVATE sha1_transform_vector (w0, w1, w2, w3, digest); } -KERNEL_FQ void m33100_init (KERN_ATTR_TMPS_ESALT (krb5asrep_17_tmp_t, krb5asrep_17_t)) +KERNEL_FQ void m32100_init (KERN_ATTR_TMPS_ESALT (krb5asrep_17_tmp_t, krb5asrep_17_t)) { /** * base @@ -194,7 +194,7 @@ KERNEL_FQ void m33100_init (KERN_ATTR_TMPS_ESALT (krb5asrep_17_tmp_t, krb5asrep_ } } -KERNEL_FQ void m33100_loop (KERN_ATTR_TMPS_ESALT (krb5asrep_17_tmp_t, krb5asrep_17_t)) +KERNEL_FQ void m32100_loop (KERN_ATTR_TMPS_ESALT (krb5asrep_17_tmp_t, krb5asrep_17_t)) { /** * base @@ -282,7 +282,7 @@ KERNEL_FQ void m33100_loop (KERN_ATTR_TMPS_ESALT (krb5asrep_17_tmp_t, krb5asrep_ } } -KERNEL_FQ void m33100_comp (KERN_ATTR_TMPS_ESALT (krb5asrep_17_tmp_t, krb5asrep_17_t)) +KERNEL_FQ void m32100_comp (KERN_ATTR_TMPS_ESALT (krb5asrep_17_tmp_t, krb5asrep_17_t)) { /** * base @@ -451,7 +451,7 @@ KERNEL_FQ void m33100_comp (KERN_ATTR_TMPS_ESALT (krb5asrep_17_tmp_t, krb5asrep_ For AS-REP EncASRepPart: The first byte is 0x79 (01 1 11001, where 01 = "class=APPLICATION", 1 = "form=constructed", 11001 is application type 25) - + According to RFC4120 Section 5.4.2: "Some implementations unconditionally send an encrypted EncTGSRepPart (application tag number 26) in this field regardless of whether the reply is a AS-REP or a TGS-REP. In the interest of compatibility, implementors MAY relax the check on the tag number of the decrypted ENC-PART" @@ -526,7 +526,7 @@ KERNEL_FQ void m33100_comp (KERN_ATTR_TMPS_ESALT (krb5asrep_17_tmp_t, krb5asrep_ if (((decrypted_block[0] & 0x00ff80ff) == 0x00300079) || ((decrypted_block[0] & 0x00ff80ff) == 0x0030007a) || - ((decrypted_block[0] & 0xFF00FFFF) == 0x30008179) || + ((decrypted_block[0] & 0xFF00FFFF) == 0x30008179) || ((decrypted_block[0] & 0xFF00FFFF) == 0x3000817a) || ((decrypted_block[0] & 0x0000FFFF) == 0x00008279 && (decrypted_block[1] & 0x000000FF) == 0x00000030) || ((decrypted_block[0] & 0x0000FFFF) == 0x0000827a && (decrypted_block[1] & 0x000000FF) == 0x00000030)) diff --git a/OpenCL/m33200-pure.cl b/OpenCL/m32200-pure.cl similarity index 99% rename from OpenCL/m33200-pure.cl rename to OpenCL/m32200-pure.cl index 26f9840c8..9a9d999ae 100755 --- a/OpenCL/m33200-pure.cl +++ b/OpenCL/m32200-pure.cl @@ -116,7 +116,7 @@ DECLSPEC void hmac_sha1_run_V (PRIVATE_AS u32x *w0, PRIVATE_AS u32x *w1, PRIVATE sha1_transform_vector (w0, w1, w2, w3, digest); } -KERNEL_FQ void m33200_init (KERN_ATTR_TMPS_ESALT (krb5asrep_18_tmp_t, krb5asrep_18_t)) +KERNEL_FQ void m32200_init (KERN_ATTR_TMPS_ESALT (krb5asrep_18_tmp_t, krb5asrep_18_t)) { /** * base @@ -194,7 +194,7 @@ KERNEL_FQ void m33200_init (KERN_ATTR_TMPS_ESALT (krb5asrep_18_tmp_t, krb5asrep_ } } -KERNEL_FQ void m33200_loop (KERN_ATTR_TMPS_ESALT (krb5asrep_18_tmp_t, krb5asrep_18_t)) +KERNEL_FQ void m32200_loop (KERN_ATTR_TMPS_ESALT (krb5asrep_18_tmp_t, krb5asrep_18_t)) { /** * base @@ -282,7 +282,7 @@ KERNEL_FQ void m33200_loop (KERN_ATTR_TMPS_ESALT (krb5asrep_18_tmp_t, krb5asrep_ } } -KERNEL_FQ void m33200_comp (KERN_ATTR_TMPS_ESALT (krb5asrep_18_tmp_t, krb5asrep_18_t)) +KERNEL_FQ void m32200_comp (KERN_ATTR_TMPS_ESALT (krb5asrep_18_tmp_t, krb5asrep_18_t)) { /** * base @@ -511,7 +511,7 @@ KERNEL_FQ void m33200_comp (KERN_ATTR_TMPS_ESALT (krb5asrep_18_tmp_t, krb5asrep_ For AS-REP EncASRepPart: The first byte is 0x79 (01 1 11001, where 01 = "class=APPLICATION", 1 = "form=constructed", 11001 is application type 25) - + According to RFC4120 Section 5.4.2: "Some implementations unconditionally send an encrypted EncTGSRepPart (application tag number 26) in this field regardless of whether the reply is a AS-REP or a TGS-REP. In the interest of compatibility, implementors MAY relax the check on the tag number of the decrypted ENC-PART" @@ -586,7 +586,7 @@ KERNEL_FQ void m33200_comp (KERN_ATTR_TMPS_ESALT (krb5asrep_18_tmp_t, krb5asrep_ if (((decrypted_block[0] & 0x00ff80ff) == 0x00300079) || ((decrypted_block[0] & 0x00ff80ff) == 0x0030007a) || - ((decrypted_block[0] & 0xFF00FFFF) == 0x30008179) || + ((decrypted_block[0] & 0xFF00FFFF) == 0x30008179) || ((decrypted_block[0] & 0xFF00FFFF) == 0x3000817a) || ((decrypted_block[0] & 0x0000FFFF) == 0x00008279 && (decrypted_block[1] & 0x000000FF) == 0x00000030) || ((decrypted_block[0] & 0x0000FFFF) == 0x0000827a && (decrypted_block[1] & 0x000000FF) == 0x00000030)) @@ -809,7 +809,7 @@ KERNEL_FQ void m33200_comp (KERN_ATTR_TMPS_ESALT (krb5asrep_18_tmp_t, krb5asrep_ block[11] = esalt_bufs[DIGESTS_OFFSET_HOST].edata2[block_position + 11]; aes256_decrypt_cbc (aes_cts_decrypt_ks, block, decrypted_block, aes_iv, s_td0, s_td1, s_td2, s_td3, s_td4); - + w0[0] = hc_swap32_S (decrypted_block[0]); w0[1] = hc_swap32_S (decrypted_block[1]); w0[2] = hc_swap32_S (decrypted_block[2]); diff --git a/docs/changes.txt b/docs/changes.txt index 9dbe1a5f1..8bd9bf062 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -20,6 +20,8 @@ - Added hash-mode: GPG (AES-128/AES-256 (SHA-1($pass))) - Added hash-mode: GPG (AES-128/AES-256 (SHA-256($pass))) - Added hash-mode: GPG (AES-128/AES-256 (SHA-512($pass))) +- Added hash-mode: Kerberos 5, etype 17, AS-REP +- Added hash-mode: Kerberos 5, etype 18, AS-REP - Added hash-mode: MetaMask Mobile Wallet - Added hash-mode: MetaMask Wallet (short hash, plaintext check) - Added hash-mode: SecureCRT MasterPassphrase v2 diff --git a/docs/readme.txt b/docs/readme.txt index 7f2db3af1..1c2132b6f 100644 --- a/docs/readme.txt +++ b/docs/readme.txt @@ -193,9 +193,11 @@ NVIDIA GPUs require "NVIDIA Driver" (440.64 or later) and "CUDA Toolkit" (9.0 or - Kerberos 5, etype 17, TGS-REP - Kerberos 5, etype 17, Pre-Auth - Kerberos 5, etype 17, DB +- Kerberos 5, etype 17, AS-REP - Kerberos 5, etype 18, TGS-REP - Kerberos 5, etype 18, Pre-Auth - Kerberos 5, etype 18, DB +- Kerberos 5, etype 18, AS-REP - Kerberos 5, etype 23, AS-REQ Pre-Auth - Kerberos 5, etype 23, TGS-REP - Kerberos 5, etype 23, AS-REP diff --git a/src/modules/module_33100.c b/src/modules/module_32100.c similarity index 99% rename from src/modules/module_33100.c rename to src/modules/module_32100.c index e34a1a677..1b4488097 100755 --- a/src/modules/module_33100.c +++ b/src/modules/module_32100.c @@ -18,7 +18,7 @@ static const u32 DGST_POS3 = 3; static const u32 DGST_SIZE = DGST_SIZE_4_4; static const u32 HASH_CATEGORY = HASH_CATEGORY_NETWORK_PROTOCOL; static const char *HASH_NAME = "Kerberos 5, etype 17, AS-REP"; -static const u64 KERN_TYPE = 33100; +static const u64 KERN_TYPE = 32100; static const u32 OPTI_TYPE = OPTI_TYPE_ZERO_BYTE | OPTI_TYPE_NOT_ITERATED | OPTI_TYPE_SLOW_HASH_SIMD_LOOP; diff --git a/src/modules/module_33200.c b/src/modules/module_32200.c similarity index 99% rename from src/modules/module_33200.c rename to src/modules/module_32200.c index 508565136..b081c7833 100755 --- a/src/modules/module_33200.c +++ b/src/modules/module_32200.c @@ -18,7 +18,7 @@ static const u32 DGST_POS3 = 3; static const u32 DGST_SIZE = DGST_SIZE_4_4; static const u32 HASH_CATEGORY = HASH_CATEGORY_NETWORK_PROTOCOL; static const char *HASH_NAME = "Kerberos 5, etype 18, AS-REP"; -static const u64 KERN_TYPE = 33200; +static const u64 KERN_TYPE = 32200; static const u32 OPTI_TYPE = OPTI_TYPE_ZERO_BYTE | OPTI_TYPE_NOT_ITERATED | OPTI_TYPE_SLOW_HASH_SIMD_LOOP; diff --git a/tools/test_modules/m33100.pm b/tools/test_modules/m32100.pm similarity index 100% rename from tools/test_modules/m33100.pm rename to tools/test_modules/m32100.pm diff --git a/tools/test_modules/m33200.pm b/tools/test_modules/m32200.pm similarity index 100% rename from tools/test_modules/m33200.pm rename to tools/test_modules/m32200.pm From 1037acdf5827f6ea1d93c6deaca65dde0f37d712 Mon Sep 17 00:00:00 2001 From: jsteube Date: Mon, 29 May 2023 20:22:30 +0000 Subject: [PATCH 10/10] Remove entries on fixed issues of hash-modes which did not exist at the time of last release --- docs/changes.txt | 5 ----- 1 file changed, 5 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index f6be03171..9c098e9d7 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -74,12 +74,8 @@ - Fixed build failed for 4410 with vector width > 1 - Fixed build failed for 18400 with Apple Metal - Fixed build failed for 18600 with Apple Metal -- Fixed build failed for 31700 with Apple Metal -- Fixed build failed for 31300 with vector width > 1 -- Fixed build failed for 31000/Blake2s with vector width > 1 - Fixed build failure for almost all hash modes that make use of hc_swap64 and/or hc_swap64_S with Apple Metal - Fixed display problem of the "Optimizers applied" list for algorithms using OPTI_TYPE_SLOW_HASH_SIMD_INIT2 and/or OPTI_TYPE_SLOW_HASH_SIMD_LOOP2 -- Fixed incompatible pointer types (salt1 and salt2 buf) in 31700 a3 kernel - Fixed incompatible pointer types (salt1 and salt2 buf) in 3730 a3 kernel - Fixed minimum password length in module of hash-mode 28200 - Handle signed/unsigned PDF permission P value for all PDF hash-modes @@ -109,7 +105,6 @@ - Hardware Monitor: avoid sprintf in src/ext_iokit.c - Help: show supported hash-modes only with -hh - Makefile: prevent make failure with Apple Silicon in case of partial rebuild -- Unit tests: add test modules for hash-modes 31500 and 31600 and handle them in tools/test.pl * changes v6.2.5 -> v6.2.6