def test_check_error_code_version_3_none(self):
        test_data = utils.hex_to_byte('30 09 A0 03 02 01 03')

        test_ts_request = TSRequest()
        test_ts_request.parse_data(test_data)
        test_ts_request.check_error_code()

        assert test_ts_request['error_code'].value == None
    def test_check_error_code_undefinied(self):
        expected_byte = b'c000006e'
        test_data = hex_to_byte('30 13 A0 03 02 01 03 A4 06 02 04 C0 00 00 6E')

        with self.assertRaises(NTStatusException) as context:
            test_ts_request = TSRequest()
            test_ts_request.parse_data(test_data)
            test_ts_request.check_error_code()

        assert context.exception.args[
            0] == 'NTSTATUS error: Not Defined %s' % expected_byte
    def test_check_error_code_logon_failure(self):
        expected_byte = b'c000006d'
        test_data = hex_to_byte('30 13 A0 03 02 01 03 A4 06 02 04 C0 00 00 6D')

        with self.assertRaises(NTStatusException) as context:
            test_ts_request = TSRequest()
            test_ts_request.parse_data(test_data)
            test_ts_request.check_error_code()

        assert context.exception.args[
            0] == 'STATUS_LOGON_FAILURE - %s' % expected_byte
    def test_check_error_code_version_2_none(self):
        test_ts_request = TSRequest()
        test_ts_request.parse_data(challenge_ts_request)
        test_ts_request.check_error_code()

        assert test_ts_request['error_code'].value == None
Beispiel #5
0
    def credssp_generator(self):
        """
        [MS-CSSP] 3.1.5 Processing Events and Sequencing Rules
        https://msdn.microsoft.com/en-us/library/cc226791.aspx

        Generator function that yields each CredSSP token to sent to the
        server. CredSSP has multiple steps that must be run for the client to
        successfully authenticate with the server and delegate the credentials.
        """
        log.debug("Starting TLS handshake process")
        self.tls_connection = SSL.Connection(self.tls_context)
        self.tls_connection.set_connect_state()

        while True:
            try:
                self.tls_connection.do_handshake()
            except SSL.WantReadError:
                out_token = self.tls_connection.bio_read(self.BIO_BUFFER_SIZE)

                log.debug("Step 1. TLS Handshake, returning token: %s" % binascii.hexlify(out_token))
                in_token = yield out_token, "Step 1. TLS Handshake"
                log.debug("Step 1. TLS Handshake, received token: %s" % binascii.hexlify(in_token))

                self.tls_connection.bio_write(in_token)
            else:
                break
        log.debug("TLS Handshake complete. Protocol: %s, Cipher: %s"
                  % (self.tls_connection.get_protocol_version_name(), self.tls_connection.get_cipher_name()))

        server_certificate = self.tls_connection.get_peer_certificate()
        server_public_key = self._get_subject_public_key(server_certificate)

        log.debug("Starting Authentication process")
        context = spnego.client(self.username, self.password, hostname=self.hostname, service='HTTP',
                                protocol=self.auth_mechanism)

        out_token = context.step()
        while True:
            nego_token = NegoToken()
            nego_token['negoToken'] = out_token

            ts_request = TSRequest()
            ts_request['negoTokens'].append(nego_token)
            ts_request_token = encoder.encode(ts_request)

            log.debug("Step 2. Authenticate, returning token: %s" % binascii.hexlify(ts_request_token))
            in_token = yield self.wrap(ts_request_token), "Step 2. Authenticate"
            in_token = self.unwrap(in_token)
            log.debug("Step 3. Authenticate, received token: %s" % binascii.hexlify(in_token))

            ts_request = decoder.decode(in_token, asn1Spec=TSRequest())[0]
            ts_request.check_error_code()
            version = int(ts_request['version'])
            out_token = context.step(bytes(ts_request['negoTokens'][0]['negoToken']))

            # Special edge case, we need to include the final NTLM token in the pubKeyAuth step but the context won't
            # be seen as complete at that stage so check if the known header is present.
            if context.complete or b"NTLMSSP\x00\x03\x00\x00\x00" in out_token:
                break

        version = min(version, TSRequest.CLIENT_VERSION)
        log.debug("Starting public key verification process at version %d" % version)
        if version < self.minimum_version:
            raise AuthenticationException("The reported server version was %d and did not meet the minimum "
                                          "requirements of %d" % (version, self.minimum_version))
        if version > 4:
            nonce = os.urandom(32)
        else:
            log.warning("Reported server version was %d, susceptible to MitM attacks and should be patched - "
                        "CVE 2018-0886" % version)
            nonce = None

        pub_key_auth = self._build_pub_key_auth(context, nonce, out_token, server_public_key)
        log.debug("Step 3. Server Authentication, returning token: %s" % binascii.hexlify(pub_key_auth))
        in_token = yield self.wrap(pub_key_auth), "Step 3. Server Authentication"
        in_token = self.unwrap(in_token)
        log.debug("Step 3. Server Authentication, received token: %s" % binascii.hexlify(in_token))

        log.debug("Starting server public key response verification")
        ts_request = decoder.decode(in_token, asn1Spec=TSRequest())[0]
        ts_request.check_error_code()
        if not ts_request['pubKeyAuth'].isValue:
            raise AuthenticationException("The server did not response with pubKeyAuth info, authentication was "
                                          "rejected")
        if len(ts_request['negoTokens']) > 0:
            # SPNEGO auth returned the mechListMIC for us to verify
            context.step(bytes(ts_request['negoTokens'][0]['negoToken']))

        response_key = context.unwrap(bytes(ts_request['pubKeyAuth'])).data
        self._verify_public_keys(nonce, response_key, server_public_key)

        log.debug("Sending encrypted credentials")
        enc_credentials = self._get_encrypted_credentials(context)

        yield self.wrap(enc_credentials), "Step 5. Delegate Credentials"