Example #1
0
    def test_unseal_message_ntlm2_key_exchange(self):
        test_flags = ntlmv2_negotiate_flags
        test_session_security = SessionSecurity(test_flags, session_base_key)
        test_server_session_security = SessionSecurity(test_flags, session_base_key, source="server")
        test_message, test_signature = test_server_session_security.wrap(plaintext_data)

        expected_data = plaintext_data

        actual_data = test_session_security.unwrap(test_message, test_signature)

        assert actual_data == expected_data
Example #2
0
    def test_unseal_message_incorrect_checksum(self):
        test_flags = ntlmv2_negotiate_flags
        test_session_security = SessionSecurity(test_flags, session_base_key)
        test_server_session_security = SessionSecurity(test_flags, session_base_key, source="server")
        test_message, test_signature = test_server_session_security.wrap(plaintext_data)
        # Overwrite signature to produce a bad checksum
        test_signature = HexToByte('01 00 00 00 b1 98 b8 47 ce 7c 58 07 00 00 00 00')

        with self.assertRaises(Exception) as context:
            test_session_security.unwrap(test_message, test_signature)

        self.assertTrue('The signature checksum does not match, message has been altered' in context.exception.args)
Example #3
0
    def test_verify_sign_no_unseal_message(self):
        test_flags = ntlmv2_negotiate_flags - NegotiateFlags.NTLMSSP_NEGOTIATE_SEAL
        test_session_security = SessionSecurity(test_flags, session_base_key)
        test_server_session_security = SessionSecurity(test_flags, session_base_key, source="server")
        test_message, test_signature = test_server_session_security.wrap(plaintext_data)

        expected_data = plaintext_data

        actual_data = test_session_security.unwrap(test_message, test_signature)

        assert test_message == expected_data
        assert actual_data == expected_data
Example #4
0
    def test_unseal_message_incorrect_seq_num(self):
        test_flags = ntlmv2_negotiate_flags
        test_session_security = SessionSecurity(test_flags, session_base_key)
        test_server_session_security = SessionSecurity(test_flags, session_base_key, source="server")
        test_message, test_signature = test_server_session_security.wrap(plaintext_data)
        # Overwrite signature to produce a bad checksum
        test_signature = HexToByte('01 00 00 00 b2 98 b8 47 ce 7c 58 07 00 00 00 01')

        with self.assertRaises(Exception) as context:
            test_session_security.unwrap(test_message, test_signature)

        self.assertTrue('The signature sequence number does not match up, message not received in the correct sequence' in context.exception.args)
Example #5
0
    def create_authenticate_message(self,
                                    user_name,
                                    password=None,
                                    nthash=None,
                                    lmhash=None,
                                    domain_name=None,
                                    workstation=None,
                                    server_certificate_hash=None):
        """
        Create an NTLM AUTHENTICATE_MESSAGE based on the Ntlm context and the previous messages sent and received

        :param user_name: The user name of the user we are trying to authenticate with
        :param password: The password of the user we are trying to authenticate with
        :param domain_name: The domain name of the user account we are authenticated with, default is None
        :param workstation: The workstation we are using to authenticate with, default is None
        :param server_certificate_hash: The SHA256 hash string of the server certificate (DER encoded) NTLM is authenticating to. Used for Channel
                                        Binding Tokens. If nothing is supplied then the CBT hash will not be sent. See messages.py AuthenticateMessage
                                        for more details
        :return: A base64 encoded string of the AUTHENTICATE_MESSAGE
        """
        self.authenticate_message = AuthenticateMessage(
            user_name, password, nthash, lmhash, domain_name, workstation,
            self.challenge_message, self.ntlm_compatibility,
            server_certificate_hash)
        self.authenticate_message.add_mic(self.negotiate_message,
                                          self.challenge_message)

        # Setups up the session_security context used to sign and seal messages if wanted
        if self.negotiate_flags & NegotiateFlags.NTLMSSP_NEGOTIATE_SEAL or self.negotiate_flags & NegotiateFlags.NTLMSSP_NEGOTIATE_SIGN:
            self.session_security = SessionSecurity(
                struct.unpack("<I",
                              self.authenticate_message.negotiate_flags)[0],
                self.authenticate_message.exported_session_key)

        return base64.b64encode(self.authenticate_message.get_data())
Example #6
0
    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_unseal_message_ntlm2_key_exchange(self):
        negotiate_flags = 3800728116
        session_key = b"\xff" * 16
        test_session_security = SessionSecurity(negotiate_flags, session_key)
        test_server_session_security = SessionSecurity(negotiate_flags,
                                                       session_key,
                                                       source="server")

        plaintext_data = b"\x50\x00\x6c\x00\x61\x00\x69\x00" \
                         b"\x6e\x00\x74\x00\x65\x00\x78\x00" \
                         b"\x74\x00"
        test_message, test_signature = \
            test_server_session_security.wrap(plaintext_data)

        expected_data = plaintext_data
        actual_data = test_session_security.unwrap(test_message,
                                                   test_signature)
        assert actual_data == expected_data
    def test_unseal_message_ntlm2_no_key_exchange(self):
        negotiate_flags = 2181726771
        session_key = b"\xeb\x93\x42\x9a\x8b\xd9\x52\xf8" \
                      b"\xb8\x9c\x55\xb8\x7f\x47\x5e\xdc"
        test_session_security = SessionSecurity(negotiate_flags, session_key)
        test_server_session_security = SessionSecurity(negotiate_flags,
                                                       session_key,
                                                       source="server")

        plaintext_data = b"\x50\x00\x6c\x00\x61\x00\x69\x00" \
                         b"\x6e\x00\x74\x00\x65\x00\x78\x00" \
                         b"\x74\x00"
        test_message, test_signature = \
            test_server_session_security.wrap(plaintext_data)

        expected_data = plaintext_data
        actual_data = test_session_security.unwrap(test_message,
                                                   test_signature)
        assert actual_data == expected_data
    def test_verify_sign_no_unseal_message(self):
        negotiate_flags = 3800728116 - NegotiateFlags.NTLMSSP_NEGOTIATE_SEAL
        session_key = b"\x55" * 16
        test_session_security = SessionSecurity(negotiate_flags, session_key)
        test_server_session_security = SessionSecurity(negotiate_flags,
                                                       session_key,
                                                       source="server")

        plaintext_data = b"\x50\x00\x6c\x00\x61\x00\x69\x00" \
                         b"\x6e\x00\x74\x00\x65\x00\x78\x00" \
                         b"\x74\x00"
        test_message, test_signature = \
            test_server_session_security.wrap(plaintext_data)

        expected_data = plaintext_data
        actual_data = test_session_security.unwrap(test_message,
                                                   test_signature)
        assert test_message == expected_data
        assert actual_data == expected_data
Example #10
0
    def test_nosign_or_seal_message(self):
        test_flags = ntlmv2_negotiate_flags - NegotiateFlags.NTLMSSP_NEGOTIATE_SEAL - NegotiateFlags.NTLMSSP_NEGOTIATE_SIGN
        test_session_security = SessionSecurity(test_flags, session_base_key)

        expected_seal = plaintext_data
        expected_sign = None

        actual_seal, actual_sign = test_session_security.wrap(plaintext_data)

        assert actual_seal == expected_seal
        assert actual_sign == expected_sign
    def test_unseal_message_ntlm1(self):
        negotiate_flags = 3791815219
        session_key = b"\xd8\x72\x62\xb0\xcd\xe4\xb1" \
                      b"\xcb\x74\x99\xbe\xcc\xcd\xf1" \
                      b"\x07\x84"
        test_session_security = SessionSecurity(negotiate_flags, session_key)
        test_server_session_security = SessionSecurity(negotiate_flags,
                                                       session_key,
                                                       source="server")

        plaintext_data = b"\x50\x00\x6c\x00\x61\x00\x69\x00" \
                         b"\x6e\x00\x74\x00\x65\x00\x78\x00" \
                         b"\x74\x00"
        test_message, test_signature = \
            test_server_session_security.wrap(plaintext_data)

        expected_data = plaintext_data
        actual_data = test_session_security.unwrap(test_message,
                                                   test_signature)
        assert actual_data == expected_data
Example #12
0
    def test_sign_and_seal_message_ntlm2_key_exchange(self):
        test_flags = ntlmv2_negotiate_flags
        test_session_security = SessionSecurity(test_flags, session_base_key)

        expected_seal = ntlmv2_output_message
        expected_sign = ntlmv2_signature

        actual_seal, actual_sign = test_session_security.wrap(plaintext_data)

        assert actual_seal == expected_seal
        assert actual_sign == expected_sign
    def test_unseal_message_incorrect_checksum(self):
        negotiate_flags = 3800728116
        session_key = b"\xff" * 16
        test_session_security = SessionSecurity(negotiate_flags, session_key)
        test_server_session_security = SessionSecurity(negotiate_flags,
                                                       session_key,
                                                       source="server")

        plaintext_data = b"\x50\x00\x6c\x00\x61\x00\x69\x00" \
                         b"\x6e\x00\x74\x00\x65\x00\x78\x00" \
                         b"\x74\x00"
        test_message, test_signature = \
            test_server_session_security.wrap(plaintext_data)
        # Overwrite signature to produce a bad checksum
        test_signature = b"\x01\x00\x00\x00\xb1\x98\xb8\x47" \
                         b"\xce\x7c\x58\x07\x00\x00\x00\x00"

        with pytest.raises(Exception) as exc:
            test_session_security.unwrap(test_message, test_signature)
        assert str(exc.value) == "The signature checksum does not match, " \
                                 "message has been altered"
Example #14
0
    def test_sign_no_seal_message(self):
        test_flags = ntlmv2_negotiate_flags - NegotiateFlags.NTLMSSP_NEGOTIATE_SEAL
        test_session_security = SessionSecurity(test_flags, session_base_key)

        expected_seal = plaintext_data
        # Because we aren't sealing beforehand the signature will be different from the example
        expected_sign = HexToByte('01 00 00 00 74 d0 45 34 2c 4f 1c d5 00 00 00 00')

        actual_seal, actual_sign = test_session_security.wrap(plaintext_data)

        assert actual_seal == expected_seal
        assert actual_sign == expected_sign
    def test_unseal_message_incorrect_seq_num(self):
        negotiate_flags = 3800728116
        session_key = b"\xff" * 16
        test_session_security = SessionSecurity(negotiate_flags, session_key)
        test_server_session_security = SessionSecurity(negotiate_flags,
                                                       session_key,
                                                       source="server")

        plaintext_data = b"\x50\x00\x6c\x00\x61\x00\x69\x00" \
                         b"\x6e\x00\x74\x00\x65\x00\x78\x00" \
                         b"\x74\x00"
        test_message, test_signature = \
            test_server_session_security.wrap(plaintext_data)
        # Overwrite signature to produce a bad checksum
        test_signature = test_signature[:-4] + b"\x01\x00\x00\x00"

        with pytest.raises(Exception) as exc:
            test_session_security.unwrap(test_message, test_signature)

        assert str(exc.value) == "The signature sequence number does not " \
                                 "match up, message not received in the " \
                                 "correct sequence"
    def test_sign_and_seal_message_ntlmv1(self):
        test_session_security = SessionSecurity(3791815219, b"\x55" * 16)

        expected_seal = b"\x56\xfe\x04\xd8\x61\xf9\x31\x9a" \
                        b"\xf0\xd7\x23\x8a\x2e\x3b\x4d\x45" \
                        b"\x7f\xb8"
        expected_sign = b"\x01\x00\x00\x00\x00\x00\x00\x00" \
                        b"\x09\xdc\xd1\xdf\x2e\x45\x9d\x36"

        plaintext_data = b"\x50\x00\x6c\x00\x61\x00\x69\x00" \
                         b"\x6e\x00\x74\x00\x65\x00\x78\x00" \
                         b"\x74\x00"
        actual_seal, actual_sign = test_session_security.wrap(plaintext_data)
        assert actual_seal == expected_seal
        assert actual_sign == expected_sign
    def test_sign_no_seal_message(self):
        negotiate_flags = 3800728116 - NegotiateFlags.NTLMSSP_NEGOTIATE_SEAL
        test_session_security = SessionSecurity(negotiate_flags, b"\x55" * 16)

        expected_seal = b"\x50\x00\x6c\x00\x61\x00\x69\x00" \
                        b"\x6e\x00\x74\x00\x65\x00\x78\x00" \
                        b"\x74\x00"
        # Because we aren't sealing beforehand the signature will be different
        # from the example
        expected_sign = b"\x01\x00\x00\x00\x74\xd0\x45\x34" \
                        b"\x2c\x4f\x1c\xd5\x00\x00\x00\x00"

        actual_seal, actual_sign = test_session_security.wrap(expected_seal)
        assert actual_seal == expected_seal
        assert actual_sign == expected_sign
    def test_sign_and_seal_message_ntlm2_key_exchange(self):
        test_session_security = SessionSecurity(3800728116, b"\x55" * 16)

        expected_seal = b"\x54\xe5\x01\x65\xbf\x19\x36\xdc" \
                        b"\x99\x60\x20\xc1\x81\x1b\x0f\x06" \
                        b"\xfb\x5f"
        expected_sign = b"\x01\x00\x00\x00\x7f\xb3\x8e\xc5" \
                        b"\xc5\x5d\x49\x76\x00\x00\x00\x00"

        plaintext_data = b"\x50\x00\x6c\x00\x61\x00\x69\x00" \
                         b"\x6e\x00\x74\x00\x65\x00\x78\x00" \
                         b"\x74\x00"
        actual_seal, actual_sign = test_session_security.wrap(plaintext_data)
        assert actual_seal == expected_seal
        assert actual_sign == expected_sign
    def test_nosign_or_seal_message(self):
        negotiate_flags = 3800728116 - \
                          NegotiateFlags.NTLMSSP_NEGOTIATE_SEAL - \
                          NegotiateFlags.NTLMSSP_NEGOTIATE_SIGN
        test_session_security = SessionSecurity(negotiate_flags, b"\x55" * 16)

        plaintext_data = b"\x50\x00\x6c\x00\x61\x00\x69\x00" \
                         b"\x6e\x00\x74\x00\x65\x00\x78\x00" \
                         b"\x74\x00"
        expected_seal = plaintext_data
        expected_sign = None

        actual_seal, actual_sign = test_session_security.wrap(plaintext_data)
        assert actual_seal == expected_seal
        assert actual_sign == expected_sign
    def test_sign_and_seal_message_ntlm2_no_key_exchange(self):
        session_key = b"\xeb\x93\x42\x9a\x8b\xd9\x52\xf8" \
                      b"\xb8\x9c\x55\xb8\x7f\x47\x5e\xdc"
        test_session_security = SessionSecurity(2181726771, session_key)

        expected_seal = b"\xa0\x23\x72\xf6\x53\x02\x73\xf3" \
                        b"\xaa\x1e\xb9\x01\x90\xce\x52\x00" \
                        b"\xc9\x9d"
        expected_sign = b"\x01\x00\x00\x00\xff\x2a\xeb\x52" \
                        b"\xf6\x81\x79\x3a\x00\x00\x00\x00"

        plaintext_data = b"\x50\x00\x6c\x00\x61\x00\x69\x00" \
                         b"\x6e\x00\x74\x00\x65\x00\x78\x00" \
                         b"\x74\x00"
        actual_seal, actual_sign = test_session_security.wrap(plaintext_data)
        assert actual_seal == expected_seal
        assert actual_sign == expected_sign
Example #21
0
    def test_wrap_unwrap(self):
        context = NTLMContext("username", "password", None)
        context.init_context()

        gen = context.step()
        next(gen)
        msg2 = b"\x4e\x54\x4c\x4d\x53\x53\x50\x00" \
               b"\x02\x00\x00\x00\x2f\x82\x88\xe2" \
               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"
        gen.send(msg2)

        plaintext_client = b"client"
        plaintext_server = b"server"
        server_sec = SessionSecurity(
            context._context._session_security.negotiate_flags,
            context._context._session_security.exported_session_key, "server"
        )

        client_header, client_wrap = context.wrap(plaintext_client)
        assert client_header.startswith(b"\x01\x00\x00\x00")
        assert len(client_header) == 16
        assert client_wrap != plaintext_client

        client_plaintext = server_sec.unwrap(client_wrap, client_header)
        assert client_plaintext == plaintext_client

        server_wrap, server_header = server_sec.wrap(plaintext_server)
        assert server_header.startswith(b"\x01\x00\x00\x00")
        assert len(server_header) == 16
        assert server_wrap != plaintext_server

        server_plaintext = context.unwrap(server_header, server_wrap)
        assert server_plaintext == plaintext_server
Example #22
0
    def test_ntlm_context(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")
        monkeypatch.setattr('ntlm_auth.messages.get_random_export_session_key',
                            lambda: b"\x55" * 16)
        monkeypatch.setattr('ntlm_auth.compute_response.get_windows_timestamp',
                            lambda: b"\x00" * 8)

        ch = 'E3CA49271E5089CC48CE82109F1324F41DBEDDC29A777410C738F7868C4FF405'
        cbt_data = GssChannelBindingsStruct()
        cbt_data[cbt_data.APPLICATION_DATA] = b"tls-server-end-point:" + \
                                              base64.b16decode(ch)
        ntlm_context = NtlmContext("User",
                                   "Password",
                                   "Domain",
                                   "COMPUTER",
                                   cbt_data=cbt_data)
        actual_nego = ntlm_context.step()
        expected_nego = b"\x4e\x54\x4c\x4d\x53\x53\x50\x00" \
                        b"\x01\x00\x00\x00\x31\xb0\x88\xe2" \
                        b"\x06\x00\x06\x00\x28\x00\x00\x00" \
                        b"\x08\x00\x08\x00\x2e\x00\x00\x00" \
                        b"\x05\x01\x28\x0a\x00\x00\x00\x0f" \
                        b"\x44\x6f\x6d\x61\x69\x6e\x43\x4f" \
                        b"\x4d\x50\x55\x54\x45\x52"
        assert actual_nego == expected_nego
        assert not ntlm_context.mic_present
        assert not ntlm_context.complete

        challenge_msg = b"\x4e\x54\x4c\x4d\x53\x53\x50\x00" \
                        b"\x02\x00\x00\x00\x2f\x82\x88\xe2" \
                        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"
        actual_auth = ntlm_context.step(challenge_msg)
        expected_auth = b'\x4e\x54\x4c\x4d\x53\x53\x50\x00' \
                        b'\x03\x00\x00\x00\x18\x00\x18\x00' \
                        b'\x6c\x00\x00\x00\x68\x00\x68\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'\xec\x00\x00\x00\x31\x82\x8a\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\x86\xc3\x50\x97' \
                        b'\xac\x9c\xec\x10\x25\x54\x76\x4a' \
                        b'\x57\xcc\xcc\x19\xaa\xaa\xaa\xaa' \
                        b'\xaa\xaa\xaa\xaa\x04\x10\xc4\x7a' \
                        b'\xcf\x19\x97\x89\xde\x7f\x20\x11' \
                        b'\x95\x7a\xea\x50\x01\x01\x00\x00' \
                        b'\x00\x00\x00\x00\x00\x00\x00\x00' \
                        b'\x00\x00\x00\x00\xaa\xaa\xaa\xaa' \
                        b'\xaa\xaa\xaa\xaa\x00\x00\x00\x00' \
                        b'\x02\x00\x0c\x00\x44\x00\x6f\x00' \
                        b'\x6d\x00\x61\x00\x69\x00\x6e\x00' \
                        b'\x01\x00\x0c\x00\x53\x00\x65\x00' \
                        b'\x72\x00\x76\x00\x65\x00\x72\x00' \
                        b'\x0a\x00\x10\x00\x6e\xa1\x9d\xf0' \
                        b'\x66\xda\x46\x22\x05\x1f\x9c\x4f' \
                        b'\x92\xc6\xdf\x74\x00\x00\x00\x00' \
                        b'\x00\x00\x00\x00\xe5\x69\x95\x1d' \
                        b'\x15\xd4\x73\x5f\x49\xe1\x4c\xf9' \
                        b'\xa7\xd3\xe6\x72'

        assert actual_auth == expected_auth
        assert ntlm_context.complete
        assert not ntlm_context.mic_present

        request_msg = b"test req"
        response_msg = b"test res"
        actual_wrapped = ntlm_context.wrap(request_msg)
        expected_wrapped = b"\x01\x00\x00\x00\xbc\xe3\x23\xa1" \
                           b"\x72\x06\x23\x78\x00\x00\x00\x00" \
                           b"\x70\x80\x1e\x11\xfe\x6b\x3a\xad"
        assert actual_wrapped == expected_wrapped

        server_sec = SessionSecurity(
            ntlm_context._session_security.negotiate_flags,
            ntlm_context._session_security.exported_session_key, "server")
        server_unwrap = server_sec.unwrap(actual_wrapped[16:],
                                          actual_wrapped[0:16])
        assert server_unwrap == request_msg

        response_wrapped = server_sec.wrap(response_msg)

        actual_unwrap = ntlm_context.unwrap(response_wrapped[1] +
                                            response_wrapped[0])
        assert actual_unwrap == response_msg
 def test_invalid_source_param(self):
     with pytest.raises(ValueError) as exc:
         SessionSecurity(3791815219, b"\x55" * 16, source="unknown")
     assert str(exc.value) == "Invalid source parameter unknown, must be " \
                              "client or server"
Example #24
0
    def test_ntlm_context_with_mic(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")
        monkeypatch.setattr('ntlm_auth.messages.get_random_export_session_key',
                            lambda: b"\x55" * 16)
        monkeypatch.setattr('ntlm_auth.compute_response.get_windows_timestamp',
                            lambda: b"\x00" * 8)

        ch = 'E3CA49271E5089CC48CE82109F1324F41DBEDDC29A777410C738F7868C4FF405'
        cbt_data = GssChannelBindingsStruct()
        cbt_data[cbt_data.APPLICATION_DATA] = b"tls-server-end-point:" + \
                                              base64.b16decode(ch)
        ntlm_context = NtlmContext("User",
                                   "Password",
                                   "Domain",
                                   "COMPUTER",
                                   cbt_data=cbt_data)
        ntlm_context.reset_rc4_state(
        )  # Verifies it won't fail when the session security isn't set up.

        actual_nego = ntlm_context.step()
        expected_nego = b"\x4e\x54\x4c\x4d\x53\x53\x50\x00" \
                        b"\x01\x00\x00\x00\x31\xb0\x88\xe2" \
                        b"\x06\x00\x06\x00\x28\x00\x00\x00" \
                        b"\x08\x00\x08\x00\x2e\x00\x00\x00" \
                        b"\x05\x01\x28\x0a\x00\x00\x00\x0f" \
                        b"\x44\x6f\x6d\x61\x69\x6e\x43\x4f" \
                        b"\x4d\x50\x55\x54\x45\x52"
        assert actual_nego == expected_nego
        assert not ntlm_context.mic_present
        assert not ntlm_context.complete

        challenge_msg = b"\x4E\x54\x4C\x4D\x53\x53\x50\x00" \
                        b"\x02\x00\x00\x00\x00\x00\x00\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"\x30\x00\x30\x00\x38\x00\x00\x00" \
                        b"\x06\x01\xB1\x1D\x00\x00\x00\x0F" \
                        b"\x02\x00\x0C\x00\x44\x00\x6F\x00" \
                        b"\x6D\x00\x61\x00\x69\x00\x6E\x00" \
                        b"\x01\x00\x0C\x00\x53\x00\x65\x00" \
                        b"\x72\x00\x76\x00\x65\x00\x72\x00" \
                        b"\x07\x00\x08\x00\x00\x00\x00\x00" \
                        b"\x00\x00\x00\x00\x00\x00\x00\x00"
        actual_auth = ntlm_context.step(challenge_msg)
        expected_auth = b'\x4E\x54\x4C\x4D\x53\x53\x50\x00' \
                        b'\x03\x00\x00\x00\x18\x00\x18\x00' \
                        b'\x7C\x00\x00\x00\x7C\x00\x7C\x00' \
                        b'\x94\x00\x00\x00\x0C\x00\x0C\x00' \
                        b'\x58\x00\x00\x00\x08\x00\x08\x00' \
                        b'\x64\x00\x00\x00\x10\x00\x10\x00' \
                        b'\x6C\x00\x00\x00\x10\x00\x10\x00' \
                        b'\x10\x01\x00\x00\x31\x82\x8A\xE2' \
                        b'\x05\x01\x28\x0A\x00\x00\x00\x0F' \
                        b'\xC4\x45\x2C\xF7\xA8\x1E\x4D\x11' \
                        b'\xD0\x78\x18\x94\x09\x57\x5D\x9E' \
                        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\x00\x00\x00\x00' \
                        b'\x00\x00\x00\x00\x00\x00\x00\x00' \
                        b'\x00\x00\x00\x00\x00\x00\x00\x00' \
                        b'\x00\x00\x00\x00\xA1\x3D\x03\x8A' \
                        b'\xD0\xCA\x02\x64\x33\x89\x7C\x33' \
                        b'\x5E\x0F\x56\xDF\x01\x01\x00\x00' \
                        b'\x00\x00\x00\x00\x00\x00\x00\x00' \
                        b'\x00\x00\x00\x00\xAA\xAA\xAA\xAA' \
                        b'\xAA\xAA\xAA\xAA\x00\x00\x00\x00' \
                        b'\x02\x00\x0C\x00\x44\x00\x6F\x00' \
                        b'\x6D\x00\x61\x00\x69\x00\x6E\x00' \
                        b'\x01\x00\x0C\x00\x53\x00\x65\x00' \
                        b'\x72\x00\x76\x00\x65\x00\x72\x00' \
                        b'\x07\x00\x08\x00\x00\x00\x00\x00' \
                        b'\x00\x00\x00\x00\x06\x00\x04\x00' \
                        b'\x02\x00\x00\x00\x0A\x00\x10\x00' \
                        b'\x6E\xA1\x9D\xF0\x66\xDA\x46\x22' \
                        b'\x05\x1F\x9C\x4F\x92\xC6\xDF\x74' \
                        b'\x00\x00\x00\x00\x00\x00\x00\x00' \
                        b'\x1D\x08\x89\xD1\xA5\xEE\xED\x21' \
                        b'\x91\x9E\x1A\xB8\x27\xC3\x0B\x17'

        assert actual_auth == expected_auth
        assert ntlm_context.complete
        assert ntlm_context.mic_present

        request_msg = b"test req"
        response_msg = b"test res"
        actual_wrapped = ntlm_context.wrap(request_msg)
        expected_wrapped = b"\x01\x00\x00\x00\xbc\xe3\x23\xa1" \
                           b"\x72\x06\x23\x78\x00\x00\x00\x00" \
                           b"\x70\x80\x1e\x11\xfe\x6b\x3a\xad"
        assert actual_wrapped == expected_wrapped

        server_sec = SessionSecurity(
            ntlm_context._session_security.negotiate_flags,
            ntlm_context._session_security.exported_session_key, "server")
        server_unwrap = server_sec.unwrap(actual_wrapped[16:],
                                          actual_wrapped[0:16])
        assert server_unwrap == request_msg

        response_wrapped = server_sec.wrap(response_msg)

        actual_unwrap = ntlm_context.unwrap(response_wrapped[1] +
                                            response_wrapped[0])
        assert actual_unwrap == response_msg

        msg = b"Hello"
        actual_sig1 = ntlm_context.sign(msg)
        expected_sig1 = b"\x01\x00\x00\x00\x08\xF0\x0D\x86\x34\x05\x1A\x1D\x01\x00\x00\x00"
        assert actual_sig1 == expected_sig1
        server_sec.verify_signature(msg, actual_sig1)

        actual_sig2 = ntlm_context.sign(msg)
        expected_sig2 = b"\x01\x00\x00\x00\x07\x64\x0C\x30\x1C\xD7\x76\xF0\x02\x00\x00\x00"
        assert actual_sig2 == expected_sig2
        server_sec.verify_signature(msg, actual_sig2)

        ntlm_context.reset_rc4_state()
        actual_sig3 = ntlm_context.sign(msg)
        expected_sig3 = b"\x01\x00\x00\x00\x1E\xD4\xA3\xE5\xE8\x05\x74\x01\x03\x00\x00\x00"
        assert actual_sig3 == expected_sig3

        server_sec.reset_rc4_state(outgoing=False)
        server_sec.verify_signature(msg, actual_sig3)

        server_sig = server_sec.get_signature(msg)
        ntlm_context.verify(msg, server_sig)
Example #25
0
    def test_invalid_source_param(self):
        test_flags = ntlmv1_negotiate_flags
        with self.assertRaises(Exception) as context:
            SessionSecurity(test_flags, session_base_key, source="unknown")

        self.assertTrue('Invalid source parameter unknown, must be client or server' in context.exception.args)