def test_lm_v2_response_with_no_target_info_timestamp(self, monkeypatch): monkeypatch.setattr('os.urandom', lambda s: b"\xaa" * 8) test_target_info = TargetInfo() test_target_info[AvId.MSV_AV_NB_DOMAIN_NAME] = \ b"\x44\x00\x6f\x00\x6d\x00\x61\x00\x69\x00\x6e\x00" test_target_info[AvId.MSV_AV_NB_COMPUTER_NAME] = \ b"\x53\x00\x65\x00\x72\x00\x76\x00\x65\x00\x72\x00" test_challenge_message = ChallengeMessage( b"\x4e\x54\x4c\x4d\x53\x53\x50\x00" b"\x02\x00\x00\x00\x03\x00\x0c\x00" b"\x38\x00\x00\x00\x33\x82\x8a\xe2" b"\x01\x23\x45\x67\x89\xab\xcd\xef" b"\x00\x00\x00\x00\x00\x00\x00\x00" b"\x24\x00\x24\x00\x44\x00\x00\x00" b"\x06\x00\x70\x17\x00\x00\x00\x0f" b"\x53\x00\x65\x00\x72\x00\x76\x00" b"\x65\x00\x72\x00\x02\x00\x0c\x00" b"\x44\x00\x6f\x00\x6d\x00\x61\x00" b"\x69\x00\x6e\x00\x01\x00\x0c\x00" b"\x53\x00\x65\x00\x72\x00\x76\x00" b"\x65\x00\x72\x00\x00\x00\x00\x00" ) test_challenge_message.target_info = test_target_info expected = b"\x86\xc3\x50\x97\xac\x9c\xec\x10" \ b"\x25\x54\x76\x4a\x57\xcc\xcc\x19" \ b"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" actual = ComputeResponse("User", "Password", "Domain", test_challenge_message, 3).get_lm_challenge_response() assert actual == expected
def test_lm_v2_response_with_server_target_info_timestamp(self): test_target_info = TargetInfo() test_target_info[AvId.MSV_AV_NB_DOMAIN_NAME] = \ b"\x44\x00\x6f\x00\x6d\x00\x61\x00\x69\x00\x6e\x00" test_target_info[AvId.MSV_AV_NB_COMPUTER_NAME] = \ b"\x53\x00\x65\x00\x72\x00\x76\x00\x65\x00\x72\x00" test_target_info[AvId.MSV_AV_TIMESTAMP] = b"\x00" * 8 test_challenge_message = ChallengeMessage( b"\x4e\x54\x4c\x4d\x53\x53\x50\x00" b"\x02\x00\x00\x00\x03\x00\x0c\x00" b"\x38\x00\x00\x00\x33\x82\x8a\xe2" b"\x01\x23\x45\x67\x89\xab\xcd\xef" b"\x00\x00\x00\x00\x00\x00\x00\x00" b"\x24\x00\x24\x00\x44\x00\x00\x00" b"\x06\x00\x70\x17\x00\x00\x00\x0f" b"\x53\x00\x65\x00\x72\x00\x76\x00" b"\x65\x00\x72\x00\x02\x00\x0c\x00" b"\x44\x00\x6f\x00\x6d\x00\x61\x00" b"\x69\x00\x6e\x00\x01\x00\x0c\x00" b"\x53\x00\x65\x00\x72\x00\x76\x00" b"\x65\x00\x72\x00\x00\x00\x00\x00" ) test_challenge_message.target_info = test_target_info # Not in MS-NLMP, using expected value expected = b"\x00" * 24 actual = ComputeResponse("User", "Password", "Domain", test_challenge_message, 3).get_lm_challenge_response() assert actual == expected
def test_nt_v2_response_with_timestamp_av_pair(self, monkeypatch): monkeypatch.setattr('os.urandom', lambda s: b"\xaa" * 8) test_target_info = TargetInfo() test_target_info[AvId.MSV_AV_NB_DOMAIN_NAME] = \ b"\x44\x00\x6f\x00\x6d\x00\x61\x00\x69\x00\x6e\x00" test_target_info[AvId.MSV_AV_NB_COMPUTER_NAME] = \ b"\x53\x00\x65\x00\x72\x00\x76\x00\x65\x00\x72\x00" test_target_info[AvId.MSV_AV_TIMESTAMP] = b"\x00" * 8 test_challenge_message = ChallengeMessage( b"\x4e\x54\x4c\x4d\x53\x53\x50\x00" b"\x02\x00\x00\x00\x03\x00\x0c\x00" b"\x38\x00\x00\x00\x33\x82\x8a\xe2" b"\x01\x23\x45\x67\x89\xab\xcd\xef" b"\x00\x00\x00\x00\x00\x00\x00\x00" b"\x24\x00\x24\x00\x44\x00\x00\x00" b"\x06\x00\x70\x17\x00\x00\x00\x0f" b"\x53\x00\x65\x00\x72\x00\x76\x00" b"\x65\x00\x72\x00\x02\x00\x0c\x00" b"\x44\x00\x6f\x00\x6d\x00\x61\x00" b"\x69\x00\x6e\x00\x01\x00\x0c\x00" b"\x53\x00\x65\x00\x72\x00\x76\x00" b"\x65\x00\x72\x00\x00\x00\x00\x00" ) test_challenge_message.target_info = test_target_info test_lmv2_response = b"\x86\xc3\x50\x97\xac\x9c\xec\x10" \ b"\x25\x54\x76\x4a\x57\xcc\xcc\x19" \ b"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" expected_response = b"\x5d\xeb\xf3\x87\x1c\x28\x94\xb8" \ b"\x1f\x16\x42\x81\xed\xbf\x0b\xff" \ b"\x01\x01\x00\x00\x00\x00\x00\x00" \ b"\x00\x00\x00\x00\x00\x00\x00\x00" \ b"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" \ b"\x00\x00\x00\x00\x02\x00\x0c\x00" \ b"\x44\x00\x6f\x00\x6d\x00\x61\x00" \ b"\x69\x00\x6e\x00\x01\x00\x0c\x00" \ b"\x53\x00\x65\x00\x72\x00\x76\x00" \ b"\x65\x00\x72\x00\x07\x00\x08\x00" \ b"\x00\x00\x00\x00\x00\x00\x00\x00" \ b"\x06\x00\x04\x00\x02\x00\x00\x00" \ b"\x00\x00\x00\x00\x00\x00\x00\x00" expected_exchange_key = b"\x9b\x37\x06\x8f\x99\x7a\x06\x5f" \ b"\xe9\xc7\x20\x63\x32\x88\xd4\x8f" expected_target_info = test_target_info expected_target_info[AvId.MSV_AV_FLAGS] = \ struct.pack("<L", AvFlags.MIC_PROVIDED) comp_response = ComputeResponse("User", "Password", "Domain", test_challenge_message, 3) actual_response, actual_exchange_key, actual_target_info = \ comp_response.get_nt_challenge_response(test_lmv2_response, None) assert actual_response == expected_response assert actual_exchange_key == expected_exchange_key assert actual_target_info == expected_target_info
def test_nt_v2_response(self, monkeypatch): monkeypatch.setattr('os.urandom', lambda s: b"\xaa" * 8) monkeypatch.setattr('ntlm_auth.compute_response.get_windows_timestamp', lambda: b"\x00" * 8) test_target_info = TargetInfo() test_target_info[AvId.MSV_AV_NB_DOMAIN_NAME] = \ b"\x44\x00\x6f\x00\x6d\x00\x61\x00\x69\x00\x6e\x00" test_target_info[AvId.MSV_AV_NB_COMPUTER_NAME] = \ b"\x53\x00\x65\x00\x72\x00\x76\x00\x65\x00\x72\x00" test_challenge_message = ChallengeMessage( b"\x4e\x54\x4c\x4d\x53\x53\x50\x00" b"\x02\x00\x00\x00\x03\x00\x0c\x00" b"\x38\x00\x00\x00\x33\x82\x8a\xe2" b"\x01\x23\x45\x67\x89\xab\xcd\xef" b"\x00\x00\x00\x00\x00\x00\x00\x00" b"\x24\x00\x24\x00\x44\x00\x00\x00" b"\x06\x00\x70\x17\x00\x00\x00\x0f" b"\x53\x00\x65\x00\x72\x00\x76\x00" b"\x65\x00\x72\x00\x02\x00\x0c\x00" b"\x44\x00\x6f\x00\x6d\x00\x61\x00" b"\x69\x00\x6e\x00\x01\x00\x0c\x00" b"\x53\x00\x65\x00\x72\x00\x76\x00" b"\x65\x00\x72\x00\x00\x00\x00\x00" ) test_challenge_message.target_info = test_target_info test_lmv2_response = b"\x86\xc3\x50\x97\xac\x9c\xec\x10" \ b"\x25\x54\x76\x4a\x57\xcc\xcc\x19" \ b"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" expected_response = b"\x68\xcd\x0a\xb8\x51\xe5\x1c\x96" \ b"\xaa\xbc\x92\x7b\xeb\xef\x6a\x1c" \ b"\x01\x01\x00\x00\x00\x00\x00\x00" \ b"\x00\x00\x00\x00\x00\x00\x00\x00" \ b"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" \ b"\x00\x00\x00\x00\x02\x00\x0c\x00" \ b"\x44\x00\x6f\x00\x6d\x00\x61\x00" \ b"\x69\x00\x6e\x00\x01\x00\x0c\x00" \ b"\x53\x00\x65\x00\x72\x00\x76\x00" \ b"\x65\x00\x72\x00\x00\x00\x00\x00" \ b"\x00\x00\x00\x00" expected_exchange_key = b"\x8d\xe4\x0c\xca\xdb\xc1\x4a\x82" \ b"\xf1\x5c\xb0\xad\x0d\xe9\x5c\xa3" expected_target_info = test_target_info comp_response = ComputeResponse("User", "Password", "Domain", test_challenge_message, 3) actual_response, actual_exchange_key, actual_target_info = \ comp_response.get_nt_challenge_response(test_lmv2_response, None) assert actual_response == expected_response assert actual_exchange_key == expected_exchange_key assert actual_target_info == expected_target_info
def test_authenticate_message_ntlm_v1_non_unicode(self, session_key, version_function): test_challenge_message = ChallengeMessage(ntlmv1_challenge_message) test_challenge_message.negotiate_flags -= NegotiateFlags.NTLMSSP_NEGOTIATE_UNICODE test_challenge_message.negotiate_flags |= NegotiateFlags.NTLMSSP_NEGOTIATE_OEM # Not a Microsoft example, using pre-computed value expected = HexToByte('4e 54 4c 4d 53 53 50 00 03 00 00 00 18 00 18 00' '62 00 00 00 18 00 18 00 7a 00 00 00 06 00 06 00' '48 00 00 00 04 00 04 00 4e 00 00 00 10 00 10 00' '52 00 00 00 10 00 10 00 92 00 00 00 32 82 02 e2' '05 01 28 0a 00 00 00 0f 44 6f 6d 61 69 6e 55 73' '65 72 43 00 4f 00 4d 00 50 00 55 00 54 00 45 00' '52 00 98 de f7 b8 7f 88 aa 5d af e2 df 77 96 88' 'a1 72 de f1 1c 7d 5c cd ef 13 67 c4 30 11 f3 02' '98 a2 ad 35 ec e6 4f 16 33 1c 44 bd be d9 27 84' '1f 94 51 88 22 b1 b3 f3 50 c8 95 86 82 ec bb 3e' '3c b7') actual = AuthenticateMessage(user_name, password, domain_name, workstation_name, test_challenge_message, 1, None) actual.add_mic(None, test_challenge_message) actual = actual.get_data() assert actual == expected
def test_challenge(self): expected_message_type = MessageTypes.NTLM_CHALLENGE expected_negotiate_flags = 2181726771 expected_server_challenge = b"\x01\x23\x45\x67\x89\xab\xcd\xef" expected_signature = NTLM_SIGNATURE expected_target_info = None expected_target_name = None expected_version = 1080863910962135046 challenge_msg = b"\x4e\x54\x4c\x4d\x53\x53\x50\x00" \ b"\x02\x00\x00\x00\x0c\x00\x0c\x00" \ b"\x38\x00\x00\x00\x33\x82\x0a\x82" \ b"\x01\x23\x45\x67\x89\xab\xcd\xef" \ b"\x00\x00\x00\x00\x00\x00\x00\x00" \ b"\x00\x00\x00\x00\x00\x00\x00\x00" \ b"\x06\x00\x70\x17\x00\x00\x00\x0f" \ b"\x53\x00\x65\x00\x72\x00\x76\x00" \ b"\x65\x00\x72\x00" actual = ChallengeMessage(challenge_msg) actual_message_type = actual.message_type actual_negotiate_flags = actual.negotiate_flags actual_server_challenge = actual.server_challenge actual_signature = actual.signature actual_target_info = actual.target_info actual_target_name = actual.target_name actual_version = actual.version assert actual_message_type == expected_message_type assert actual_negotiate_flags == expected_negotiate_flags assert actual_server_challenge == expected_server_challenge assert actual_signature == expected_signature assert actual_target_info == expected_target_info assert actual_target_name == expected_target_name assert actual_version == expected_version
def test_authenticate_message_with_cbt(self, random_function, session_key_function, timestamp_function): test_challenge_message = ChallengeMessage(ntlmv2_challenge_message) test_server_cert_hash = 'E3CA49271E5089CC48CE82109F1324F41DBEDDC29A777410C738F7868C4FF405' # Not a Microsoft example, using pre-computed value expected = HexToByte('4e 54 4c 4d 53 53 50 00 03 00 00 00 18 00 18 00' '7c 00 00 00 68 00 68 00 94 00 00 00 0c 00 0c 00' '48 00 00 00 08 00 08 00 54 00 00 00 20 00 20 00' '5c 00 00 00 10 00 10 00 fc 00 00 00 31 82 8a e2' '06 01 b1 1d 00 00 00 0f 44 00 6f 00 6d 00 61 00' '69 00 6e 00 55 00 73 00 65 00 72 00 43 00 00 00' '4f 00 00 00 4d 00 00 00 50 00 00 00 55 00 00 00' '54 00 00 00 45 00 00 00 52 00 00 00 86 c3 50 97' 'ac 9c ec 10 25 54 76 4a 57 cc cc 19 aa aa aa aa' 'aa aa aa aa 04 10 c4 7a cf 19 97 89 de 7f 20 11' '95 7a ea 50 01 01 00 00 00 00 00 00 00 00 00 00' '00 00 00 00 aa aa aa aa aa aa aa aa 00 00 00 00' '02 00 0c 00 44 00 6f 00 6d 00 61 00 69 00 6e 00' '01 00 0c 00 53 00 65 00 72 00 76 00 65 00 72 00' '0a 00 10 00 6e a1 9d f0 66 da 46 22 05 1f 9c 4f' '92 c6 df 74 00 00 00 00 00 00 00 00 e5 69 95 1d' '15 d4 73 5f 49 e1 4c f9 a7 d3 e6 72') actual = AuthenticateMessage(user_name, password, domain_name, workstation_name, test_challenge_message, 3, test_server_cert_hash) actual.add_mic(None, test_challenge_message) actual = actual.get_data() assert actual == expected
def test_nt_v1_with_extended_security_response(self, monkeypatch): monkeypatch.setattr('os.urandom', lambda s: b"\xaa" * 8) test_challenge_message = ChallengeMessage( b"\x4e\x54\x4c\x4d\x53\x53\x50\x00" b"\x02\x00\x00\x00\x0c\x00\x0c\x00" b"\x38\x00\x00\x00\x33\x82\x0a\x82" b"\x01\x23\x45\x67\x89\xab\xcd\xef" b"\x00\x00\x00\x00\x00\x00\x00\x00" b"\x00\x00\x00\x00\x00\x00\x00\x00" b"\x06\x00\x70\x17\x00\x00\x00\x0f" b"\x53\x00\x65\x00\x72\x00\x76\x00" b"\x65\x00\x72\x00" ) test_lmv1_response = b"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" \ b"\x00\x00\x00\x00\x00\x00\x00\x00" \ b"\x00\x00\x00\x00\x00\x00\x00\x00" expected_response = b"\x75\x37\xf8\x03\xae\x36\x71\x28" \ b"\xca\x45\x82\x04\xbd\xe7\xca\xf8" \ b"\x1e\x97\xed\x26\x83\x26\x72\x32" expected_exchange_key = b"\xeb\x93\x42\x9a\x8b\xd9\x52\xf8" \ b"\xb8\x9c\x55\xb8\x7f\x47\x5e\xdc" expected_target_info = None comp_response = ComputeResponse("User", "Password", "Domain", test_challenge_message, 1) actual_response, actual_exchange_key, actual_target_info = \ comp_response.get_nt_challenge_response(test_lmv1_response, None) assert actual_response == expected_response assert actual_exchange_key == expected_exchange_key assert actual_target_info == expected_target_info
def test_nt_v1_response(self): test_challenge_message = ChallengeMessage( b"\x4e\x54\x4c\x4d\x53\x53\x50\x00" b"\x02\x00\x00\x00\x0c\x00\x0c\x00" b"\x38\x00\x00\x00\x33\x82\x02\xe2" b"\x01\x23\x45\x67\x89\xab\xcd\xef" b"\x06\x00\x70\x17\x00\x00\x00\x0f" b"\x53\x00\x65\x00\x72\x00\x76\x00" b"\x65\x00\x72\x00" ) test_lmv1_response = b"\x98\xde\xf7\xb8\x7f\x88\xaa\x5d" \ b"\xaf\xe2\xdf\x77\x96\x88\xa1\x72" \ b"\xde\xf1\x1c\x7d\x5c\xcd\xef\x13" expected_response = b"\x67\xc4\x30\x11\xf3\x02\x98\xa2" \ b"\xad\x35\xec\xe6\x4f\x16\x33\x1c" \ b"\x44\xbd\xbe\xd9\x27\x84\x1f\x94" expected_exchange_key = b"\xd8\x72\x62\xb0\xcd\xe4\xb1\xcb" \ b"\x74\x99\xbe\xcc\xcd\xf1\x07\x84" expected_target_info = None comp_response = ComputeResponse("User", "Password", "Domain", test_challenge_message, 1) actual_response, actual_exchange_key, actual_target_info = \ comp_response.get_nt_challenge_response(test_lmv1_response, None) assert actual_response == expected_response assert actual_exchange_key == expected_exchange_key assert actual_target_info == expected_target_info
def test_lm_v2_response(self, monkeypatch): monkeypatch.setattr('os.urandom', lambda s: b"\xaa" * 8) test_challenge_message = ChallengeMessage( b"\x4e\x54\x4c\x4d\x53\x53\x50\x00" b"\x02\x00\x00\x00\x03\x00\x0c\x00" b"\x38\x00\x00\x00\x33\x82\x8a\xe2" b"\x01\x23\x45\x67\x89\xab\xcd\xef" b"\x00\x00\x00\x00\x00\x00\x00\x00" b"\x24\x00\x24\x00\x44\x00\x00\x00" b"\x06\x00\x70\x17\x00\x00\x00\x0f" b"\x53\x00\x65\x00\x72\x00\x76\x00" b"\x65\x00\x72\x00\x02\x00\x0c\x00" b"\x44\x00\x6f\x00\x6d\x00\x61\x00" b"\x69\x00\x6e\x00\x01\x00\x0c\x00" b"\x53\x00\x65\x00\x72\x00\x76\x00" b"\x65\x00\x72\x00\x00\x00\x00\x00" ) expected = b"\x86\xc3\x50\x97\xac\x9c\xec\x10" \ b"\x25\x54\x76\x4a\x57\xcc\xcc\x19" \ b"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" actual = ComputeResponse("User", "Password", "Domain", test_challenge_message, 3).get_lm_challenge_response() assert actual == expected
def step(self, input_token=None): if self._negotiate_message is None: self._negotiate_message = NegotiateMessage(self.negotiate_flags, self.domain, self.workstation) return self._negotiate_message.get_data() else: self._challenge_message = ChallengeMessage(input_token) self._authenticate_message = AuthenticateMessage( self.username, self.password, self.domain, self.workstation, self._challenge_message, self.ntlm_compatibility, server_certificate_hash=self._server_certificate_hash, cbt_data=self.cbt_data ) self._authenticate_message.add_mic(self._negotiate_message, self._challenge_message) flag_bytes = self._authenticate_message.negotiate_flags flags = struct.unpack("<I", flag_bytes)[0] if flags & NegotiateFlags.NTLMSSP_NEGOTIATE_SEAL or \ flags & NegotiateFlags.NTLMSSP_NEGOTIATE_SIGN: self._session_security = SessionSecurity( flags, self.session_key ) self.complete = True return self._authenticate_message.get_data()
def test_challenge_no_version(self): expected_message_type = MessageTypes.NTLM_CHALLENGE expected_negotiate_flags = ntlmv1_negotiate_flags expected_server_challenge = server_challenge expected_signature = NTLM_SIGNATURE expected_target_info = None expected_target_name = None expected_version = None actual = ChallengeMessage(ntlmv1_challenge_message) actual_message_type = actual.message_type actual_negotiate_flags = actual.negotiate_flags actual_server_challenge = actual.server_challenge actual_signature = actual.signature actual_target_info = actual.target_info actual_target_name = actual.target_name actual_version = actual.version assert actual_message_type == expected_message_type assert actual_negotiate_flags == expected_negotiate_flags assert actual_server_challenge == expected_server_challenge assert actual_signature == expected_signature assert actual_target_info == expected_target_info assert actual_target_name == expected_target_name assert actual_version == expected_version
def test_challenge_with_target_info(self): test_target_info = TargetInfo() test_target_info[ TargetInfo.MSV_AV_NB_DOMAIN_NAME] = ntlmv2_netbios_domain_name test_target_info[ TargetInfo.MSV_AV_NB_COMPUTER_NAME] = ntlmv2_netbios_server_name expected_message_type = MessageTypes.NTLM_CHALLENGE expected_negotiate_flags = ntlmv2_negotiate_flags expected_server_challenge = server_challenge expected_signature = NTLM_SIGNATURE expected_target_info = test_target_info.get_data() expected_target_name = None expected_version = struct.unpack( "<q", HexToByte('06 00 70 17 00 00 00 0f'))[0] actual = ChallengeMessage(ntlmv2_challenge_message) actual_message_type = actual.message_type actual_negotiate_flags = actual.negotiate_flags actual_server_challenge = actual.server_challenge actual_signature = actual.signature actual_target_info = actual.target_info.get_data() actual_target_name = actual.target_name actual_version = actual.version assert actual_message_type == expected_message_type assert actual_negotiate_flags == expected_negotiate_flags assert actual_server_challenge == expected_server_challenge assert actual_signature == expected_signature assert actual_target_info == expected_target_info assert actual_target_name == expected_target_name assert actual_version == expected_version
def test_challenge(self): expected_message_type = MessageTypes.NTLM_CHALLENGE expected_negotiate_flags = ntlmv1_with_ess_negotiate_flags expected_server_challenge = server_challenge expected_signature = NTLM_SIGNATURE expected_target_info = None expected_target_name = None expected_version = struct.unpack( "<q", HexToByte('06 00 70 17 00 00 00 0f'))[0] actual = ChallengeMessage(ntlmv1_with_ess_challenge_message) actual_message_type = actual.message_type actual_negotiate_flags = actual.negotiate_flags actual_server_challenge = actual.server_challenge actual_signature = actual.signature actual_target_info = actual.target_info actual_target_name = actual.target_name actual_version = actual.version assert actual_message_type == expected_message_type assert actual_negotiate_flags == expected_negotiate_flags assert actual_server_challenge == expected_server_challenge assert actual_signature == expected_signature assert actual_target_info == expected_target_info assert actual_target_name == expected_target_name assert actual_version == expected_version
def parse_challenge_message(self, msg2): """ Parse the NTLM CHALLENGE_MESSAGE from the server and add it to the Ntlm context fields :param msg2: A base64 encoded string of the CHALLENGE_MESSAGE """ msg2 = base64.b64decode(msg2) self.challenge_message = ChallengeMessage(msg2)
def fingerprint(self, ip_addr, port=445): try: # connect and attempt authentication connection = Connection(uuid.uuid4(), ip_addr, port, require_signing=False) connection.connect(Dialects.SMB_2_0_2, timeout=TIMEOUT) try: session = Session( connection, "", "", require_encryption=False ) # dont require encryption or signing to support o2 HomeBox try: session.connect() except SMBAuthenticationError: # ignore authentication error # the result doesn't matter as long as there was an attempt pass for packet in session.preauth_integrity_hash_value: # find a STATUS_MORE_PROCESSING_REQUIRED response if not isinstance(packet, SMB2HeaderResponse) or not packet[ "status"].value == NtStatus.STATUS_MORE_PROCESSING_REQUIRED: continue sess_resp_bytes = packet["data"].value # parse session setup response sess_resp = SMB2SessionSetupResponse() sess_resp.unpack(sess_resp_bytes) chlg_mesg_bytes = sess_resp["buffer"].value # skip if this is not a NTLMSSP challenge # https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/801a4681-8809-4be9-ab0d-61dcfe762786 if not chlg_mesg_bytes.startswith(NTLMSSP_MAGIC_NUMBER): continue # parse NTLMSSP challenge # (labelled "security blob" in wireshark) chlg_mesg = ChallengeMessage(chlg_mesg_bytes) # parse the version field # https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/b1a6ceb2-f8ad-462b-b5af-f18527c48175 return struct.unpack( NTLM_VERSION_STRUCT, chlg_mesg.version.to_bytes(8, byteorder='little')) return (None, None, None, None) finally: connection.disconnect() except Exception as e: print("SMB connection failed") print(e) return (None, None, None, None)
def test_nt_v2_response_no_target_info(self, monkeypatch): monkeypatch.setattr('os.urandom', lambda s: b"\xaa" * 8) monkeypatch.setattr('ntlm_auth.compute_response.get_windows_timestamp', lambda: b"\x00" * 8) test_challenge_message = ChallengeMessage( b"\x4e\x54\x4c\x4d\x53\x53\x50\x00" b"\x02\x00\x00\x00\x03\x00\x0c\x00" b"\x38\x00\x00\x00\x33\x82\x8a\xe2" b"\x01\x23\x45\x67\x89\xab\xcd\xef" b"\x00\x00\x00\x00\x00\x00\x00\x00" b"\x24\x00\x24\x00\x44\x00\x00\x00" b"\x06\x00\x70\x17\x00\x00\x00\x0f" b"\x53\x00\x65\x00\x72\x00\x76\x00" b"\x65\x00\x72\x00\x02\x00\x0c\x00" b"\x44\x00\x6f\x00\x6d\x00\x61\x00" b"\x69\x00\x6e\x00\x01\x00\x0c\x00" b"\x53\x00\x65\x00\x72\x00\x76\x00" b"\x65\x00\x72\x00\x00\x00\x00\x00" ) test_challenge_message.target_info = None test_lmv2_response = b"\x86\xc3\x50\x97\xac\x9c\xec\x10" \ b"\x25\x54\x76\x4a\x57\xcc\xcc\x19" \ b"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" expected_response = b"\x39\x56\xf2\xe5\x69\xd9\xaf\xa3" \ b"\xac\x2d\x4f\x36\x7d\x38\xb9\xc5" \ b"\x01\x01\x00\x00\x00\x00\x00\x00" \ b"\x00\x00\x00\x00\x00\x00\x00\x00" \ b"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" \ b"\x00\x00\x00\x00\x00\x00\x00\x00" \ b"\x00\x00\x00\x00" expected_exchange_key = b"\xe3\x35\x1f\x5b\xe0\xa0\x2b\xc2" \ b"\xee\xb8\x76\x52\xf7\xe0\x77\x75" expected_target_info = TargetInfo() comp_response = ComputeResponse("User", "Password", "Domain", test_challenge_message, 3) actual_response, actual_exchange_key, actual_target_info = \ comp_response.get_nt_challenge_response(test_lmv2_response, None) assert actual_response == expected_response assert actual_exchange_key == expected_exchange_key assert actual_target_info.pack() == expected_target_info.pack()
def test_authenticate_message_ntlm_v1(self, monkeypatch): monkeypatch.setattr('ntlm_auth.messages.get_random_export_session_key', lambda: b"\x55" * 16) monkeypatch.setattr('ntlm_auth.messages.get_version', lambda s: b"\x05\x01\x28\x0A\x00\x00\x00\x0F") test_challenge_message = ChallengeMessage( b"\x4e\x54\x4c\x4d\x53\x53\x50\x00" b"\x02\x00\x00\x00\x0c\x00\x0c\x00" b"\x38\x00\x00\x00\x33\x82\x02\xe2" b"\x01\x23\x45\x67\x89\xab\xcd\xef" b"\x06\x00\x70\x17\x00\x00\x00\x0f" b"\x53\x00\x65\x00\x72\x00\x76\x00" b"\x65\x00\x72\x00") # Need to override the flags in the challenge message to match the # expectation, these flags are inconsequential and are done manualy for # sanity test_challenge_message.negotiate_flags -= \ NegotiateFlags.NTLMSSP_TARGET_TYPE_SERVER test_challenge_message.negotiate_flags |= \ NegotiateFlags.NTLMSSP_REQUEST_TARGET test_challenge_message.negotiate_flags |= \ NegotiateFlags.NTLMSSP_NEGOTIATE_TARGET_INFO expected = b"\x4e\x54\x4c\x4d\x53\x53\x50\x00" \ b"\x03\x00\x00\x00\x18\x00\x18\x00" \ b"\x6c\x00\x00\x00\x18\x00\x18\x00" \ b"\x84\x00\x00\x00\x0c\x00\x0c\x00" \ b"\x48\x00\x00\x00\x08\x00\x08\x00" \ b"\x54\x00\x00\x00\x10\x00\x10\x00" \ b"\x5c\x00\x00\x00\x10\x00\x10\x00" \ b"\x9c\x00\x00\x00\x35\x82\x80\xe2" \ b"\x05\x01\x28\x0a\x00\x00\x00\x0f" \ b"\x44\x00\x6f\x00\x6d\x00\x61\x00" \ b"\x69\x00\x6e\x00\x55\x00\x73\x00" \ b"\x65\x00\x72\x00\x43\x00\x4f\x00" \ b"\x4d\x00\x50\x00\x55\x00\x54\x00" \ b"\x45\x00\x52\x00\x98\xde\xf7\xb8" \ b"\x7f\x88\xaa\x5d\xaf\xe2\xdf\x77" \ b"\x96\x88\xa1\x72\xde\xf1\x1c\x7d" \ b"\x5c\xcd\xef\x13\x67\xc4\x30\x11" \ b"\xf3\x02\x98\xa2\xad\x35\xec\xe6" \ b"\x4f\x16\x33\x1c\x44\xbd\xbe\xd9" \ b"\x27\x84\x1f\x94\x51\x88\x22\xb1" \ b"\xb3\xf3\x50\xc8\x95\x86\x82\xec" \ b"\xbb\x3e\x3c\xb7" actual = AuthenticateMessage("User", "Password", "Domain", "COMPUTER", test_challenge_message, 1, None) actual.add_mic(None, test_challenge_message) actual = actual.get_data() assert actual == expected
def test_authenticate_message_ntlm_v1_with_ess(self, monkeypatch): monkeypatch.setattr('os.urandom', lambda s: b"\xaa" * 8) monkeypatch.setattr('ntlm_auth.messages.get_version', lambda s: b"\x05\x01\x28\x0A\x00\x00\x00\x0F") test_challenge_message = ChallengeMessage( b"\x4e\x54\x4c\x4d\x53\x53\x50\x00" b"\x02\x00\x00\x00\x0c\x00\x0c\x00" b"\x38\x00\x00\x00\x33\x82\x0a\x82" b"\x01\x23\x45\x67\x89\xab\xcd\xef" b"\x00\x00\x00\x00\x00\x00\x00\x00" b"\x00\x00\x00\x00\x00\x00\x00\x00" b"\x06\x00\x70\x17\x00\x00\x00\x0f" b"\x53\x00\x65\x00\x72\x00\x76\x00" b"\x65\x00\x72\x00") # Need to override the flags in the challenge message to match the # expectation, these flags are inconsequential and are done manualy # for sanity test_challenge_message.negotiate_flags -= \ NegotiateFlags.NTLMSSP_TARGET_TYPE_SERVER test_challenge_message.negotiate_flags |= \ NegotiateFlags.NTLMSSP_REQUEST_TARGET expected = b"\x4e\x54\x4c\x4d\x53\x53\x50\x00" \ b"\x03\x00\x00\x00\x18\x00\x18\x00" \ b"\x6c\x00\x00\x00\x18\x00\x18\x00" \ b"\x84\x00\x00\x00\x0c\x00\x0c\x00" \ b"\x48\x00\x00\x00\x08\x00\x08\x00" \ b"\x54\x00\x00\x00\x10\x00\x10\x00" \ b"\x5c\x00\x00\x00\x00\x00\x00\x00" \ b"\x9c\x00\x00\x00\x35\x82\x08\x82" \ b"\x05\x01\x28\x0a\x00\x00\x00\x0f" \ b"\x44\x00\x6f\x00\x6d\x00\x61\x00" \ b"\x69\x00\x6e\x00\x55\x00\x73\x00" \ b"\x65\x00\x72\x00\x43\x00\x4f\x00" \ b"\x4d\x00\x50\x00\x55\x00\x54\x00" \ b"\x45\x00\x52\x00\xaa\xaa\xaa\xaa" \ b"\xaa\xaa\xaa\xaa\x00\x00\x00\x00" \ b"\x00\x00\x00\x00\x00\x00\x00\x00" \ b"\x00\x00\x00\x00\x75\x37\xf8\x03" \ b"\xae\x36\x71\x28\xca\x45\x82\x04" \ b"\xbd\xe7\xca\xf8\x1e\x97\xed\x26" \ b"\x83\x26\x72\x32" actual = AuthenticateMessage("User", "Password", "Domain", "COMPUTER", test_challenge_message, 1, None) actual.add_mic(None, test_challenge_message) actual = actual.get_data() assert actual == expected
def test_authenticate_message_ntlm_v1(self, session_key, version_function): test_challenge_message = ChallengeMessage(ntlmv1_challenge_message) # Need to override the flags in the challenge message to match the expectation, these flags are inconsequential and are done manualy for sanity test_challenge_message.negotiate_flags -= NegotiateFlags.NTLMSSP_TARGET_TYPE_SERVER test_challenge_message.negotiate_flags |= NegotiateFlags.NTLMSSP_REQUEST_TARGET test_challenge_message.negotiate_flags |= NegotiateFlags.NTLMSSP_NEGOTIATE_TARGET_INFO expected = ntlmv1_authenticate_message actual = AuthenticateMessage(user_name, password, domain_name, "COMPUTER", test_challenge_message, 1, None) actual.add_mic(None, test_challenge_message) actual = actual.get_data() assert actual == expected
def test_challenge_message_with_target_name(self): # Same as the test above but with the flags modified to show it has the # target name for coverage test_target_info = TargetInfo() test_target_info[AvId.MSV_AV_NB_DOMAIN_NAME] = \ b"\x44\x00\x6f\x00\x6d\x00\x61\x00\x69\x00\x6e\x00" test_target_info[AvId.MSV_AV_NB_COMPUTER_NAME] = \ b"\x53\x00\x65\x00\x72\x00\x76\x00\x65\x00\x72\x00" expected_message_type = MessageTypes.NTLM_CHALLENGE expected_negotiate_flags = 3800728119 expected_server_challenge = b"\x01\x23\x45\x67\x89\xab\xcd\xef" expected_signature = NTLM_SIGNATURE expected_target_info = test_target_info.pack() expected_target_name = "Server".encode('utf-16-le') expected_version = 1080863910962135046 challenge_msg = b"\x4e\x54\x4c\x4d\x53\x53\x50\x00" \ b"\x02\x00\x00\x00\x0c\x00\x0c\x00" \ b"\x38\x00\x00\x00\x37\x82\x8a\xe2" \ b"\x01\x23\x45\x67\x89\xab\xcd\xef" \ b"\x00\x00\x00\x00\x00\x00\x00\x00" \ b"\x24\x00\x24\x00\x44\x00\x00\x00" \ b"\x06\x00\x70\x17\x00\x00\x00\x0f" \ b"\x53\x00\x65\x00\x72\x00\x76\x00" \ b"\x65\x00\x72\x00\x02\x00\x0c\x00" \ b"\x44\x00\x6f\x00\x6d\x00\x61\x00" \ b"\x69\x00\x6e\x00\x01\x00\x0c\x00" \ b"\x53\x00\x65\x00\x72\x00\x76\x00" \ b"\x65\x00\x72\x00\x00\x00\x00\x00" actual = ChallengeMessage(challenge_msg) actual_message_type = actual.message_type actual_negotiate_flags = actual.negotiate_flags actual_server_challenge = actual.server_challenge actual_signature = actual.signature actual_target_info = actual.target_info.pack() actual_target_name = actual.target_name actual_version = actual.version assert actual_message_type == expected_message_type assert actual_negotiate_flags == expected_negotiate_flags assert actual_server_challenge == expected_server_challenge assert actual_signature == expected_signature assert actual_target_info == expected_target_info assert actual_target_name == expected_target_name assert actual_version == expected_version
def test_lm_v1_response(self): test_challenge_message = ChallengeMessage( b"\x4e\x54\x4c\x4d\x53\x53\x50\x00" b"\x02\x00\x00\x00\x0c\x00\x0c\x00" b"\x38\x00\x00\x00\x33\x82\x02\xe2" b"\x01\x23\x45\x67\x89\xab\xcd\xef" b"\x06\x00\x70\x17\x00\x00\x00\x0f" b"\x53\x00\x65\x00\x72\x00\x76\x00" b"\x65\x00\x72\x00" ) expected = b"\x98\xde\xf7\xb8\x7f\x88\xaa\x5d" \ b"\xaf\xe2\xdf\x77\x96\x88\xa1\x72" \ b"\xde\xf1\x1c\x7d\x5c\xcd\xef\x13" actual = ComputeResponse("User", "Password", "Domain", test_challenge_message, 1).get_lm_challenge_response() assert actual == expected
def test_authenticate_message_ntlm_v1_non_unicode(self, monkeypatch): monkeypatch.setattr('ntlm_auth.messages.get_random_export_session_key', lambda: b"\x55" * 16) monkeypatch.setattr('ntlm_auth.messages.get_version', lambda s: b"\x05\x01\x28\x0A\x00\x00\x00\x0F") test_challenge_message = ChallengeMessage( b"\x4e\x54\x4c\x4d\x53\x53\x50\x00" b"\x02\x00\x00\x00\x0c\x00\x0c\x00" b"\x38\x00\x00\x00\x33\x82\x02\xe2" b"\x01\x23\x45\x67\x89\xab\xcd\xef" b"\x06\x00\x70\x17\x00\x00\x00\x0f" b"\x53\x00\x65\x00\x72\x00\x76\x00" b"\x65\x00\x72\x00") test_challenge_message.negotiate_flags -= \ NegotiateFlags.NTLMSSP_NEGOTIATE_UNICODE test_challenge_message.negotiate_flags |= \ NegotiateFlags.NTLMSSP_NEGOTIATE_OEM # Not a Microsoft example, using pre-computed value expected = b"\x4e\x54\x4c\x4d\x53\x53\x50\x00" \ b"\x03\x00\x00\x00\x18\x00\x18\x00" \ b"\x5a\x00\x00\x00\x18\x00\x18\x00" \ b"\x72\x00\x00\x00\x06\x00\x06\x00" \ b"\x48\x00\x00\x00\x04\x00\x04\x00" \ b"\x4e\x00\x00\x00\x08\x00\x08\x00" \ b"\x52\x00\x00\x00\x10\x00\x10\x00" \ b"\x8a\x00\x00\x00\x32\x82\x02\xe2" \ b"\x05\x01\x28\x0a\x00\x00\x00\x0f" \ b"\x44\x6f\x6d\x61\x69\x6e\x55\x73" \ b"\x65\x72\x43\x4f\x4d\x50\x55\x54" \ b"\x45\x52\x98\xde\xf7\xb8\x7f\x88" \ b"\xaa\x5d\xaf\xe2\xdf\x77\x96\x88" \ b"\xa1\x72\xde\xf1\x1c\x7d\x5c\xcd" \ b"\xef\x13\x67\xc4\x30\x11\xf3\x02" \ b"\x98\xa2\xad\x35\xec\xe6\x4f\x16" \ b"\x33\x1c\x44\xbd\xbe\xd9\x27\x84" \ b"\x1f\x94\x51\x88\x22\xb1\xb3\xf3" \ b"\x50\xc8\x95\x86\x82\xec\xbb\x3e" \ b"\x3c\xb7" actual = AuthenticateMessage("User", "Password", "Domain", "COMPUTER", test_challenge_message, 1, None) actual.add_mic(None, test_challenge_message) actual = actual.get_data() assert actual == expected
def test_challenge_message_with_target_name(self): # Same as the test above but with the flags modified to show it has the target name for coverage test_target_info = TargetInfo() test_target_info[ TargetInfo.MSV_AV_NB_DOMAIN_NAME] = ntlmv2_netbios_domain_name test_target_info[ TargetInfo.MSV_AV_NB_COMPUTER_NAME] = ntlmv2_netbios_server_name test_challenge_message = HexToByte( '4e 54 4c 4d 53 53 50 00 02 00 00 00 0c 00 0c 00' '38 00 00 00 37 82 8a e2 01 23 45 67 89 ab cd ef' '00 00 00 00 00 00 00 00 24 00 24 00 44 00 00 00' '06 00 70 17 00 00 00 0f 53 00 65 00 72 00 76 00' '65 00 72 00 02 00 0c 00 44 00 6f 00 6d 00 61 00' '69 00 6e 00 01 00 0c 00 53 00 65 00 72 00 76 00' '65 00 72 00 00 00 00 00') expected_message_type = MessageTypes.NTLM_CHALLENGE expected_negotiate_flags = 3800728119 expected_server_challenge = server_challenge expected_signature = NTLM_SIGNATURE expected_target_info = test_target_info.get_data() expected_target_name = ntlmv2_netbios_server_name expected_version = struct.unpack( "<q", HexToByte('06 00 70 17 00 00 00 0f'))[0] actual = ChallengeMessage(test_challenge_message) actual_message_type = actual.message_type actual_negotiate_flags = actual.negotiate_flags actual_server_challenge = actual.server_challenge actual_signature = actual.signature actual_target_info = actual.target_info.get_data() actual_target_name = actual.target_name actual_version = actual.version assert actual_message_type == expected_message_type assert actual_negotiate_flags == expected_negotiate_flags assert actual_server_challenge == expected_server_challenge assert actual_signature == expected_signature assert actual_target_info == expected_target_info assert actual_target_name == expected_target_name assert actual_version == expected_version
def test_lm_v1_with_ntlm_2_response(self): test_challenge_message = ChallengeMessage( b"\x4e\x54\x4c\x4d\x53\x53\x50\x00" b"\x02\x00\x00\x00\x0c\x00\x0c\x00" b"\x38\x00\x00\x00\x33\x82\x02\xe2" b"\x01\x23\x45\x67\x89\xab\xcd\xef" b"\x06\x00\x70\x17\x00\x00\x00\x0f" b"\x53\x00\x65\x00\x72\x00\x76\x00" b"\x65\x00\x72\x00" ) # Not explicitly in the example shown but it does expect the same # response that we already have set expected = b"\x67\xc4\x30\x11\xf3\x02\x98\xa2" \ b"\xad\x35\xec\xe6\x4f\x16\x33\x1c" \ b"\x44\xbd\xbe\xd9\x27\x84\x1f\x94" actual = ComputeResponse("User", "Password", "Domain", test_challenge_message, 2).get_lm_challenge_response() assert actual == expected
def test_lm_v1_with_extended_security_response(self, monkeypatch): monkeypatch.setattr('os.urandom', lambda s: b"\xaa" * 8) test_challenge_message = ChallengeMessage( b"\x4e\x54\x4c\x4d\x53\x53\x50\x00" b"\x02\x00\x00\x00\x0c\x00\x0c\x00" b"\x38\x00\x00\x00\x33\x82\x0a\x82" b"\x01\x23\x45\x67\x89\xab\xcd\xef" b"\x00\x00\x00\x00\x00\x00\x00\x00" b"\x00\x00\x00\x00\x00\x00\x00\x00" b"\x06\x00\x70\x17\x00\x00\x00\x0f" b"\x53\x00\x65\x00\x72\x00\x76\x00" b"\x65\x00\x72\x00" ) expected = b"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" \ b"\x00\x00\x00\x00\x00\x00\x00\x00" \ b"\x00\x00\x00\x00\x00\x00\x00\x00" actual = ComputeResponse("User", "Password", "Domain", test_challenge_message, 1).get_lm_challenge_response() assert actual == expected
def test_authenticate_without_domain_workstation(self, session_key, version_function): test_challenge_message = ChallengeMessage(ntlmv1_challenge_message) # Not a Microsoft example, using pre-computed value expected = HexToByte('4e 54 4c 4d 53 53 50 00 03 00 00 00 18 00 18 00' '50 00 00 00 18 00 18 00 68 00 00 00 00 00 00 00' '48 00 00 00 08 00 08 00 48 00 00 00 00 00 00 00' '50 00 00 00 10 00 10 00 80 00 00 00 31 82 02 e2' '05 01 28 0a 00 00 00 0f 55 00 73 00 65 00 72 00' '98 de f7 b8 7f 88 aa 5d af e2 df 77 96 88 a1 72' 'de f1 1c 7d 5c cd ef 13 67 c4 30 11 f3 02 98 a2' 'ad 35 ec e6 4f 16 33 1c 44 bd be d9 27 84 1f 94' '51 88 22 b1 b3 f3 50 c8 95 86 82 ec bb 3e 3c b7') actual = AuthenticateMessage(user_name, password, None, None, test_challenge_message, 1, None) actual.add_mic(None, test_challenge_message) actual = actual.get_data() assert actual == expected
def test_authenticate_without_domain_workstation(self, monkeypatch): monkeypatch.setattr('ntlm_auth.messages.get_random_export_session_key', lambda: b"\x55" * 16) monkeypatch.setattr('ntlm_auth.messages.get_version', lambda s: b"\x05\x01\x28\x0A\x00\x00\x00\x0F") test_challenge_message = ChallengeMessage( b"\x4e\x54\x4c\x4d\x53\x53\x50\x00" b"\x02\x00\x00\x00\x0c\x00\x0c\x00" b"\x38\x00\x00\x00\x33\x82\x02\xe2" b"\x01\x23\x45\x67\x89\xab\xcd\xef" b"\x06\x00\x70\x17\x00\x00\x00\x0f" b"\x53\x00\x65\x00\x72\x00\x76\x00" b"\x65\x00\x72\x00") # Not a Microsoft example, using pre-computed value expected = b"\x4e\x54\x4c\x4d\x53\x53\x50\x00" \ b"\x03\x00\x00\x00\x18\x00\x18\x00" \ b"\x50\x00\x00\x00\x18\x00\x18\x00" \ b"\x68\x00\x00\x00\x00\x00\x00\x00" \ b"\x48\x00\x00\x00\x08\x00\x08\x00" \ b"\x48\x00\x00\x00\x00\x00\x00\x00" \ b"\x50\x00\x00\x00\x10\x00\x10\x00" \ b"\x80\x00\x00\x00\x31\x82\x02\xe2" \ b"\x05\x01\x28\x0a\x00\x00\x00\x0f" \ b"\x55\x00\x73\x00\x65\x00\x72\x00" \ b"\x98\xde\xf7\xb8\x7f\x88\xaa\x5d" \ b"\xaf\xe2\xdf\x77\x96\x88\xa1\x72" \ b"\xde\xf1\x1c\x7d\x5c\xcd\xef\x13" \ b"\x67\xc4\x30\x11\xf3\x02\x98\xa2" \ b"\xad\x35\xec\xe6\x4f\x16\x33\x1c" \ b"\x44\xbd\xbe\xd9\x27\x84\x1f\x94" \ b"\x51\x88\x22\xb1\xb3\xf3\x50\xc8" \ b"\x95\x86\x82\xec\xbb\x3e\x3c\xb7" actual = AuthenticateMessage("User", "Password", None, None, test_challenge_message, 1, None) actual.add_mic(None, test_challenge_message) actual = actual.get_data() assert actual == expected
def test_authenticate_message_with_mic(self, random_function, session_key_function): test_challenge_message = ChallengeMessage(ntlmv2_challenge_message) test_challenge_message.target_info[ TargetInfo.MSV_AV_TIMESTAMP] = mock_timestamp() test_server_cert_hash = 'E3CA49271E5089CC48CE82109F1324F41DBEDDC29A777410C738F7868C4FF405' test_negotiate_message = NegotiateMessage(ntlmv2_negotiate_flags, domain_name, workstation_name) # Not a Microsoft example, using pre-computed value expected = HexToByte('4e 54 4c 4d 53 53 50 00 03 00 00 00 18 00 18 00' '8c 00 00 00 7c 00 7c 00 a4 00 00 00 0c 00 0c 00' '58 00 00 00 08 00 08 00 64 00 00 00 20 00 20 00' '6c 00 00 00 10 00 10 00 20 01 00 00 31 82 8a e2' '06 01 b1 1d 00 00 00 0f 77 ff c5 e6 db 55 87 0e' '65 8d 7c ff 33 cd 90 2e 44 00 6f 00 6d 00 61 00' '69 00 6e 00 55 00 73 00 65 00 72 00 43 00 00 00' '4f 00 00 00 4d 00 00 00 50 00 00 00 55 00 00 00' '54 00 00 00 45 00 00 00 52 00 00 00 00 00 00 00' '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00' '00 00 00 00 a1 3d 03 8a d0 ca 02 64 33 89 7c 33' '5e 0f 56 df 01 01 00 00 00 00 00 00 00 00 00 00' '00 00 00 00 aa aa aa aa aa aa aa aa 00 00 00 00' '02 00 0c 00 44 00 6f 00 6d 00 61 00 69 00 6e 00' '01 00 0c 00 53 00 65 00 72 00 76 00 65 00 72 00' '07 00 08 00 00 00 00 00 00 00 00 00 06 00 04 00' '02 00 00 00 0a 00 10 00 6e a1 9d f0 66 da 46 22' '05 1f 9c 4f 92 c6 df 74 00 00 00 00 00 00 00 00' '1d 08 89 d1 a5 ee ed 21 91 9e 1a b8 27 c3 0b 17') actual = AuthenticateMessage(user_name, password, domain_name, workstation_name, test_challenge_message, 3, test_server_cert_hash) actual.add_mic(test_negotiate_message, test_challenge_message) actual = actual.get_data() assert actual == expected
import time from ntlm_auth.messages import ChallengeMessage from ntlm_auth.target_info import TargetInfo from ntlm_auth.compute_response import ComputeResponse, get_windows_timestamp from ntlm_auth.constants import AvFlags from ..expected_values import * from ..mock_functions import mock_random, mock_timestamp from ..utils import HexToByte # Test AV_PAIR structure used for NTLMv2 Calculations target_info = TargetInfo() target_info[TargetInfo.MSV_AV_NB_DOMAIN_NAME] = ntlmv2_netbios_domain_name target_info[TargetInfo.MSV_AV_NB_COMPUTER_NAME] = ntlmv2_netbios_server_name ntlmv1_challenge_message = ChallengeMessage(ntlmv1_challenge_message) ntlmv1_with_ess_challenge_message = ChallengeMessage(ntlmv1_with_ess_challenge_message) ntlmv2_challenge_message = ChallengeMessage(ntlmv2_challenge_message) """ [MS-NLMP] v28.0 2016-07-14 4.2 Cryptographic Values for Validation The following tests use known inputs in the documentation and tests the outputs for various compute functions set out by Microsoft. Please do not modify the expected results unless it is otherwise specified as they will validate the functions work correctly. For tests that follow Microsoft examples, the examples are stored in expected_values.py """ class Test_Generic(unittest.TestCase):