Ejemplo n.º 1
0
    def step(self, in_token=None):
        if not self._is_wrapped:
            log.debug("NTLM step input: %s",
                      to_text(base64.b64encode(in_token or b"")))

        out_token = getattr(self, '_step_%s' % self.usage)(in_token=in_token)

        if not self._is_wrapped:
            log.debug("NTLM step output: %s",
                      to_text(base64.b64encode(out_token or b"")))

        if self._complete:
            self._temp_msg = None  # Clear out any temp data we still have stored.

            in_usage = 'accept' if self.usage == 'initiate' else 'initiate'
            self._sign_key_out = signkey(self._context_attr, self._session_key,
                                         self.usage)
            self._sign_key_in = signkey(self._context_attr, self._session_key,
                                        in_usage)

            # Found a vague reference in MS-NLMP that states if NTLMv2 authentication was not used then only 1 key is
            # used for sealing. This seems to reference when NTLMSSP_NEGOTIATE_EXTENDED_SESSION_SECURITY is not set and
            # not NTLMv2 messages itself.
            # https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/d1c86e81-eb66-47fd-8a6f-970050121347
            if self._context_attr & NegotiateFlags.extended_session_security:
                self._handle_out = rc4init(
                    sealkey(self._context_attr, self._session_key, self.usage))
                self._handle_in = rc4init(
                    sealkey(self._context_attr, self._session_key, in_usage))
            else:
                self._handle_out = self._handle_in = rc4init(
                    sealkey(self._context_attr, self._session_key, self.usage))

        return out_token
Ejemplo n.º 2
0
def test_seal_ntlmv2_no_key_exch():
    flags = NegotiateFlags.seal | NegotiateFlags.sign | NegotiateFlags.extended_session_security | \
        NegotiateFlags.key_128

    seal_key = sealkey(flags, TEST_RANDOM_SESSION_KEY, usage='initiate')
    seal_handle = rc4init(seal_key)
    sign_key = signkey(flags, TEST_RANDOM_SESSION_KEY, usage='initiate')

    b_data = to_bytes(u"Plaintext", encoding='utf-16-le')
    actual_msg, actual_signature = seal(flags, seal_handle, sign_key, 0,
                                        b_data)

    assert actual_msg == b"\x54\xE5\x01\x65\xBF\x19\x36\xDC\x99\x60\x20\xC1\x81\x1B\x0F\x06" \
                         b"\xFB\x5F"
    assert actual_signature == b"\x01\x00\x00\x00\x70\x35\x28\x51\xF2\x56\x43\x09\x00\x00\x00\x00"
Ejemplo n.º 3
0
def test_seal_ntlmv2():
    # https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/54973495-20d2-49e8-9925-c399a403ed4a
    flags = NegotiateFlags.seal | NegotiateFlags.sign | NegotiateFlags.extended_session_security | \
        NegotiateFlags.key_exch | NegotiateFlags.key_128

    seal_key = sealkey(flags, TEST_RANDOM_SESSION_KEY, usage='initiate')
    seal_handle = rc4init(seal_key)
    sign_key = signkey(flags, TEST_RANDOM_SESSION_KEY, usage='initiate')

    b_data = to_bytes(u"Plaintext", encoding='utf-16-le')
    actual_msg, actual_signature = seal(flags, seal_handle, sign_key, 0,
                                        b_data)

    assert actual_msg == b"\x54\xE5\x01\x65\xBF\x19\x36\xDC\x99\x60\x20\xC1\x81\x1B\x0F\x06" \
                         b"\xFB\x5F"
    assert actual_signature == b"\x01\x00\x00\x00\x7F\xB3\x8E\xC5\xC5\x5D\x49\x76\x00\x00\x00\x00"
Ejemplo n.º 4
0
def test_seal_ntlmv1():
    # https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/9e2b483e-d185-4feb-aa4f-db6e2c0c49d9
    seal_key = sealkey(TEST_NTLMV1_FLAGS,
                       TEST_RANDOM_SESSION_KEY,
                       usage='initiate')
    seal_handle = rc4init(seal_key)
    sign_key = signkey(TEST_NTLMV1_FLAGS,
                       TEST_RANDOM_SESSION_KEY,
                       usage='initiate')

    b_data = to_bytes(u"Plaintext", encoding='utf-16-le')
    actual_msg, actual_signature = seal(TEST_NTLMV1_FLAGS, seal_handle,
                                        sign_key, 0, b_data)

    assert actual_msg == b"\x56\xFE\x04\xD8\x61\xF9\x31\x9A\xF0\xD7\x23\x8A\x2E\x3B\x4D\x45" \
                         b"\x7F\xB8"

    # The docs example seems to keep the random pad in the signature even though the actual function definition sets
    # that to 0x00000000. Assert the actual working implementation that has been tested against MS servers.
    assert actual_signature == b"\x01\x00\x00\x00\x00\x00\x00\x00\x09\xDC\xD1\xDF\x2E\x45\x9D\x36"
Ejemplo n.º 5
0
def test_seal_ntlmv1_with_ess():
    # https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/052aef59-b55b-4800-b4a8-e93eca1600d6
    key_exchange_key = compute_response_v1(TEST_NTLMV1_CLIENT_CHALLENGE_FLAGS,
                                           ntowfv1(TEST_PASSWD),
                                           lmowfv1(TEST_PASSWD),
                                           TEST_SERVER_CHALLENGE,
                                           TEST_CLIENT_CHALLENGE)[2]
    seal_key = sealkey(TEST_NTLMV1_CLIENT_CHALLENGE_FLAGS,
                       key_exchange_key,
                       usage='initiate')
    seal_handle = rc4init(seal_key)
    sign_key = signkey(TEST_NTLMV1_CLIENT_CHALLENGE_FLAGS,
                       key_exchange_key,
                       usage='initiate')

    b_data = to_bytes(u"Plaintext", encoding='utf-16-le')
    actual_msg, actual_signature = seal(TEST_NTLMV1_CLIENT_CHALLENGE_FLAGS,
                                        seal_handle, sign_key, 0, b_data)

    assert actual_msg == b"\xA0\x23\x72\xF6\x53\x02\x73\xF3\xAA\x1E\xB9\x01\x90\xCE\x52\x00" \
                         b"\xC9\x9D"
    assert actual_signature == b"\x01\x00\x00\x00\xFF\x2A\xEB\x52\xF6\x81\x79\x3A\x00\x00\x00\x00"
Ejemplo n.º 6
0
def test_seal_key_no_flags():
    actual = crypto.sealkey(0, TEST_RANDOM_SESSION_KEY, 'initiate')

    assert actual == TEST_RANDOM_SESSION_KEY
Ejemplo n.º 7
0
def test_seal_key_lm_key_or_datagram(flags, expected):
    actual = crypto.sealkey(flags, TEST_RANDOM_SESSION_KEY, 'initiate')

    print(base64.b16encode(actual).decode('ascii'))

    assert actual == expected
Ejemplo n.º 8
0
def test_seal_key_ess(flags, usage, expected):
    actual = crypto.sealkey(NegotiateFlags.extended_session_security | flags,
                            TEST_RANDOM_SESSION_KEY, usage)

    assert actual == expected