void scramble(char *to, _MYSQL_DATA *_psSessionData, const char *message, const char *password) { SHA1_CONTEXT sha1_context; uint8 hash_stage1[SHA1_HASH_SIZE]; uint8 hash_stage2[SHA1_HASH_SIZE]; sha1_reset(&sha1_context); /* Stock pass-the-hash Attacks do not appear feasible. However, if another conversation is intercepted and the SHA1 hash (hash_stage2) is known, hash_stage1 could probably be derived. A new reply could then be generated based on that information. Of course, if we already have this sort of network access, what are we messing with this for? */ if (_psSessionData->hashFlag == HASH) if ( (strncmp(password, "*", 1) == 0) && (strlen(password) == 2 * SHA1_HASH_SIZE + 1) ) writeError(ERR_ERROR, "[%s] MySQL 4.1 and above use a SHA1-based authentication scheme which does not appear to be susceptible to pass-the-hash style attacks.", MODULE_NAME); /* stage 1: hash password */ sha1_input(&sha1_context, (uint8 *) password, strlen(password)); sha1_result(&sha1_context, hash_stage1); /* stage 2: hash stage 1; note that hash_stage2 is stored in the database */ sha1_reset(&sha1_context); sha1_input(&sha1_context, hash_stage1, SHA1_HASH_SIZE); sha1_result(&sha1_context, hash_stage2); /* create crypt string as sha1(message, hash_stage2) */; sha1_reset(&sha1_context); sha1_input(&sha1_context, (const uint8 *) message, SCRAMBLE_LENGTH); sha1_input(&sha1_context, hash_stage2, SHA1_HASH_SIZE); /* xor allows 'from' and 'to' overlap: lets take advantage of it */ sha1_result(&sha1_context, (uint8 *) to); my_crypt(to, (const uchar *) to, hash_stage1, SCRAMBLE_LENGTH); }
static void srp_get_x(srp_t *srp, mpz_t x_c, const gchar *raw_salt) { gchar *userpass; guint8 hash[SHA1_HASH_SIZE], final_hash[SHA1_HASH_SIZE]; sha1_context ctx; ctx.version = SHA1_TYPE_NORMAL; // build the string Username:Password userpass = (gchar *) g_malloc(srp->username_len + srp->password_len + 2); memcpy(userpass, srp->username_upper, srp->username_len); userpass[srp->username_len] = ':'; memcpy(userpass + srp->username_len + 1, srp->password_upper, srp->password_len); userpass[srp->username_len + srp->password_len + 1] = 0; // null-terminator // get the SHA-1 hash of the string sha1_reset(&ctx); sha1_input(&ctx, (guint8 *) userpass, (srp->username_len + srp->password_len + 1)); sha1_digest(&ctx, hash); g_free(userpass); // get the SHA-1 hash of the salt and user:pass hash sha1_reset(&ctx); sha1_input(&ctx, (guint8 *) raw_salt, 32); sha1_input(&ctx, hash, 20); sha1_digest(&ctx, final_hash); // create an arbitrary-length integer from the hash and return it mpz_init2(x_c, 160); mpz_import(x_c, 20, -1, 1, 0, 0, (gchar *) final_hash); }
void srp_get_M1(srp_t *srp, gchar *out, const gchar *B, const gchar *salt) { sha1_context ctx; guint8 username_hash[SHA1_HASH_SIZE]; gchar A[32]; gchar S[32]; gchar K[40]; ctx.version = SHA1_TYPE_NORMAL; if (!srp) return; if (srp->M1) { purple_debug_info("bnet", "SRP: srp_get_M1() using cached M[1] value."); memcpy(out, srp->M1, 20); return; } /* calculate SHA-1 hash of username */ sha1_reset(&ctx); sha1_input(&ctx, (guint8 *) srp->username_upper, srp->username_len); sha1_digest(&ctx, username_hash); srp_get_A(srp, A); srp_get_S(srp, S, B, salt); srp_get_K(srp, K, S); /* calculate M[1] */ sha1_reset(&ctx); sha1_input(&ctx, (guint8 *) srp_I, 20); sha1_input(&ctx, username_hash, 20); sha1_input(&ctx, (guint8 *) salt, 32); sha1_input(&ctx, (guint8 *) A, 32); sha1_input(&ctx, (guint8 *) B, 32); sha1_input(&ctx, (guint8 *) K, 40); sha1_digest(&ctx, (guint8 *) out); srp->salt = (gchar *) g_malloc(32); srp->B = (gchar *) g_malloc(32); srp->M1 = (gchar *) g_malloc(20); if (srp->salt) g_memmove(srp->salt, salt, 32); if (srp->B) g_memmove(srp->B, B, 32); if (srp->M1) g_memmove(srp->M1, out, 20); }
void srp_get_K(srp_t *srp, gchar *out, const gchar *S) { gchar odd[16], even[16]; guint8 odd_hash[SHA1_HASH_SIZE], even_hash[SHA1_HASH_SIZE]; gchar *Sp = (gchar *) S; gchar *op = odd; gchar *ep = even; guint16 i; sha1_context ctx; ctx.version = SHA1_TYPE_NORMAL; if (!srp) return; if (srp->K) { g_memmove(out, srp->K, 40); return; } for (i = 0; i < 16; i++) { *(op++) = *(Sp++); *(ep++) = *(Sp++); } sha1_reset(&ctx); sha1_input(&ctx, (guint8 *) odd, 16); sha1_digest(&ctx, odd_hash); sha1_reset(&ctx); sha1_input(&ctx, (guint8 *) even, 16); sha1_digest(&ctx, even_hash); Sp = out; op = (gchar *) odd_hash; ep = (gchar *) even_hash; for (i = 0; i < 20; i++) { *(Sp++) = *(op++); *(Sp++) = *(ep++); } srp->K = (gchar *) g_malloc(40); if (srp->K) g_memmove(srp->K, out, 40); }
void mediv_random_update(mediv_random_context *ctx){ sha1_context sha; sha.version = SHA1; sha1_reset(&sha); sha1_input(&sha, ctx->source1, 0x14); sha1_input(&sha, ctx->data, 0x14); sha1_input(&sha, ctx->source2, 0x14); sha1_digest(&sha, ctx->data); }
static guint32 srp_get_u(const gchar *B) { sha1_context ctx; union { guint8 as8[SHA1_HASH_SIZE]; guint32 as32[5]; } data; guint32 u; ctx.version = SHA1_TYPE_NORMAL; sha1_reset(&ctx); sha1_input(&ctx, (guint8 *) B, 32); sha1_digest(&ctx, data.as8); u = data.as32[0]; u = MSB4(u); // needed? yes return u; }
uint32_t __stdcall crev_ver3(uint8_t *archive_time, uint8_t *archive_name, uint8_t *seed, uint8_t *ini_file, uint8_t *ini_header, uint32_t *version, uint32_t *checksum, uint8_t *result){ uint32_t x = 0; uint32_t y = 0; uint32_t z = 0; uint32_t lret; uint8_t *files[5]; //uint8_t *tok; uint8_t *buff; uint8_t *buff2; uint32_t archive_rev = 0; uint32_t header_size = 0; sha1_context sha; lockdown_heep ldh; uint32_t pe_file; PE_IMAGE_NT_HEADERS *nt; PE_IMAGE_SECTION_HEADER *sections; const uint8_t *keys[] = {"Exe", "Util", "Network", "Screen"}; const uint32_t seeds[] = { 0xA1F3055A, 0x5657124C, 0x1780AB47, 0x80B3A410, 0xAF2179EA, 0x0837B808, 0x6F2516C6, 0xE3178148, 0x0FCF90B6, 0xF2F09516, 0x378D8D8C, 0x07F8E083, 0xB0EE9741, 0x7923C9AF, 0xCA11A05E, 0xD723C016, 0xFD545590, 0xFB600C2E, 0x684C8785, 0x58BEDE0B }; sha.version = lSHA1; sha1_reset(&sha); if( (archive_name[14] < '0' || archive_name[14] > '1') || (archive_name[15] < '0' || archive_name[15] > '9')){ return CREV_UNKNOWN_REVISION; } archive_rev = ((archive_name[14] - '0') * 10) + (archive_name[15] - '0'); buff = safe_malloc(MAX_PATH); read_ini_new(ini_file, ini_header, "Path", "", buff, MAX_PATH); files[0] = safe_malloc(MAX_PATH); combine_paths(buff, "", files[0], MAX_PATH); for(x = 1; x < 5; x++){ read_ini_new(ini_file, ini_header, (uint8_t*)keys[x-1], "\xFF", buff, MAX_PATH); if(buff[0] == 0xFF){ for(y = 0; y < x; y++) if(files[y] != NULL) free(files[y]); sprintf_s(result, crev_max_result(), "%s\x00", keys[x-1]); free(buff); return CREV_MISSING_FILENAME; } files[x] = safe_malloc(MAX_PATH); combine_paths(files[0], buff, files[x], MAX_PATH); } read_ini_new(ini_file, "CRev_Main", "LockdownPath", "", buff, MAX_PATH); combine_paths(buff, "", files[0], MAX_PATH); sprintf_s(files[0], MAX_PATH, "%s\\Lockdown-IX86-%02d.dll", files[0], archive_rev); free(buff); lockdown_shuffle_seed(seed); buff = safe_malloc(0x40); memset(buff, '6', 0x40); for(x = 0; x < 0x10; x++) buff[x] ^= seed[x]; sha1_input(&sha, buff, 0x40); free(buff); for(x = 0; x < 4; x++){ pe_file = pe_load_library(files[x]); if(pe_file == 0){ sprintf_s(result, CREV_MAX_RESULT, files[x]); for(z = 0; z < 5; z++) if(files[z] != NULL) free(files[z]); return CREV_MISSING_FILE; } nt = (PE_IMAGE_NT_HEADERS*)(pe_file + ((PE_IMAGE_DOS_HEADER*)pe_file)->e_lfanew); if(nt->OptionalHeader.NumberOfRvaAndSizes <= 0x0D){ for(z = 0; z < 5; z++) if(files[z] != NULL) free(files[z]); pe_unload_library(pe_file); return CREV_TOFEW_RVAS; } header_size = nt->OptionalHeader.SizeOfHeaders; if((header_size % nt->OptionalHeader.FileAlignment) != 0) header_size += (nt->OptionalHeader.FileAlignment - (header_size % nt->OptionalHeader.FileAlignment)); sha1_input(&sha, (uint8_t*)pe_file, header_size); //Hash the PE Header lockdown_heep_create(&ldh); lret = lockdown_proc_reloc(pe_file, &ldh); if(lret != CREV_SUCCESS){ sprintf_s(result, CREV_MAX_RESULT, files[x]); for(z = 0; z < 5; z++) if(files[z] != NULL) free(files[z]); pe_unload_library(pe_file); return lret; } lret = lockdown_proc_import(pe_file, &ldh); if(lret != CREV_SUCCESS){ sprintf_s(result, CREV_MAX_RESULT, files[x]); for(z = 0; z < 5; z++) if(files[z] != NULL) free(files[z]); pe_unload_library(pe_file); return lret; } lockdown_heep_sort(&ldh); /*for(y = 0; y < ldh.cur_len; y += 0x10){ wwrite_to_file(tto_hex((uint8_t*)(ldh.mem + y), 16, FALSE)); wwrite_to_file("\n"); }*/ sections = (PE_IMAGE_SECTION_HEADER *)(pe_file + nt->FileHeader.SizeOfOptionalHeader + ((PE_IMAGE_DOS_HEADER*)pe_file)->e_lfanew + PE_SIZE_OF_NT_SIGNATURE + PE_IMAGE_SIZEOF_FILE_HEADER); for(y = 0; y < nt->FileHeader.NumberOfSections; y++){ lret = lockdown_hash1(&sha, &ldh, (uint32_t)(§ions[y]), pe_file, seeds[archive_rev]); if(lret != CREV_SUCCESS){ sprintf_s(result, CREV_MAX_RESULT, files[x]); for(z = 0; z < 5; z++) if(files[z] != NULL) free(files[z]); pe_unload_library(pe_file); return lret; } } lockdown_heep_cleanup(&ldh); pe_unload_library(pe_file); } //Hash Screen Buffer x = get_file_size(files[4]); if(x == 0){ sprintf_s(result, CREV_MAX_RESULT, files[3]); return CREV_MISSING_FILE; } buff = safe_malloc(x); get_file_data(files[4], buff, x, 0); sha1_input(&sha, buff, x); free(buff); sha1_input(&sha, "\x01\x00\x00\x00", 4); //Verify Return Address sha1_input(&sha, "\x00\x00\x00\x00", 4); //Verify Module Offset buff2 = safe_malloc(sha1_hash_size); sha1_digest(&sha, buff2); //wwrite_to_file(tto_hex(buff2, sha1_hash_size, FALSE)); wwrite_to_file("\n"); //Second SHA Pass buff = safe_malloc(0x40); memset(buff, '\\', 0x40); for(x = 0; x < 0x10; x++) buff[x] ^= seed[x]; sha1_reset(&sha); sha1_input(&sha, buff, 0x40); sha1_input(&sha, buff2, sha1_hash_size); memset(buff2, 0, sha1_hash_size); sha1_digest(&sha, buff2); lockdown_shuffle_digest((uint8_t*)(&buff2[4])); *version = crev_get_file_version(files[1]); *checksum = (*(uint32_t*)&buff2[0]); memcpy(result, (uint8_t*)(&buff2[4]), 0x10); for(x = 0; x < 5; x++) if(files[x] != NULL) free(files[x]); return CREV_SUCCESS; }
int srp_check_M2(srp_t *srp, const gchar *var_M2) { sha1_context ctx; gchar local_M2[SHA1_HASH_SIZE]; gchar *A; gchar S[32]; gchar *K; gchar *M1; guint8 username_hash[SHA1_HASH_SIZE]; int res; int mustFree = 0; ctx.version = SHA1_TYPE_NORMAL; if (!srp) return 0; if (srp->M2) return (memcmp(srp->M2, var_M2, 20) == 0); if (srp->A && srp->K && srp->M1) { A = srp->A; K = srp->K; M1 = srp->M1; } else { if (!srp->B || !srp->salt) return 0; A = (gchar *) g_malloc(32); if (!A) return 0; K = (gchar *) g_malloc(40); if (!K) { g_free(A); return 0; } M1 = (gchar *) g_malloc(20); if (!M1) { g_free(K); g_free(A); return 0; } mustFree = 1; /* get the other values needed for the hash */ srp_get_A(srp, A); srp_get_S(srp, S, (gchar *) srp->B, (gchar *) srp->salt); srp_get_K(srp, K, S); /* calculate SHA-1 hash of username */ sha1_reset(&ctx); sha1_input(&ctx, (guint8 *) srp->username_upper, srp->username_len); sha1_digest(&ctx, username_hash); /* calculate M[1] */ sha1_reset(&ctx); sha1_input(&ctx, (guint8 *) srp_I, 20); sha1_input(&ctx, username_hash, 20); sha1_input(&ctx, (guint8 *) srp->salt, 32); sha1_input(&ctx, (guint8 *) A, 32); sha1_input(&ctx, (guint8 *) srp->B, 32); sha1_input(&ctx, (guint8 *) K, 40); sha1_digest(&ctx, (guint8 *) M1); } /* calculate M[2] */ sha1_reset(&ctx); sha1_input(&ctx, (guint8 *) A, 32); sha1_input(&ctx, (guint8 *) M1, 20); sha1_input(&ctx, (guint8 *) K, 40); sha1_digest(&ctx, (guint8 *) local_M2); res = (memcmp(local_M2, var_M2, 20) == 0); if (mustFree) { g_free(A); g_free(K); g_free(M1); } /* cache result */ srp->M2 = (gchar *) g_malloc(20); if (srp->M2) g_memmove(srp->M2, local_M2, 20); return res; }