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; token_t token; token.token_cnt = 3; token.signatures_cnt = 1; token.signatures_buf[0] = SIGNATURE_MYSQL_AUTH; token.len[0] = 9; token.attr[0] = TOKEN_ATTR_FIXED_LENGTH | TOKEN_ATTR_VERIFY_SIGNATURE; token.sep[1] = '*'; token.len_min[1] = 40; token.len_max[1] = 40; token.attr[1] = TOKEN_ATTR_VERIFY_LENGTH | TOKEN_ATTR_VERIFY_HEX; token.sep[2] = '*'; token.len_min[2] = 40; token.len_max[2] = 40; token.attr[2] = TOKEN_ATTR_VERIFY_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); // 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]); /* * store 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); return (PARSER_OK); }
bool GDBDebugServer::cmd_write_memory(gdb_cmd & cmd) { size_t s = cmd.data.find(','); size_t s2 = cmd.data.find(':'); if ((s == std::string::npos) || (s2 == std::string::npos)) { gdbDebugServer.warning("Malformed write memory request received: %s", cmd.data.c_str()); return send_cmd_ack("E01"); } u32 addr = hex_to_u32(cmd.data.substr(0, s)); u32 len = hex_to_u32(cmd.data.substr(s + 1, s2 - s - 1)); const char* data_ptr = (cmd.data.c_str()) + s2 + 1; for (u32 i = 0; i < len; ++i) { if (vm::check_addr(addr + i, 1, vm::page_allocated | vm::page_writable)) { u8 val; int res = sscanf_s(data_ptr, "%02hhX", &val); if (!res) { gdbDebugServer.warning("Couldn't read u8 from string %s", data_ptr); return send_cmd_ack("E02"); } data_ptr += 2; vm::write8(addr + i, val); } else { return send_cmd_ack("E03"); } } return send_cmd_ack("OK"); }
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; token_t token; token.token_cnt = 2; token.sep[0] = hashconfig->separator; token.len_min[0] = 40; token.len_max[0] = 40; token.attr[0] = TOKEN_ATTR_VERIFY_LENGTH | TOKEN_ATTR_VERIFY_HEX; token.len_min[1] = 20; token.len_max[1] = 20; token.attr[1] = TOKEN_ATTR_VERIFY_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 *hash_pos = token.buf[0]; 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]); if (hashconfig->opti_type & OPTI_TYPE_OPTIMIZED_KERNEL) { digest[0] -= SHA1M_A; digest[1] -= SHA1M_B; digest[2] -= SHA1M_C; digest[3] -= SHA1M_D; digest[4] -= SHA1M_E; } 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); return (PARSER_OK); }
bool GDBDebugServer::set_reg(std::shared_ptr<ppu_thread> thread, u32 rid, std::string value) { switch (rid) { case 64: thread->cia = static_cast<u32>(hex_to_u64(value)); return true; //msr? case 65: return true; case 66: thread->cr_unpack(hex_to_u32(value)); return true; case 67: thread->lr = hex_to_u64(value); return true; case 68: thread->ctr = hex_to_u64(value); return true; //xer case 69: return true; //fpscr case 70: return true; default: if (rid > 70) return false; if (rid > 31) { u64 val = hex_to_u64(value); thread->fpr[rid - 32] = reinterpret_cast<f64&>(val); } else { thread->gpr[rid] = hex_to_u64(value); } return true; } }
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; token_t token; token.token_cnt = 2; token.sep[0] = hashconfig->separator; token.len_min[0] = 32; token.len_max[0] = 32; token.attr[0] = TOKEN_ATTR_VERIFY_LENGTH | TOKEN_ATTR_VERIFY_HEX; token.len_min[1] = SALT_MIN; token.len_max[1] = SALT_MAX; token.attr[1] = TOKEN_ATTR_VERIFY_LENGTH; if (hashconfig->opts_type & OPTS_TYPE_ST_HEX) { token.len_min[1] *= 2; token.len_max[1] *= 2; token.attr[1] |= 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 *hash_pos = token.buf[0]; 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); 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); return (PARSER_OK); }
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; token_t token; token.token_cnt = 1; token.len_min[0] = 64; token.len_max[0] = 64; token.attr[0] = TOKEN_ATTR_VERIFY_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 *hash_pos = token.buf[0]; 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]); if (hashconfig->opti_type & OPTI_TYPE_OPTIMIZED_KERNEL) { digest[0] -= SHA256M_A; digest[1] -= SHA256M_B; digest[2] -= SHA256M_C; digest[3] -= SHA256M_D; digest[4] -= SHA256M_E; digest[5] -= SHA256M_F; digest[6] -= SHA256M_G; digest[7] -= SHA256M_H; } return (PARSER_OK); }
bool GDBDebugServer::cmd_read_memory(gdb_cmd & cmd) { size_t s = cmd.data.find(','); u32 addr = hex_to_u32(cmd.data.substr(0, s)); u32 len = hex_to_u32(cmd.data.substr(s + 1)); std::string result; result.reserve(len * 2); for (u32 i = 0; i < len; ++i) { if (vm::check_addr(addr, 1, vm::page_allocated | vm::page_readable)) { result += to_hexbyte(vm::read8(addr + i)); } else { break; //result += "xx"; } } if (len && !result.length()) { //nothing read return send_cmd_ack("E01"); } return send_cmd_ack(result); }
bool GDBDebugServer::cmd_read_register(gdb_cmd & cmd) { if (!select_thread(general_ops_thread_id)) { return send_cmd_ack("E02"); } auto th = selected_thread.lock(); if (th->id_type() == 1) { auto ppu = std::static_pointer_cast<ppu_thread>(th); u32 rid = hex_to_u32(cmd.data); std::string result = get_reg(ppu, rid); if (!result.length()) { gdbDebugServer.warning("Wrong register id %d", rid); return send_cmd_ack("E01"); } return send_cmd_ack(result); } gdbDebugServer.warning("Unimplemented thread type %d", th->id_type()); return send_cmd_ack(""); }
int module_hash_decode_potfile (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, MAYBE_UNUSED void *tmps) { wpa_pmkid_t *wpa_pmkid = (wpa_pmkid_t *) esalt_buf; wpa_pmk_tmp_t *wpa_pmk_tmp = (wpa_pmk_tmp_t *) tmps; // here we have in line_hash_buf: PMK*essid:password // but we don't care about the password // PMK wpa_pmk_tmp->out[0] = hex_to_u32 ((const u8 *) line_buf + 0); wpa_pmk_tmp->out[1] = hex_to_u32 ((const u8 *) line_buf + 8); wpa_pmk_tmp->out[2] = hex_to_u32 ((const u8 *) line_buf + 16); wpa_pmk_tmp->out[3] = hex_to_u32 ((const u8 *) line_buf + 24); wpa_pmk_tmp->out[4] = hex_to_u32 ((const u8 *) line_buf + 32); wpa_pmk_tmp->out[5] = hex_to_u32 ((const u8 *) line_buf + 40); wpa_pmk_tmp->out[6] = hex_to_u32 ((const u8 *) line_buf + 48); wpa_pmk_tmp->out[7] = hex_to_u32 ((const u8 *) line_buf + 56); // essid char *sep_pos = strrchr (line_buf, ':'); if (sep_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED); if ((line_buf + 64) != sep_pos) return (PARSER_HASH_LENGTH); char *essid_pos = sep_pos + 1; const int essid_len = strlen (essid_pos); if (essid_len & 1) return (PARSER_SALT_VALUE); if (essid_len > 64) return (PARSER_SALT_VALUE); wpa_pmkid->essid_len = hex_decode ((const u8 *) essid_pos, essid_len, (u8 *) wpa_pmkid->essid_buf); return PARSER_OK; }
bool GDBDebugServer::cmd_write_register(gdb_cmd & cmd) { if (!select_thread(general_ops_thread_id)) { return send_cmd_ack("E02"); } auto th = selected_thread.lock(); if (th->id_type() == 1) { auto ppu = std::static_pointer_cast<ppu_thread>(th); size_t eq_pos = cmd.data.find('='); if (eq_pos == std::string::npos) { gdbDebugServer.warning("Wrong write_register cmd data %s", cmd.data.c_str()); return send_cmd_ack("E02"); } u32 rid = hex_to_u32(cmd.data.substr(0, eq_pos)); std::string value = cmd.data.substr(eq_pos + 1); if (!set_reg(ppu, rid, value)) { gdbDebugServer.warning("Wrong register id %d", rid); return send_cmd_ack("E01"); } return send_cmd_ack("OK"); } gdbDebugServer.warning("Unimplemented thread type %d", th->id_type()); return send_cmd_ack(""); }
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; token_t token; token.token_cnt = 2; token.len[0] = 128; token.attr[0] = TOKEN_ATTR_FIXED_LENGTH | TOKEN_ATTR_VERIFY_HEX; 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); const u8 *hash_pos = token.buf[0]; 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[ 8] = hex_to_u32 (hash_pos + 64); digest[ 9] = hex_to_u32 (hash_pos + 72); digest[10] = hex_to_u32 (hash_pos + 80); digest[11] = hex_to_u32 (hash_pos + 88); digest[12] = hex_to_u32 (hash_pos + 96); digest[13] = hex_to_u32 (hash_pos + 104); digest[14] = hex_to_u32 (hash_pos + 112); digest[15] = hex_to_u32 (hash_pos + 120); 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]); digest[ 8] = byte_swap_32 (digest[ 8]); digest[ 9] = byte_swap_32 (digest[ 9]); digest[10] = byte_swap_32 (digest[10]); digest[11] = byte_swap_32 (digest[11]); digest[12] = byte_swap_32 (digest[12]); digest[13] = byte_swap_32 (digest[13]); digest[14] = byte_swap_32 (digest[14]); digest[15] = byte_swap_32 (digest[15]); const u8 *salt_pos = token.buf[1]; salt->salt_buf[0] = hex_to_u32 (salt_pos + 0); salt->salt_buf[1] = hex_to_u32 (salt_pos + 8); salt->salt_buf[2] = hex_to_u32 (salt_pos + 16); salt->salt_buf[3] = hex_to_u32 (salt_pos + 24); salt->salt_buf[0] = byte_swap_32 (salt->salt_buf[0]); salt->salt_buf[1] = byte_swap_32 (salt->salt_buf[1]); salt->salt_buf[2] = byte_swap_32 (salt->salt_buf[2]); salt->salt_buf[3] = byte_swap_32 (salt->salt_buf[3]); salt->salt_iter = ROUNDS_ORACLET - 1; salt->salt_len = 16; return (PARSER_OK); }
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; apple_secure_notes_t *apple_secure_notes = (apple_secure_notes_t *) esalt_buf; token_t token; token.token_cnt = 6; token.signatures_cnt = 1; token.signatures_buf[0] = SIGNATURE_FILEVAULT2; token.len[0] = 6; token.attr[0] = TOKEN_ATTR_FIXED_LENGTH | TOKEN_ATTR_VERIFY_SIGNATURE; token.sep[1] = '$'; token.len_min[1] = 1; token.len_max[1] = 10; token.attr[1] = TOKEN_ATTR_VERIFY_LENGTH | TOKEN_ATTR_VERIFY_DIGIT; token.sep[2] = '$'; token.len_min[2] = 1; token.len_max[2] = 6; token.attr[2] = TOKEN_ATTR_VERIFY_LENGTH | TOKEN_ATTR_VERIFY_DIGIT; token.sep[3] = '$'; token.len_min[3] = 32; token.len_max[3] = 32; token.attr[3] = TOKEN_ATTR_VERIFY_LENGTH | TOKEN_ATTR_VERIFY_HEX; token.sep[4] = '$'; token.len_min[4] = 1; token.len_max[4] = 6; token.attr[4] = TOKEN_ATTR_VERIFY_LENGTH | TOKEN_ATTR_VERIFY_DIGIT; token.sep[5] = '$'; token.len_min[5] = 48; token.len_max[5] = 48; token.attr[5] = TOKEN_ATTR_VERIFY_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); // Z_PK const u8 *Z_PK_pos = token.buf[1]; const u32 Z_PK = hc_strtoul ((const char *) Z_PK_pos, NULL, 10); if (Z_PK != 1) return (PARSER_SIGNATURE_UNMATCHED); apple_secure_notes->Z_PK = Z_PK; // ZCRYPTOSALT const u8 *ZCRYPTOSALT_pos = token.buf[3]; apple_secure_notes->ZCRYPTOSALT[ 0] = hex_to_u32 ((const u8 *) &ZCRYPTOSALT_pos[ 0]); apple_secure_notes->ZCRYPTOSALT[ 1] = hex_to_u32 ((const u8 *) &ZCRYPTOSALT_pos[ 8]); apple_secure_notes->ZCRYPTOSALT[ 2] = hex_to_u32 ((const u8 *) &ZCRYPTOSALT_pos[16]); apple_secure_notes->ZCRYPTOSALT[ 3] = hex_to_u32 ((const u8 *) &ZCRYPTOSALT_pos[24]); apple_secure_notes->ZCRYPTOSALT[ 4] = 0; apple_secure_notes->ZCRYPTOSALT[ 5] = 0; apple_secure_notes->ZCRYPTOSALT[ 6] = 0; apple_secure_notes->ZCRYPTOSALT[ 7] = 0; apple_secure_notes->ZCRYPTOSALT[ 8] = 0; apple_secure_notes->ZCRYPTOSALT[ 9] = 0; apple_secure_notes->ZCRYPTOSALT[10] = 0; apple_secure_notes->ZCRYPTOSALT[11] = 0; apple_secure_notes->ZCRYPTOSALT[12] = 0; apple_secure_notes->ZCRYPTOSALT[13] = 0; apple_secure_notes->ZCRYPTOSALT[14] = 0; apple_secure_notes->ZCRYPTOSALT[15] = 0; // ZCRYPTOITERATIONCOUNT const u8 *ZCRYPTOITERATIONCOUNT_pos = token.buf[4]; const u32 ZCRYPTOITERATIONCOUNT = hc_strtoul ((const char *) ZCRYPTOITERATIONCOUNT_pos, NULL, 10); apple_secure_notes->ZCRYPTOITERATIONCOUNT = ZCRYPTOITERATIONCOUNT; // ZCRYPTOWRAPPEDKEY const u8 *ZCRYPTOWRAPPEDKEY_pos = token.buf[5]; apple_secure_notes->ZCRYPTOWRAPPEDKEY[0] = hex_to_u32 ((const u8 *) &ZCRYPTOWRAPPEDKEY_pos[ 0]); apple_secure_notes->ZCRYPTOWRAPPEDKEY[1] = hex_to_u32 ((const u8 *) &ZCRYPTOWRAPPEDKEY_pos[ 8]); apple_secure_notes->ZCRYPTOWRAPPEDKEY[2] = hex_to_u32 ((const u8 *) &ZCRYPTOWRAPPEDKEY_pos[16]); apple_secure_notes->ZCRYPTOWRAPPEDKEY[3] = hex_to_u32 ((const u8 *) &ZCRYPTOWRAPPEDKEY_pos[24]); apple_secure_notes->ZCRYPTOWRAPPEDKEY[4] = hex_to_u32 ((const u8 *) &ZCRYPTOWRAPPEDKEY_pos[32]); apple_secure_notes->ZCRYPTOWRAPPEDKEY[5] = hex_to_u32 ((const u8 *) &ZCRYPTOWRAPPEDKEY_pos[40]); // fake salt salt->salt_buf[0] = apple_secure_notes->ZCRYPTOSALT[0]; salt->salt_buf[1] = apple_secure_notes->ZCRYPTOSALT[1]; salt->salt_buf[2] = apple_secure_notes->ZCRYPTOSALT[2]; salt->salt_buf[3] = apple_secure_notes->ZCRYPTOSALT[3]; salt->salt_buf[4] = apple_secure_notes->Z_PK; salt->salt_iter = apple_secure_notes->ZCRYPTOITERATIONCOUNT - 1; salt->salt_len = 20; // fake hash digest[0] = apple_secure_notes->ZCRYPTOWRAPPEDKEY[0]; digest[1] = apple_secure_notes->ZCRYPTOWRAPPEDKEY[1]; digest[2] = apple_secure_notes->ZCRYPTOWRAPPEDKEY[2]; digest[3] = apple_secure_notes->ZCRYPTOWRAPPEDKEY[3]; return (PARSER_OK); }
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; jks_sha1_t *jks_sha1 = (jks_sha1_t *) esalt_buf; token_t token; token.token_cnt = 7; token.signatures_cnt = 1; token.signatures_buf[0] = SIGNATURE_JKS_SHA1; token.sep[0] = '*'; token.len_min[0] = 10; token.len_max[0] = 10; token.attr[0] = TOKEN_ATTR_VERIFY_LENGTH | TOKEN_ATTR_VERIFY_SIGNATURE; token.sep[1] = '*'; token.len_min[1] = 40; token.len_max[1] = 40; token.attr[1] = TOKEN_ATTR_VERIFY_LENGTH | TOKEN_ATTR_VERIFY_HEX; token.sep[2] = '*'; token.len_min[2] = 40; token.len_max[2] = 40; token.attr[2] = TOKEN_ATTR_VERIFY_LENGTH | TOKEN_ATTR_VERIFY_HEX; token.sep[3] = '*'; token.len_min[3] = 2; token.len_max[3] = 16384; token.attr[3] = TOKEN_ATTR_VERIFY_LENGTH | TOKEN_ATTR_VERIFY_HEX; token.sep[4] = '*'; token.len_min[4] = 2; token.len_max[4] = 2; token.attr[4] = TOKEN_ATTR_VERIFY_LENGTH | TOKEN_ATTR_VERIFY_DIGIT; token.sep[5] = '*'; token.len_min[5] = 28; token.len_max[5] = 28; token.attr[5] = TOKEN_ATTR_VERIFY_LENGTH | TOKEN_ATTR_VERIFY_HEX; token.sep[6] = '*'; token.len_min[6] = 0; token.len_max[6] = 64; token.attr[6] = TOKEN_ATTR_VERIFY_LENGTH; const int rc_tokenizer = input_tokenizer ((const u8 *) line_buf, line_len, &token); if (rc_tokenizer != PARSER_OK) return (rc_tokenizer); // checksum const u8 *checksum_pos = token.buf[1]; jks_sha1->checksum[0] = hex_to_u32 ((const u8 *) &checksum_pos[ 0]); jks_sha1->checksum[1] = hex_to_u32 ((const u8 *) &checksum_pos[ 8]); jks_sha1->checksum[2] = hex_to_u32 ((const u8 *) &checksum_pos[16]); jks_sha1->checksum[3] = hex_to_u32 ((const u8 *) &checksum_pos[24]); jks_sha1->checksum[4] = hex_to_u32 ((const u8 *) &checksum_pos[32]); // iv const u8 *iv_pos = token.buf[2]; jks_sha1->iv[0] = hex_to_u32 ((const u8 *) &iv_pos[ 0]); jks_sha1->iv[1] = hex_to_u32 ((const u8 *) &iv_pos[ 8]); jks_sha1->iv[2] = hex_to_u32 ((const u8 *) &iv_pos[16]); jks_sha1->iv[3] = hex_to_u32 ((const u8 *) &iv_pos[24]); jks_sha1->iv[4] = hex_to_u32 ((const u8 *) &iv_pos[32]); // enc_key const u8 *enc_key_pos = token.buf[3]; const int enc_key_len = token.len[3]; u8 *enc_key_buf = (u8 *) jks_sha1->enc_key_buf; for (int i = 0, j = 0; j < enc_key_len; i += 1, j += 2) { enc_key_buf[i] = hex_to_u8 ((const u8 *) &enc_key_pos[j]); jks_sha1->enc_key_len++; } // der1 const u8 *der1_pos = token.buf[4]; u8 *der = (u8 *) jks_sha1->der; der[0] = hex_to_u8 ((const u8 *) &der1_pos[0]); // der2 const u8 *der2_pos = token.buf[5]; for (int i = 6, j = 0; j < 28; i += 1, j += 2) { der[i] = hex_to_u8 ((const u8 *) &der2_pos[j]); } der[1] = 0; der[2] = 0; der[3] = 0; der[4] = 0; der[5] = 0; // alias const u8 *alias_pos = token.buf[6]; strncpy ((char *) jks_sha1->alias, (const char *) alias_pos, 64); // fake salt salt->salt_buf[0] = jks_sha1->iv[0]; salt->salt_buf[1] = jks_sha1->iv[1]; salt->salt_buf[2] = jks_sha1->iv[2]; salt->salt_buf[3] = jks_sha1->iv[3]; salt->salt_buf[4] = jks_sha1->iv[4]; salt->salt_len = 20; // fake digest digest[0] = byte_swap_32 (jks_sha1->der[0]); digest[1] = byte_swap_32 (jks_sha1->der[1]); digest[2] = byte_swap_32 (jks_sha1->der[2]); digest[3] = byte_swap_32 (jks_sha1->der[3]); digest[4] = byte_swap_32 (jks_sha1->der[4]); return (PARSER_OK); }
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; dpapimk_t *dpapimk = (dpapimk_t *) esalt_buf; token_t token; token.token_cnt = 10; token.signatures_cnt = 1; token.signatures_buf[0] = SIGNATURE_DPAPIMK; // signature token.len[0] = 9; token.attr[0] = TOKEN_ATTR_FIXED_LENGTH | TOKEN_ATTR_VERIFY_SIGNATURE; // version token.len_min[1] = 1; token.len_max[1] = 1; token.sep[1] = '*'; token.attr[1] = TOKEN_ATTR_VERIFY_LENGTH | TOKEN_ATTR_VERIFY_DIGIT; // context token.len_min[2] = 1; token.len_max[2] = 1; token.sep[2] = '*'; token.attr[2] = TOKEN_ATTR_VERIFY_LENGTH | TOKEN_ATTR_VERIFY_DIGIT; // sid token.len_min[3] = 10; token.len_max[3] = 60; token.sep[3] = '*'; token.attr[3] = TOKEN_ATTR_VERIFY_LENGTH; // cipher token.len_min[4] = 4; token.len_max[4] = 6; token.sep[4] = '*'; token.attr[4] = TOKEN_ATTR_VERIFY_LENGTH; // hash token.len_min[5] = 4; token.len_max[5] = 6; token.sep[5] = '*'; token.attr[5] = TOKEN_ATTR_VERIFY_LENGTH; // iterations token.len_min[6] = 1; token.len_max[6] = 6; token.sep[6] = '*'; token.attr[6] = TOKEN_ATTR_VERIFY_LENGTH | TOKEN_ATTR_VERIFY_DIGIT; // iv token.len_min[7] = 32; token.len_max[7] = 32; token.sep[7] = '*'; token.attr[7] = TOKEN_ATTR_VERIFY_LENGTH | TOKEN_ATTR_VERIFY_HEX; // content len token.len_min[8] = 1; token.len_max[8] = 6; token.sep[8] = '*'; token.attr[8] = TOKEN_ATTR_VERIFY_LENGTH | TOKEN_ATTR_VERIFY_DIGIT; // content token.len_min[9] = 0; token.len_max[9] = 1024; token.attr[9] = TOKEN_ATTR_VERIFY_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 *version_pos = token.buf[1]; const u8 *context_pos = token.buf[2]; const u8 *SID_pos = token.buf[3]; const u8 *rounds_pos = token.buf[6]; const u8 *iv_pos = token.buf[7]; const u8 *contents_len_pos = token.buf[8]; const u8 *contents_pos = token.buf[9]; /** * content verification */ const int version = hc_strtoul ((const char *) version_pos, NULL, 10); const int contents_len = hc_strtoul ((const char *) contents_len_pos, NULL, 10); if (version == 1) { if (contents_len != 208) return (PARSER_SALT_LENGTH); } else if (version == 2) { if (contents_len != 288) return (PARSER_SALT_LENGTH); } else { return (PARSER_SALT_VALUE); } if (contents_len != token.len[9]) return (PARSER_SALT_LENGTH); dpapimk->contents_len = contents_len; dpapimk->context = hc_strtoul ((const char *) context_pos, NULL, 10); // division by 4 should be fine because contents_len is either 208 or 288 for (u32 i = 0; i < dpapimk->contents_len / 4; i++) { dpapimk->contents[i] = hex_to_u32 ((const u8 *) &contents_pos[i * 8]); dpapimk->contents[i] = byte_swap_32 (dpapimk->contents[i]); } // SID const int SID_len = token.len[3]; u8 SID_utf16le[128] = { 0 }; for (int i = 0; i < SID_len; i++) { SID_utf16le[i * 2] = SID_pos[i]; } /* Specific to DPAPI: needs trailing '\0' while computing hash */ dpapimk->SID_len = (SID_len + 1) * 2; SID_utf16le[dpapimk->SID_len] = 0x80; memcpy ((u8 *) dpapimk->SID, SID_utf16le, sizeof (SID_utf16le)); for (u32 i = 0; i < 32; i++) { dpapimk->SID[i] = byte_swap_32 (dpapimk->SID[i]); } // iv dpapimk->iv[0] = hex_to_u32 ((const u8 *) &iv_pos[ 0]); dpapimk->iv[1] = hex_to_u32 ((const u8 *) &iv_pos[ 8]); dpapimk->iv[2] = hex_to_u32 ((const u8 *) &iv_pos[16]); dpapimk->iv[3] = hex_to_u32 ((const u8 *) &iv_pos[24]); dpapimk->iv[0] = byte_swap_32 (dpapimk->iv[0]); dpapimk->iv[1] = byte_swap_32 (dpapimk->iv[1]); dpapimk->iv[2] = byte_swap_32 (dpapimk->iv[2]); dpapimk->iv[3] = byte_swap_32 (dpapimk->iv[3]); digest[0] = dpapimk->iv[0]; digest[1] = dpapimk->iv[1]; digest[2] = dpapimk->iv[2]; digest[3] = dpapimk->iv[3]; salt->salt_buf[0] = dpapimk->iv[0]; salt->salt_buf[1] = dpapimk->iv[1]; salt->salt_buf[2] = dpapimk->iv[2]; salt->salt_buf[3] = dpapimk->iv[3]; salt->salt_len = 16; // iter salt->salt_iter = hc_strtoul ((const char *) rounds_pos, NULL, 10) - 1; return (PARSER_OK); }
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; odf12_t *odf12 = (odf12_t *) esalt_buf; token_t token; token.token_cnt = 12; token.signatures_cnt = 1; token.signatures_buf[0] = SIGNATURE_ODF; token.len_min[0] = 5; token.len_max[0] = 5; token.sep[0] = '*'; token.attr[0] = TOKEN_ATTR_VERIFY_LENGTH | TOKEN_ATTR_VERIFY_SIGNATURE; token.len_min[1] = 1; token.len_max[1] = 1; token.sep[1] = '*'; token.attr[1] = TOKEN_ATTR_VERIFY_LENGTH | TOKEN_ATTR_VERIFY_DIGIT; token.len_min[2] = 1; token.len_max[2] = 1; token.sep[2] = '*'; token.attr[2] = TOKEN_ATTR_VERIFY_LENGTH | TOKEN_ATTR_VERIFY_DIGIT; token.len_min[3] = 4; token.len_max[3] = 6; token.sep[3] = '*'; token.attr[3] = TOKEN_ATTR_VERIFY_LENGTH | TOKEN_ATTR_VERIFY_DIGIT; token.len_min[4] = 2; token.len_max[4] = 2; token.sep[4] = '*'; token.attr[4] = TOKEN_ATTR_VERIFY_LENGTH | TOKEN_ATTR_VERIFY_DIGIT; token.len_min[5] = 64; token.len_max[5] = 64; token.sep[5] = '*'; token.attr[5] = TOKEN_ATTR_VERIFY_LENGTH | TOKEN_ATTR_VERIFY_HEX; token.len_min[6] = 2; token.len_max[6] = 2; token.sep[6] = '*'; token.attr[6] = TOKEN_ATTR_VERIFY_LENGTH | TOKEN_ATTR_VERIFY_DIGIT; token.len_min[7] = 32; token.len_max[7] = 32; token.sep[7] = '*'; token.attr[7] = TOKEN_ATTR_VERIFY_LENGTH | TOKEN_ATTR_VERIFY_HEX; token.len_min[8] = 2; token.len_max[8] = 2; token.sep[8] = '*'; token.attr[8] = TOKEN_ATTR_VERIFY_LENGTH | TOKEN_ATTR_VERIFY_DIGIT; token.len_min[9] = 32; token.len_max[9] = 32; token.sep[9] = '*'; token.attr[9] = TOKEN_ATTR_VERIFY_LENGTH | TOKEN_ATTR_VERIFY_HEX; token.len_min[10] = 1; token.len_max[10] = 1; token.sep[10] = '*'; token.attr[10] = TOKEN_ATTR_VERIFY_LENGTH | TOKEN_ATTR_VERIFY_DIGIT; token.len[11] = 2048; token.attr[11] = 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 *checksum = token.buf[5]; const u8 *iv = token.buf[7]; const u8 *salt_buf = token.buf[9]; const u8 *encrypted_data = token.buf[11]; const u32 cipher_type = strtol ((const char *) token.buf[1], NULL, 10); const u32 checksum_type = strtol ((const char *) token.buf[2], NULL, 10); const u32 iterations = strtol ((const char *) token.buf[3], NULL, 10); const u32 key_size = strtol ((const char *) token.buf[4], NULL, 10); const u32 iv_len = strtol ((const char *) token.buf[6], NULL, 10); const u32 salt_len = strtol ((const char *) token.buf[8], NULL, 10); const u32 unused = strtol ((const char *) token.buf[10], NULL, 10); if (cipher_type != 1) return (PARSER_SALT_VALUE); if (checksum_type != 1) return (PARSER_SALT_VALUE); if (key_size != 32) return (PARSER_SALT_VALUE); if (iv_len != 16) return (PARSER_SALT_VALUE); if (salt_len != 16) return (PARSER_SALT_VALUE); if (unused != 0) return (PARSER_SALT_VALUE); // esalt odf12->iterations = iterations; odf12->checksum[0] = hex_to_u32 (&checksum[ 0]); odf12->checksum[1] = hex_to_u32 (&checksum[ 8]); odf12->checksum[2] = hex_to_u32 (&checksum[16]); odf12->checksum[3] = hex_to_u32 (&checksum[24]); odf12->checksum[4] = hex_to_u32 (&checksum[32]); odf12->checksum[5] = hex_to_u32 (&checksum[40]); odf12->checksum[6] = hex_to_u32 (&checksum[48]); odf12->checksum[7] = hex_to_u32 (&checksum[56]); odf12->iv[0] = hex_to_u32 (&iv[0]); odf12->iv[1] = hex_to_u32 (&iv[8]); odf12->iv[2] = hex_to_u32 (&iv[16]); odf12->iv[3] = hex_to_u32 (&iv[24]); for (int i = 0, j = 0; i < 256; i += 1, j += 8) { odf12->encrypted_data[i] = hex_to_u32 (&encrypted_data[j]); } // salt salt->salt_len = salt_len; salt->salt_iter = iterations - 1; salt->salt_buf[0] = hex_to_u32 (&salt_buf[ 0]); salt->salt_buf[1] = hex_to_u32 (&salt_buf[ 8]); salt->salt_buf[2] = hex_to_u32 (&salt_buf[16]); salt->salt_buf[3] = hex_to_u32 (&salt_buf[24]); /** * digest */ digest[0] = odf12->checksum[0]; digest[1] = odf12->checksum[1]; digest[2] = odf12->checksum[2]; digest[3] = odf12->checksum[3]; digest[4] = odf12->checksum[4]; digest[5] = odf12->checksum[5]; digest[6] = odf12->checksum[6]; digest[7] = odf12->checksum[7]; return (PARSER_OK); }
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; wpa_pmkid_t *wpa_pmkid = (wpa_pmkid_t *) esalt_buf; token_t token; // real 16801 pmkid hash-lines token.token_cnt = 3; token.sep[0] = ':'; token.len_min[0] = 32; token.len_max[0] = 32; token.attr[0] = TOKEN_ATTR_VERIFY_LENGTH | TOKEN_ATTR_VERIFY_HEX; token.sep[1] = ':'; token.len_min[1] = 12; token.len_max[1] = 12; token.attr[1] = TOKEN_ATTR_VERIFY_LENGTH | TOKEN_ATTR_VERIFY_HEX; token.sep[2] = ':'; token.len_min[2] = 12; token.len_max[2] = 12; token.attr[2] = TOKEN_ATTR_VERIFY_LENGTH | TOKEN_ATTR_VERIFY_HEX; const int rc_tokenizer = input_tokenizer ((const u8 *) line_buf, line_len, &token); if (rc_tokenizer != PARSER_OK) { // we'll accept normal 16800 pmkid hash-lines, too token.token_cnt = 4; token.sep[0] = ':'; token.len_min[0] = 32; token.len_max[0] = 32; token.attr[0] = TOKEN_ATTR_VERIFY_LENGTH | TOKEN_ATTR_VERIFY_HEX; token.sep[1] = ':'; token.len_min[1] = 12; token.len_max[1] = 12; token.attr[1] = TOKEN_ATTR_VERIFY_LENGTH | TOKEN_ATTR_VERIFY_HEX; token.sep[2] = ':'; token.len_min[2] = 12; token.len_max[2] = 12; token.attr[2] = TOKEN_ATTR_VERIFY_LENGTH | TOKEN_ATTR_VERIFY_HEX; token.sep[3] = ':'; token.len_min[3] = 0; token.len_max[3] = 64; token.attr[3] = TOKEN_ATTR_VERIFY_LENGTH | TOKEN_ATTR_VERIFY_HEX; const int rc_tokenizer2 = input_tokenizer ((const u8 *) line_buf, line_len, &token); if (rc_tokenizer2 != PARSER_OK) return (rc_tokenizer); // essid const u8 *essid_buf = token.buf[3]; const int essid_len = token.len[3]; if (essid_len & 1) return (PARSER_SALT_VALUE); wpa_pmkid->essid_len = hex_decode (essid_buf, essid_len, (u8 *) wpa_pmkid->essid_buf); } // pmkid const u8 *pmkid_buf = token.buf[0]; wpa_pmkid->pmkid[0] = hex_to_u32 (pmkid_buf + 0); wpa_pmkid->pmkid[1] = hex_to_u32 (pmkid_buf + 8); wpa_pmkid->pmkid[2] = hex_to_u32 (pmkid_buf + 16); wpa_pmkid->pmkid[3] = hex_to_u32 (pmkid_buf + 24); // mac_ap const u8 *macap_buf = token.buf[1]; wpa_pmkid->orig_mac_ap[0] = hex_to_u8 (macap_buf + 0); wpa_pmkid->orig_mac_ap[1] = hex_to_u8 (macap_buf + 2); wpa_pmkid->orig_mac_ap[2] = hex_to_u8 (macap_buf + 4); wpa_pmkid->orig_mac_ap[3] = hex_to_u8 (macap_buf + 6); wpa_pmkid->orig_mac_ap[4] = hex_to_u8 (macap_buf + 8); wpa_pmkid->orig_mac_ap[5] = hex_to_u8 (macap_buf + 10); // mac_sta const u8 *macsta_buf = token.buf[2]; wpa_pmkid->orig_mac_sta[0] = hex_to_u8 (macsta_buf + 0); wpa_pmkid->orig_mac_sta[1] = hex_to_u8 (macsta_buf + 2); wpa_pmkid->orig_mac_sta[2] = hex_to_u8 (macsta_buf + 4); wpa_pmkid->orig_mac_sta[3] = hex_to_u8 (macsta_buf + 6); wpa_pmkid->orig_mac_sta[4] = hex_to_u8 (macsta_buf + 8); wpa_pmkid->orig_mac_sta[5] = hex_to_u8 (macsta_buf + 10); // pmkid_data wpa_pmkid->pmkid_data[0] = 0x204b4d50; // "PMK " wpa_pmkid->pmkid_data[1] = 0x656d614e; // "Name" wpa_pmkid->pmkid_data[2] = (wpa_pmkid->orig_mac_ap[0] << 0) | (wpa_pmkid->orig_mac_ap[1] << 8) | (wpa_pmkid->orig_mac_ap[2] << 16) | (wpa_pmkid->orig_mac_ap[3] << 24); wpa_pmkid->pmkid_data[3] = (wpa_pmkid->orig_mac_ap[4] << 0) | (wpa_pmkid->orig_mac_ap[5] << 8) | (wpa_pmkid->orig_mac_sta[0] << 16) | (wpa_pmkid->orig_mac_sta[1] << 24); wpa_pmkid->pmkid_data[4] = (wpa_pmkid->orig_mac_sta[2] << 0) | (wpa_pmkid->orig_mac_sta[3] << 8) | (wpa_pmkid->orig_mac_sta[4] << 16) | (wpa_pmkid->orig_mac_sta[5] << 24); // salt salt->salt_buf[0] = wpa_pmkid->pmkid_data[0]; salt->salt_buf[1] = wpa_pmkid->pmkid_data[1]; salt->salt_buf[2] = wpa_pmkid->pmkid_data[2]; salt->salt_buf[3] = wpa_pmkid->pmkid_data[3]; salt->salt_buf[4] = wpa_pmkid->pmkid_data[4]; salt->salt_buf[5] = wpa_pmkid->pmkid_data[5]; salt->salt_buf[6] = wpa_pmkid->pmkid_data[6]; salt->salt_buf[7] = wpa_pmkid->pmkid_data[7]; salt->salt_len = 32; salt->salt_iter = ROUNDS_WPA_PMK - 1; // hash digest[0] = wpa_pmkid->pmkid[0]; digest[1] = wpa_pmkid->pmkid[1]; digest[2] = wpa_pmkid->pmkid[2]; digest[3] = wpa_pmkid->pmkid[3]; 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]); return (PARSER_OK); }
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; token_t token; token.token_cnt = 3; token.signatures_cnt = 1; token.signatures_buf[0] = SIGNATURE_NETSCALER; token.len[0] = 1; token.attr[0] = TOKEN_ATTR_FIXED_LENGTH | TOKEN_ATTR_VERIFY_SIGNATURE; token.len[1] = 8; token.attr[1] = TOKEN_ATTR_FIXED_LENGTH; 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); // salt const u8 *salt_pos = token.buf[1]; const int salt_len = token.len[1]; memcpy (salt->salt_buf, salt_pos, salt_len); salt->salt_buf[0] = byte_swap_32 (salt->salt_buf[0]); salt->salt_buf[1] = byte_swap_32 (salt->salt_buf[1]); salt->salt_len = salt_len; // 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]); if (hashconfig->opti_type & OPTI_TYPE_OPTIMIZED_KERNEL) { digest[0] -= SHA1M_A; digest[1] -= SHA1M_B; digest[2] -= SHA1M_C; digest[3] -= SHA1M_D; digest[4] -= SHA1M_E; } return (PARSER_OK); }
int potfile_remove_parse (hashcat_ctx_t *hashcat_ctx) { const hashconfig_t *hashconfig = hashcat_ctx->hashconfig; const hashes_t *hashes = hashcat_ctx->hashes; const potfile_ctx_t *potfile_ctx = hashcat_ctx->potfile_ctx; if (potfile_ctx->enabled == false) return 0; // if no potfile exists yet we don't need to do anything here if (hc_path_exist (potfile_ctx->filename) == false) return 0; hash_t *hashes_buf = hashes->hashes_buf; u32 hashes_cnt = hashes->hashes_cnt; // no solution for these special hash types (for instane because they use hashfile in output etc) if (hashconfig->hash_mode == 5200) return 0; if ((hashconfig->hash_mode >= 6200) && (hashconfig->hash_mode <= 6299)) return 0; if (hashconfig->hash_mode == 9000) return 0; if ((hashconfig->hash_mode >= 13700) && (hashconfig->hash_mode <= 13799)) return 0; if (hashconfig->hash_mode == 14600) return 0; hash_t hash_buf; hash_buf.digest = hcmalloc (hashconfig->dgst_size); hash_buf.salt = NULL; hash_buf.esalt = NULL; hash_buf.hook_salt = NULL; hash_buf.hash_info = NULL; hash_buf.cracked = 0; if (hashconfig->is_salted == true) { hash_buf.salt = (salt_t *) hcmalloc (sizeof (salt_t)); } if (hashconfig->esalt_size > 0) { hash_buf.esalt = hcmalloc (hashconfig->esalt_size); } if (hashconfig->hook_salt_size > 0) { hash_buf.hook_salt = hcmalloc (hashconfig->hook_salt_size); } // we only need this variable in a very specific situation: // whenever we use --username and --show together we want to keep all hashes sorted within a nice structure pot_tree_entry_t *all_hashes_tree = NULL; pot_tree_entry_t *tree_entry_cache = NULL; pot_hash_node_t *tree_nodes_cache = NULL; if (potfile_ctx->keep_all_hashes == true) { // we need *at most* one entry for every hash // (if there are no hashes with the same keys (hash + salt), a counter example would be: same hash but different user name) tree_entry_cache = (pot_tree_entry_t *) hccalloc (hashes_cnt, sizeof (pot_tree_entry_t)); // we need *always exactly* one linked list for every hash tree_nodes_cache = (pot_hash_node_t *) hccalloc (hashes_cnt, sizeof (pot_hash_node_t)); for (u32 hash_pos = 0; hash_pos < hashes_cnt; hash_pos++) { // initialize the linked list node: // we always need to create a new one and add it, because we want to keep and later update all hashes: pot_hash_node_t *new_node = &tree_nodes_cache[hash_pos]; new_node->hash_buf = &hashes_buf[hash_pos]; new_node->next = NULL; // initialize the entry: pot_tree_entry_t *new_entry = &tree_entry_cache[hash_pos]; // note: the "key" (hash + salt) is indirectly accessible via the first nodes "hash_buf" new_entry->nodes = new_node; // the hashconfig is needed here because we need to be able to check within the sort function if we also need // to sort by salt and we also need to have the correct order of dgst_pos0...dgst_pos3: new_entry->hashconfig = (hashconfig_t *) hashconfig; // "const hashconfig_t" gives a warning // the following function searches if the "key" is already present and if not inserts the new entry: void **found = tsearch (new_entry, (void **) &all_hashes_tree, sort_pot_tree_by_hash); pot_tree_entry_t *found_entry = (pot_tree_entry_t *) *found; // we now need to check these cases; tsearch () could return: // 1. NULL : if we have a memory allocation problem (not enough memory for the tree structure) // 2. found_entry == new_entry: if we successfully insert a new key (which was not present yet) // 3. found_entry != new_entry: if the key was already present // case 1: memory allocation error if (found_entry == NULL) { fprintf (stderr, "Error while allocating memory for the potfile search: %s\n", MSG_ENOMEM); return -1; } // case 2: this means it was a new insert (and the insert was successful) if (found_entry == new_entry) { // no updates to the linked list required (since it is the first one!) } // case 3: if we have found an already existing entry else { new_node->next = found_entry->nodes; } // we always insert the new node at the very beginning // (or in other words: the head of the linked list always points to *this* new inserted node) found_entry->nodes = new_node; } } // special case for a split hash if (hashconfig->hash_mode == 3000) { int parser_status = hashconfig->parse_func ((u8 *) LM_ZERO_HASH, 16, &hash_buf, hashconfig); if (parser_status == PARSER_OK) { if (potfile_ctx->keep_all_hashes == true) { potfile_update_hashes (hashcat_ctx, &hash_buf, NULL, 0, all_hashes_tree); } else { hash_t *found = (hash_t *) hc_bsearch_r (&hash_buf, hashes_buf, hashes_cnt, sizeof (hash_t), sort_by_hash_no_salt, (void *) hashconfig); potfile_update_hash (hashcat_ctx, found, NULL, 0); } } } const int rc = potfile_read_open (hashcat_ctx); if (rc == -1) return -1; char *line_buf = (char *) hcmalloc (HCBUFSIZ_LARGE); while (!feof (potfile_ctx->fp)) { int line_len = fgetl (potfile_ctx->fp, line_buf); if (line_len == 0) continue; char *last_separator = strrchr (line_buf, hashconfig->separator); if (last_separator == NULL) continue; // ?? char *line_pw_buf = last_separator + 1; int line_pw_len = line_buf + line_len - line_pw_buf; char *line_hash_buf = line_buf; int line_hash_len = last_separator - line_buf; line_hash_buf[line_hash_len] = 0; if (line_hash_len == 0) continue; if (hashconfig->is_salted == true) { memset (hash_buf.salt, 0, sizeof (salt_t)); } if (hashconfig->esalt_size > 0) { memset (hash_buf.esalt, 0, hashconfig->esalt_size); } if (hashconfig->hook_salt_size > 0) { memset (hash_buf.hook_salt, 0, hashconfig->hook_salt_size); } hash_t *found = NULL; if (hashconfig->hash_mode == 6800) { if (line_hash_len < 256) // 64 = 64 * u32 in salt_buf[] { // manipulate salt_buf memcpy (hash_buf.salt->salt_buf, line_hash_buf, line_hash_len); hash_buf.salt->salt_len = line_hash_len; found = (hash_t *) bsearch (&hash_buf, hashes_buf, hashes_cnt, sizeof (hash_t), sort_by_hash_t_salt); } } else if ((hashconfig->hash_mode == 2500) || (hashconfig->hash_mode == 2501)) { // here we have in line_hash_buf: hash:macap:macsta:essid:password char *sep_pos = strrchr (line_hash_buf, ':'); if (sep_pos == NULL) continue; sep_pos[0] = 0; char *hash_pos = line_hash_buf; const size_t hash_len = strlen (hash_pos); if (hash_len != 32 + 1 + 12 + 1 + 12) continue; char *essid_pos = sep_pos + 1; int essid_len = (int) strlen (essid_pos); if (is_hexify ((const u8 *) essid_pos, (const int) essid_len) == true) { essid_len = exec_unhexify ((const u8 *) essid_pos, essid_len, (u8 *) essid_pos, essid_len); } if (essid_len > 32) continue; if (hashconfig->is_salted == true) { // this should be always true, but we need it to make scan-build happy memcpy (hash_buf.salt->salt_buf, essid_pos, essid_len); hash_buf.salt->salt_len = essid_len; hash_buf.salt->salt_iter = ROUNDS_WPA - 1; u32 hash[4]; hash[0] = hex_to_u32 ((const u8 *) &hash_pos[ 0]); hash[1] = hex_to_u32 ((const u8 *) &hash_pos[ 8]); hash[2] = hex_to_u32 ((const u8 *) &hash_pos[16]); hash[3] = hex_to_u32 ((const u8 *) &hash_pos[24]); hash[0] = byte_swap_32 (hash[0]); hash[1] = byte_swap_32 (hash[1]); hash[2] = byte_swap_32 (hash[2]); hash[3] = byte_swap_32 (hash[3]); u32 *digest = (u32 *) hash_buf.digest; digest[0] = hash[0]; digest[1] = hash[1]; digest[2] = hash[2]; digest[3] = hash[3]; } found = (hash_t *) hc_bsearch_r (&hash_buf, hashes_buf, hashes_cnt, sizeof (hash_t), sort_by_hash, (void *) hashconfig); } else { int parser_status = hashconfig->parse_func ((u8 *) line_hash_buf, line_hash_len, &hash_buf, hashconfig); if (parser_status != PARSER_OK) continue; if (potfile_ctx->keep_all_hashes == true) { potfile_update_hashes (hashcat_ctx, &hash_buf, line_pw_buf, line_pw_len, all_hashes_tree); continue; } found = (hash_t *) hc_bsearch_r (&hash_buf, hashes_buf, hashes_cnt, sizeof (hash_t), sort_by_hash, (void *) hashconfig); } potfile_update_hash (hashcat_ctx, found, line_pw_buf, line_pw_len); } hcfree (line_buf); potfile_read_close (hashcat_ctx); if (potfile_ctx->keep_all_hashes == true) { pot_tree_destroy (all_hashes_tree); // this could be slow (should we just skip it?) hcfree (tree_nodes_cache); hcfree (tree_entry_cache); } if (hashconfig->esalt_size > 0) { hcfree (hash_buf.esalt); } if (hashconfig->hook_salt_size > 0) { hcfree (hash_buf.hook_salt); } if (hashconfig->is_salted == true) { hcfree (hash_buf.salt); } hcfree (hash_buf.digest); return 0; }
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; ikepsk_t *ikepsk = (ikepsk_t *) esalt_buf; token_t token; token.token_cnt = 9; token.sep[0] = ':'; token.len_min[0] = 0; token.len_max[0] = 1024; token.attr[0] = TOKEN_ATTR_VERIFY_LENGTH | TOKEN_ATTR_VERIFY_HEX; token.sep[1] = ':'; token.len_min[1] = 0; token.len_max[1] = 1024; token.attr[1] = TOKEN_ATTR_VERIFY_LENGTH | TOKEN_ATTR_VERIFY_HEX; token.sep[2] = ':'; token.len_min[2] = 0; token.len_max[2] = 1024; token.attr[2] = TOKEN_ATTR_VERIFY_LENGTH | TOKEN_ATTR_VERIFY_HEX; token.sep[3] = ':'; token.len_min[3] = 0; token.len_max[3] = 1024; token.attr[3] = TOKEN_ATTR_VERIFY_LENGTH | TOKEN_ATTR_VERIFY_HEX; token.sep[4] = ':'; token.len_min[4] = 0; token.len_max[4] = 1024; token.attr[4] = TOKEN_ATTR_VERIFY_LENGTH | TOKEN_ATTR_VERIFY_HEX; token.sep[5] = ':'; token.len_min[5] = 0; token.len_max[5] = 1024; token.attr[5] = TOKEN_ATTR_VERIFY_LENGTH | TOKEN_ATTR_VERIFY_HEX; token.sep[6] = ':'; token.len_min[6] = 0; token.len_max[6] = 128; token.attr[6] = TOKEN_ATTR_VERIFY_LENGTH | TOKEN_ATTR_VERIFY_HEX; token.sep[7] = ':'; token.len_min[7] = 0; token.len_max[7] = 128; token.attr[7] = TOKEN_ATTR_VERIFY_LENGTH | TOKEN_ATTR_VERIFY_HEX; token.sep[8] = ':'; token.len_min[8] = 32; token.len_max[8] = 32; token.attr[8] = TOKEN_ATTR_VERIFY_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); ikepsk->msg_len[0] = token.len[0] / 2; ikepsk->msg_len[1] = ikepsk->msg_len[0] + token.len[1] / 2; ikepsk->msg_len[2] = ikepsk->msg_len[1] + token.len[2] / 2; ikepsk->msg_len[3] = ikepsk->msg_len[2] + token.len[3] / 2; ikepsk->msg_len[4] = ikepsk->msg_len[3] + token.len[4] / 2; ikepsk->msg_len[5] = ikepsk->msg_len[4] + token.len[5] / 2; ikepsk->nr_len = (token.len[6] + token.len[7]) / 2; if (ikepsk->msg_len[5] > 512) return (PARSER_SALT_LENGTH); if (ikepsk->nr_len > 64) return (PARSER_SALT_LENGTH); u8 *ptr1 = (u8 *) ikepsk->msg_buf; u8 *ptr2 = (u8 *) ikepsk->nr_buf; for (int i = 0; i < token.len[0]; i += 2) *ptr1++ = hex_to_u8 (token.buf[0] + i); for (int i = 0; i < token.len[1]; i += 2) *ptr1++ = hex_to_u8 (token.buf[1] + i); for (int i = 0; i < token.len[2]; i += 2) *ptr1++ = hex_to_u8 (token.buf[2] + i); for (int i = 0; i < token.len[3]; i += 2) *ptr1++ = hex_to_u8 (token.buf[3] + i); for (int i = 0; i < token.len[4]; i += 2) *ptr1++ = hex_to_u8 (token.buf[4] + i); for (int i = 0; i < token.len[5]; i += 2) *ptr1++ = hex_to_u8 (token.buf[5] + i); for (int i = 0; i < token.len[6]; i += 2) *ptr2++ = hex_to_u8 (token.buf[6] + i); for (int i = 0; i < token.len[7]; i += 2) *ptr2++ = hex_to_u8 (token.buf[7] + i); *ptr1++ = 0x80; *ptr2++ = 0x80; /** * Store to database */ const u8 *hash_pos = token.buf[8]; 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); salt->salt_len = 32; salt->salt_buf[0] = ikepsk->nr_buf[0]; salt->salt_buf[1] = ikepsk->nr_buf[1]; salt->salt_buf[2] = ikepsk->nr_buf[2]; salt->salt_buf[3] = ikepsk->nr_buf[3]; salt->salt_buf[4] = ikepsk->nr_buf[4]; salt->salt_buf[5] = ikepsk->nr_buf[5]; salt->salt_buf[6] = ikepsk->nr_buf[6]; salt->salt_buf[7] = ikepsk->nr_buf[7]; return (PARSER_OK); }