示例#1
0
    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
示例#2
0
    def test_nt_v2_temp_response(self):
        test_target_info = TargetInfo(target_info.get_data())

        expected = ntlmv2_temp

        actual = ComputeResponse._get_NTLMv2_temp(timestamp, client_challenge, test_target_info)
        assert actual == expected
示例#3
0
def get_test_target_info():
    target_info = TargetInfo()
    target_info[TargetInfo.MSV_AV_NB_DOMAIN_NAME] = HexToByte(
        '44 00 6f 00 6d 00 61 00 69 00 6e 00')
    target_info[TargetInfo.MSV_AV_NB_COMPUTER_NAME] = HexToByte(
        '53 00 65 00 72 00 76 00 65 00 72 00')

    return target_info
示例#4
0
    def test_nt_v2_response_no_target_info(self, random_function, timestamp_function):
        test_challenge_message = ntlmv2_challenge_message
        test_challenge_message.target_info = None

        expected_response = HexToByte('39 56 f2 e5 69 d9 af a3 ac 2d 4f 36 7d 38 b9 c5'
                                      '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 00 00 00 00'
                                      '00 00 00 00')
        expected_exchange_key = HexToByte('e3 35 1f 5b e0 a0 2b c2 ee b8 76 52 f7 e0 77 75')
        expected_target_info = TargetInfo()

        actual_response, actual_exchange_key, actual_target_info = ComputeResponse(user_name, password, domain_name,
                                                                                   test_challenge_message,
                                                                                   3).get_nt_challenge_response(ntlmv2_lmv2_response, None)

        assert actual_response == expected_response
        assert actual_exchange_key == expected_exchange_key
        assert actual_target_info.get_data() == expected_target_info.get_data()
示例#5
0
    def test_lm_v2_response_with_no_server_target_info_timestamp(self, random_function):
        test_target_info = TargetInfo(target_info.get_data())
        test_challenge_message = ntlmv2_challenge_message
        test_challenge_message.target_info = test_target_info

        expected = ntlmv2_lmv2_response

        actual = ComputeResponse(user_name, password, domain_name, test_challenge_message, 3).get_lm_challenge_response()

        assert actual == expected
示例#6
0
    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
示例#7
0
    def test_lm_v2_response_with_server_target_info_timestamp(self):
        test_target_info = TargetInfo(target_info.get_data())
        test_target_info[TargetInfo.MSV_AV_TIMESTAMP] = timestamp
        test_challenge_message = ntlmv2_challenge_message
        test_challenge_message.target_info = test_target_info

        # Not in MS-NLMP, using expected value
        expected = HexToByte('00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
                             '00 00 00 00 00 00 00 00')

        actual = ComputeResponse(user_name, password, domain_name, test_challenge_message,
                                 3).get_lm_challenge_response()

        assert actual == expected
示例#8
0
    def test_nt_v2_response(self, random_function, timestamp_function):
        test_target_info = TargetInfo(target_info.get_data())
        test_challenge_message = ntlmv2_challenge_message
        test_challenge_message.target_info = test_target_info

        expected_response = ntlmv2_ntlmv2_response
        expected_exchange_key = ntlmv2_session_base_key #in ntlmv2 session_base key is the same as exchange_key
        expected_target_info = test_target_info

        actual_response, actual_exchange_key, actual_target_info = ComputeResponse(user_name, password, domain_name,
                                                                                   test_challenge_message,
                                                                                   3).get_nt_challenge_response(ntlmv2_lmv2_response, None)

        assert actual_response == expected_response
        assert actual_exchange_key == expected_exchange_key
        assert actual_target_info == expected_target_info
示例#9
0
    def __init__(self, msg2):
        self.data = msg2
        # Setting the object values from the raw_challenge_message
        self.signature = msg2[0:8]
        self.message_type = struct.unpack("<I", msg2[8:12])[0]
        self.negotiate_flags = struct.unpack("<I", msg2[20:24])[0]
        self.server_challenge = msg2[24:32]
        self.reserved = msg2[32:40]

        if self.negotiate_flags & NegotiateFlags.NTLMSSP_NEGOTIATE_VERSION and self.negotiate_flags & NegotiateFlags.NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY:
            size = len(msg2)
            self.version = struct.unpack("<q", msg2[48:56])[0]
        else:
            self.version = None

        if self.negotiate_flags & NegotiateFlags.NTLMSSP_REQUEST_TARGET:
            target_name_len = struct.unpack("<H", msg2[12:14])[0]
            target_name_max_len = struct.unpack("<H", msg2[14:16])[0]
            target_name_buffer_offset = struct.unpack("<I", msg2[16:20])[0]
            self.target_name = msg2[
                target_name_buffer_offset:target_name_buffer_offset +
                target_name_len]
        else:
            self.target_name = None

        if self.negotiate_flags & NegotiateFlags.NTLMSSP_NEGOTIATE_TARGET_INFO:
            target_info_len = struct.unpack("<H", msg2[40:42])[0]
            target_info_max_len = struct.unpack("<H", msg2[42:44])[0]
            target_info_buffer_offset = struct.unpack("<I", msg2[44:48])[0]

            target_info_raw = msg2[
                target_info_buffer_offset:target_info_buffer_offset +
                target_info_len]
            self.target_info = TargetInfo(target_info_raw)
        else:
            self.target_info = None

        # Verify initial integrity of the message, it matches what should be there
        assert self.signature == NTLM_SIGNATURE
        assert self.message_type == MessageTypes.NTLM_CHALLENGE
示例#10
0
    def test_nt_v2_response_with_timestamp_av_pair(self, random_function):
        test_target_info = TargetInfo(target_info.get_data())
        test_target_info[TargetInfo.MSV_AV_TIMESTAMP] = timestamp
        test_challenge_message = ntlmv2_challenge_message
        test_challenge_message.target_info = test_target_info

        expected_response = HexToByte('5d eb f3 87 1c 28 94 b8 1f 16 42 81 ed bf 0b ff'
                                      '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'
                                      '00 00 00 00 00 00 00 00')
        expected_exchange_key = HexToByte('9b 37 06 8f 99 7a 06 5f e9 c7 20 63 32 88 d4 8f')
        expected_target_info = test_target_info
        expected_target_info[TargetInfo.MSV_AV_FLAGS] = struct.pack("<L", AvFlags.MIC_PROVIDED)

        actual_response, actual_exchange_key, actual_target_info = ComputeResponse(user_name, password, domain_name,
                                                                                   test_challenge_message,
                                                                                   3).get_nt_challenge_response(ntlmv2_lmv2_response, None)

        assert actual_response == expected_response
        assert actual_exchange_key == expected_exchange_key
        assert actual_target_info == expected_target_info
示例#11
0
import unittest2 as unittest # for compatiblity with older version of python
import mock
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
示例#12
0
    def get_nt_challenge_response(self, lm_challenge_response,
                                  server_certificate_hash):
        """
        [MS-NLMP] v28.0 2016-07-14

        3.3.1 - NTLM v1 Authentication
        3.3.2 - NTLM v2 Authentication

        This method returns the NtChallengeResponse key based on the ntlm_compatibility chosen
        and the target_info supplied by the CHALLENGE_MESSAGE. It is quite different from what
        is set in the document as it combines the NTLMv1, NTLM2 and NTLMv2 methods into one
        and calls separate methods based on the ntlm_compatibility value chosen.

        :param lm_challenge_response: The LmChallengeResponse calculated beforeand, used to get the key_exchange_key value
        :param server_certificate_hash: The SHA256 hash of the server certificate (DER encoded) NTLM is authenticated to.
                                        Used in Channel Binding Tokens if present, default value is None. See
                                        AuthenticateMessage in messages.py for more details
        :return response: (NtChallengeResponse) - The NT response to the server challenge. Computed by the client
        :return session_base_key: (SessionBaseKey) - A session key calculated from the user password challenge
        :return target_info: (AV_PAIR) - The AV_PAIR structure used in the nt_challenge calculations
        """
        if self._negotiate_flags & NegotiateFlags.NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY and self._ntlm_compatibility < 3:
            # The compatibility level is less than 3 which means it doesn't support NTLMv2 but we want extended security so use NTLM2 which is different from NTLMv2
            # [MS-NLMP] - 3.3.1 NTLMv1 Authentication
            response, session_base_key = ComputeResponse._get_NTLM2_response(
                self._password, self._server_challenge, self._client_challenge)
            key_exchange_key = compkeys._get_exchange_key_ntlm_v1(
                self._negotiate_flags, session_base_key,
                self._server_challenge, lm_challenge_response,
                comphash._lmowfv1(self._password))
            target_info = None

        elif 0 <= self._ntlm_compatibility < 3:
            response, session_base_key = ComputeResponse._get_NTLMv1_response(
                self._password, self._server_challenge)
            key_exchange_key = compkeys._get_exchange_key_ntlm_v1(
                self._negotiate_flags, session_base_key,
                self._server_challenge, lm_challenge_response,
                comphash._lmowfv1(self._password))
            target_info = None
        else:
            if self._server_target_info is None:
                target_info = TargetInfo()
            else:
                target_info = self._server_target_info

            if target_info[TargetInfo.MSV_AV_TIMESTAMP] is None:
                timestamp = get_windows_timestamp()
            else:
                timestamp = target_info[TargetInfo.MSV_AV_TIMESTAMP][1]

                # [MS-NLMP] If the CHALLENGE_MESSAGE TargetInfo field has an MsvAvTimestamp present, the client SHOULD provide a MIC
                target_info[TargetInfo.MSV_AV_FLAGS] = struct.pack(
                    "<L", AvFlags.MIC_PROVIDED)

            if server_certificate_hash != None:
                channel_bindings_hash = ComputeResponse._get_channel_bindings_value(
                    server_certificate_hash)
                target_info[
                    TargetInfo.MSV_AV_CHANNEL_BINDINGS] = channel_bindings_hash

            response, session_base_key = ComputeResponse._get_NTLMv2_response(
                self._user_name, self._password, self._domain_name,
                self._server_challenge, self._client_challenge, timestamp,
                target_info)

            key_exchange_key = compkeys._get_exchange_key_ntlm_v2(
                session_base_key)

        return response, key_exchange_key, target_info