samlogon.c
来自「samba最新软件」· C语言 代码 · 共 1,856 行 · 第 1/4 页
C
1,856 行
sizeof(lm_key)) != 0) { d_printf("LM Key does not match expectations (first 8 session key)!\n"); d_printf("lm_key:\n"); dump_data(1, lm_key, 8); d_printf("expected:\n"); dump_data(1, session_key.data, 8); pass = false; }#endif } if (lm_good && memcmp(lm_hash, user_session_key, 8) != 0) { uint8_t lm_key_expected[16]; memcpy(lm_key_expected, lm_hash, 8); memset(lm_key_expected+8, '\0', 8); if (memcmp(lm_key_expected, user_session_key, 16) != 0) { d_printf("NT Session Key does not match expectations (should be first-8 LM hash)!\n"); d_printf("user_session_key:\n"); dump_data(1, user_session_key, sizeof(user_session_key)); d_printf("expected:\n"); dump_data(1, lm_key_expected, sizeof(lm_key_expected)); pass = false; } } return pass;}/* * Test the NTLM response only, but in the both the NT and LM fields. */static bool test_ntlm_in_both(struct samlogon_state *samlogon_state, char **error_string) { bool pass = true; bool lm_good; NTSTATUS nt_status; DATA_BLOB nt_response = data_blob_talloc(samlogon_state->mem_ctx, NULL, 24); DATA_BLOB session_key = data_blob_talloc(samlogon_state->mem_ctx, NULL, 16); uint8_t lm_key[8]; uint8_t lm_hash[16]; uint8_t user_session_key[16]; uint8_t nt_hash[16]; ZERO_STRUCT(lm_key); ZERO_STRUCT(user_session_key); SMBNTencrypt(samlogon_state->password, samlogon_state->chall.data, nt_response.data); E_md4hash(samlogon_state->password, nt_hash); SMBsesskeygen_ntv1(nt_hash, session_key.data); lm_good = E_deshash(samlogon_state->password, lm_hash); if (!lm_good) { ZERO_STRUCT(lm_hash); } nt_status = check_samlogon(samlogon_state, BREAK_NONE, samlogon_state->parameter_control, &samlogon_state->chall, NULL, &nt_response, lm_key, user_session_key, error_string); if (NT_STATUS_EQUAL(NT_STATUS_WRONG_PASSWORD, nt_status)) { /* for 'old' passwords, we allow the server to be OK or wrong password */ if (samlogon_state->old_password) { return true; } return false; } else if (!NT_STATUS_EQUAL(samlogon_state->expected_error, nt_status)) { SAFE_FREE(*error_string); asprintf(error_string, "Expected error: %s, got %s", nt_errstr(samlogon_state->expected_error), nt_errstr(nt_status)); return false; } else if (NT_STATUS_EQUAL(samlogon_state->expected_error, nt_status) && !NT_STATUS_IS_OK(nt_status)) { return true; } else if (!NT_STATUS_IS_OK(nt_status)) { return false; } if (!NT_STATUS_IS_OK(nt_status)) { return false; } if (memcmp(lm_hash, lm_key, sizeof(lm_key)) != 0) { d_printf("LM Key does not match expectations!\n"); d_printf("lm_key:\n"); dump_data(1, lm_key, 8); d_printf("expected:\n"); dump_data(1, lm_hash, 8); pass = false; } if (memcmp(session_key.data, user_session_key, sizeof(user_session_key)) != 0) { d_printf("NT Session Key does not match expectations!\n"); d_printf("user_session_key:\n"); dump_data(1, user_session_key, 16); d_printf("expected:\n"); dump_data(1, session_key.data, session_key.length); pass = false; } return pass;}/* * Test the NTLMv2 and LMv2 responses */enum ntlmv2_domain { UPPER_DOMAIN, NO_DOMAIN};static bool test_lmv2_ntlmv2_broken(struct samlogon_state *samlogon_state, enum ntlm_break break_which, enum ntlmv2_domain ntlmv2_domain, char **error_string) { bool pass = true; NTSTATUS nt_status; DATA_BLOB ntlmv2_response = data_blob(NULL, 0); DATA_BLOB lmv2_response = data_blob(NULL, 0); DATA_BLOB lmv2_session_key = data_blob(NULL, 0); DATA_BLOB ntlmv2_session_key = data_blob(NULL, 0); DATA_BLOB names_blob = NTLMv2_generate_names_blob(samlogon_state->mem_ctx, samlogon_state->iconv_convenience, TEST_MACHINE_NAME, lp_workgroup(global_loadparm)); uint8_t lm_session_key[8]; uint8_t user_session_key[16]; ZERO_STRUCT(lm_session_key); ZERO_STRUCT(user_session_key); switch (ntlmv2_domain) { case UPPER_DOMAIN: if (!SMBNTLMv2encrypt(samlogon_state->mem_ctx, samlogon_state->account_name, samlogon_state->account_domain, samlogon_state->password, &samlogon_state->chall, &names_blob, &lmv2_response, &ntlmv2_response, &lmv2_session_key, &ntlmv2_session_key)) { data_blob_free(&names_blob); return false; } break; case NO_DOMAIN: if (!SMBNTLMv2encrypt(samlogon_state->mem_ctx, samlogon_state->account_name, "", samlogon_state->password, &samlogon_state->chall, &names_blob, &lmv2_response, &ntlmv2_response, &lmv2_session_key, &ntlmv2_session_key)) { data_blob_free(&names_blob); return false; } break; } data_blob_free(&names_blob); nt_status = check_samlogon(samlogon_state, break_which, samlogon_state->parameter_control, &samlogon_state->chall, &lmv2_response, &ntlmv2_response, lm_session_key, user_session_key, error_string); data_blob_free(&lmv2_response); data_blob_free(&ntlmv2_response); if (NT_STATUS_EQUAL(NT_STATUS_WRONG_PASSWORD, nt_status)) { /* for 'old' passwords, we allow the server to be OK or wrong password */ if (samlogon_state->old_password) { return true; } return break_which == BREAK_BOTH; } else if (NT_STATUS_EQUAL(NT_STATUS_NOT_FOUND, nt_status) && strchr_m(samlogon_state->account_name, '@')) { return ((break_which == BREAK_NT) || (break_which == BREAK_BOTH) || (break_which == NO_NT)); } else if (!NT_STATUS_EQUAL(samlogon_state->expected_error, nt_status)) { SAFE_FREE(*error_string); asprintf(error_string, "Expected error: %s, got %s", nt_errstr(samlogon_state->expected_error), nt_errstr(nt_status)); return false; } else if (NT_STATUS_EQUAL(samlogon_state->expected_error, nt_status) && !NT_STATUS_IS_OK(nt_status)) { return true; } else if (!NT_STATUS_IS_OK(nt_status)) { return false; } switch (break_which) { case NO_NT: if (memcmp(lmv2_session_key.data, user_session_key, sizeof(user_session_key)) != 0) { d_printf("USER (LMv2) Session Key does not match expectations!\n"); d_printf("user_session_key:\n"); dump_data(1, user_session_key, 16); d_printf("expected:\n"); dump_data(1, lmv2_session_key.data, ntlmv2_session_key.length); pass = false; } if (memcmp(lmv2_session_key.data, lm_session_key, sizeof(lm_session_key)) != 0) { d_printf("LM (LMv2) Session Key does not match expectations!\n"); d_printf("lm_session_key:\n"); dump_data(1, lm_session_key, 8); d_printf("expected:\n"); dump_data(1, lmv2_session_key.data, 8); pass = false; } break; default: if (memcmp(ntlmv2_session_key.data, user_session_key, sizeof(user_session_key)) != 0) { if (memcmp(lmv2_session_key.data, user_session_key, sizeof(user_session_key)) == 0) { d_printf("USER (NTLMv2) Session Key expected, got LMv2 sessesion key instead:\n"); d_printf("user_session_key:\n"); dump_data(1, user_session_key, 16); d_printf("expected:\n"); dump_data(1, ntlmv2_session_key.data, ntlmv2_session_key.length); pass = false; } else { d_printf("USER (NTLMv2) Session Key does not match expectations!\n"); d_printf("user_session_key:\n"); dump_data(1, user_session_key, 16); d_printf("expected:\n"); dump_data(1, ntlmv2_session_key.data, ntlmv2_session_key.length); pass = false; } } if (memcmp(ntlmv2_session_key.data, lm_session_key, sizeof(lm_session_key)) != 0) { if (memcmp(lmv2_session_key.data, lm_session_key, sizeof(lm_session_key)) == 0) { d_printf("LM (NTLMv2) Session Key expected, got LMv2 sessesion key instead:\n"); d_printf("user_session_key:\n"); dump_data(1, lm_session_key, 8); d_printf("expected:\n"); dump_data(1, ntlmv2_session_key.data, 8); pass = false; } else { d_printf("LM (NTLMv2) Session Key does not match expectations!\n"); d_printf("lm_session_key:\n"); dump_data(1, lm_session_key, 8); d_printf("expected:\n"); dump_data(1, ntlmv2_session_key.data, 8); pass = false; } } } return pass;}/* * Test the NTLM and LMv2 responses */static bool test_lmv2_ntlm_broken(struct samlogon_state *samlogon_state, enum ntlm_break break_which, enum ntlmv2_domain ntlmv2_domain, char **error_string) { bool pass = true; NTSTATUS nt_status; DATA_BLOB ntlmv2_response = data_blob(NULL, 0); DATA_BLOB lmv2_response = data_blob(NULL, 0); DATA_BLOB lmv2_session_key = data_blob(NULL, 0); DATA_BLOB ntlmv2_session_key = data_blob(NULL, 0); DATA_BLOB names_blob = NTLMv2_generate_names_blob(samlogon_state->mem_ctx, samlogon_state->iconv_convenience, lp_netbios_name(global_loadparm), lp_workgroup(global_loadparm)); DATA_BLOB ntlm_response = data_blob_talloc(samlogon_state->mem_ctx, NULL, 24); DATA_BLOB ntlm_session_key = data_blob_talloc(samlogon_state->mem_ctx, NULL, 16); bool lm_good; uint8_t lm_hash[16]; uint8_t lm_session_key[8]; uint8_t user_session_key[16]; uint8_t nt_hash[16]; SMBNTencrypt(samlogon_state->password, samlogon_state->chall.data, ntlm_response.data); E_md4hash(samlogon_state->password, nt_hash); SMBsesskeygen_ntv1(nt_hash, ntlm_session_key.data); lm_good = E_deshash(samlogon_state->password, lm_hash); if (!lm_good) { ZERO_STRUCT(lm_hash); } ZERO_STRUCT(lm_session_key); ZERO_STRUCT(user_session_key); switch (ntlmv2_domain) { case UPPER_DOMAIN: /* TODO - test with various domain cases, and without domain */ if (!SMBNTLMv2encrypt(samlogon_state->mem_ctx, samlogon_state->account_name, samlogon_state->account_domain, samlogon_state->password, &samlogon_state->chall, &names_blob, &lmv2_response, &ntlmv2_response, &lmv2_session_key, &ntlmv2_session_key)) { data_blob_free(&names_blob); return false; } break; case NO_DOMAIN: /* TODO - test with various domain cases, and without domain */ if (!SMBNTLMv2encrypt(samlogon_state->mem_ctx, samlogon_state->account_name, "", samlogon_state->password, &samlogon_state->chall, &names_blob, &lmv2_response, &ntlmv2_response, &lmv2_session_key, &ntlmv2_session_key)) { data_blob_free(&names_blob); return false; } break; } data_blob_free(&names_blob); nt_status = check_samlogon(samlogon_state, break_which, samlogon_state->parameter_control, &samlogon_state->chall, &lmv2_response, &ntlm_response, lm_session_key, user_session_key, error_string); data_blob_free(&lmv2_response); data_blob_free(&ntlmv2_response); if (NT_STATUS_EQUAL(NT_STATUS_WRONG_PASSWORD, nt_status)) { /* for 'old' passwords, we allow the server to be OK or wrong password */ if (samlogon_state->old_password) { return true; } return ((break_which == BREAK_NT) || (break_which == BREAK_BOTH)); } else if (NT_STATUS_EQUAL(NT_STATUS_NOT_FOUND, nt_status) && strchr_m(samlogon_state->account_name, '@')) { return ((break_which == BREAK_NT) || (break_which == BREAK_BOTH)); } else if (!NT_STATUS_EQUAL(samlogon_state->expected_error, nt_status)) { SAFE_FREE(*error_string); asprintf(error_string, "Expected error: %s, got %s", nt_errstr(samlogon_state->expected_error), nt_errstr(nt_status)); return false; } else if (NT_STATUS_EQUAL(samlogon_state->expected_error, nt_status) && !NT_STATUS_IS_OK(nt_status)) { return true; } else if (!NT_STATUS_IS_OK(nt_status)) { return false; } switch (break_which) { case NO_NT: if (memcmp(lmv2_session_key.data, user_session_key, sizeof(user_session_key)) != 0) { d_printf("USER (LMv2) Session Key does not match expectations!\n"); d_printf("user_session_key:\n"); dump_data(1, user_session_key, 16); d_printf("expected:\n"); dump_data(1, lmv2_session_key.data, ntlmv2_session_key.length); pass = false; } if (memcmp(lmv2_session_key.data, lm_session_key, sizeof(lm_session_key)) != 0) { d_printf("LM (LMv2) Session Key does not match expectations!\n"); d_printf("lm_session_key:\n"); dump_data(1, lm_session_key, 8); d_printf("expected:\n"); dump_data(1, lmv2_session_key.data, 8); pass = false; } break; case BREAK_LM: if (memcmp(ntlm_session_key.data, user_session_key, sizeof(user_session_key)) != 0) { d_printf("USER (NTLMv2) Session Key does not match expectations!\n"); d_printf("user_session_key:\n"); dump_data(1, user_session_key, 16); d_printf("expected:\n"); dump_data(1, ntlm_session_key.data, ntlm_session_key.length); pass = false; } if (lm_good) { if (memcmp(lm_hash, lm_session_key, sizeof(lm_session_key)) != 0) { d_printf("LM Session Key does not match expectations!\n"); d_printf("lm_session_key:\n"); dump_data(1, lm_session_key, 8); d_printf("expected:\n"); dump_data(1, lm_hash, 8); pass = false; } } else { static const uint8_t zeros[8]; if (memcmp(zeros, lm_session_key, sizeof(lm_session_key)) != 0) { d_printf("LM Session Key does not match expectations (zeros)!\n"); d_printf("lm_session_key:\n"); dump_data(1, lm_session_key, 8); d_printf("expected:\n"); dump_data(1, zeros, 8); pass = false; } } break; default: if (memcmp(ntlm_session_key.data, user_session_key, sizeof(user_session_key)) != 0) { d_printf("USER (NTLMv2) Session Key does not match expectations!\n"); d_printf("user_session_key:\n"); dump_data(1, user_session_key, 16); d_printf("expected:\n"); dump_data(1, ntlm_session_key.data, ntlm_session_key.length); pass = false; } if (memcmp(ntlm_session_key.data, lm_session_key, sizeof(lm_session_key)) != 0) { d_printf("LM (NTLMv2) Session Key does not match expectations!\n"); d_printf("lm_session_key:\n"); dump_data(1, lm_session_key, 8); d_printf("expected:\n"); dump_data(1, ntlm_session_key.data, 8); pass = false; } } return pass;}/* * Test the NTLMv2 and LMv2 responses */static bool test_lmv2_ntlmv2(struct samlogon_state *samlogon_state, char **error_string) { return test_lmv2_ntlmv2_broken(samlogon_state, BREAK_NONE, UPPER_DOMAIN, error_string);}#if 0static bool test_lmv2_ntlmv2_no_dom(struct samlogon_state *samlogon_state, char **error_string) { return test_lmv2_ntlmv2_broken(samlogon_state, BREAK_NONE, NO_DOMAIN, error_string);}#endif/* * Test the LMv2 response only */static bool test_lmv2(struct samlogon_state *samlogon_state, char **error_string)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?