Exemplo n.º 1
0
 def test_that_initialize_security_context_generates_negotiate_sign_token(
         self):
     ntlm_context = NtlmContext(self.auth,
                                hostname='thor',
                                session_security='sign')
     context = ntlm_context.initialize_security_context()
     token = context.send(None)
     self.assertEqual(self.tokens.negotiate_sign, token)
Exemplo n.º 2
0
 def test_that_initialize_security_context_generates_negotiate_seal_token(
         self):
     ntlm_context = NtlmContext(self.auth,
                                hostname='DEVMAC',
                                session_security='encrypt')
     context = ntlm_context.initialize_security_context()
     token = context.send(None)
     self.assertEqual(token, self.tokens.negotiate_seal)
Exemplo n.º 3
0
 def __init__(self, pkg_name):
     self.pkg_info = win32security.QuerySecurityPackageInfo(pkg_name)
     auth = PasswordAuthentication('workgroup',
                                   'developer',
                                   'password',
                                   compatibility=4)
     ntlm_context = NtlmContext(auth, session_security='none')
     self.context = ntlm_context.initialize_security_context()
     _BaseAuth.__init__(self)
Exemplo n.º 4
0
    def _credssp_processor(self):
        """
        Implements a state machine
        :return:
        """
        response = (yield)
        context = self._get_credssp_header(response)

        if context is None:
            raise Exception('The remote host did not respond with a \'www-authenticate\' header containing '
                            '\'CredSSP\' as an available authentication mechanism')

        # 1. First, secure the channel with a RC4-SHA TLS Handshake
        if not context:
            tls_credssp = SSL.Connection(self.tls_credssp_context)
            tls_credssp.set_connect_state()
            while True:
                try:
                    tls_credssp.do_handshake()
                except SSL.WantReadError:
                    response = yield self._set_credssp_header(response.request, tls_credssp.bio_read(4096))
                    context = self._get_credssp_header(response)
                    if context is None or not context:
                        raise Exception('The remote host rejected the CredSSP TLS handshake')
                    tls_credssp.bio_write(context)
                else:
                    break

        # add logging to display the negotiated cipher (move to a function)
        openssl_lib = _util.binding.lib
        ffi = _util.binding.ffi
        cipher = openssl_lib.SSL_get_current_cipher(tls_credssp._ssl)
        cipher_name = ffi.string( openssl_lib.SSL_CIPHER_get_name(cipher))
        # print cipher_name

        # 2. Send an TSRequest containing an NTLM Negotiate Request
        context = NtlmContext(PasswordAuthentication(self.domain, self.username, self.password), session_security='encrypt')
        context_generator = context.initialize_security_context()
        negotiate_token = context_generator.send(None)

        ts_request = TSRequest()
        ts_request['negoTokens'] = negotiate_token
        tls_credssp.send(ts_request.getData())

        http_challenge_response = yield self._set_credssp_header(response.request, tls_credssp.bio_read(4096))

        # Extract and decrypt the encoded TSRequest response struct from the Negotiate header
        authenticate_header = self._get_credssp_header(http_challenge_response)
        if not authenticate_header or authenticate_header is None:
            raise Exception("The remote host rejected the CredSSP negotiation token")
        tls_credssp.bio_write(authenticate_header)

        # NTLM Challenge Response and Server Public Key Validation
        ts_request = TSRequest()
        ts_request.fromString(tls_credssp.recv(8192))
        challenge_token = ts_request['negoTokens']
        server_cert = tls_credssp.get_peer_certificate()

        # not using channel bindings
        #certificate_digest = base64.b16decode(server_cert.digest('SHA256').replace(':', ''))
        ## channel_binding_structure = gss_channel_bindings_struct()
        ## channel_binding_structure['application_data'] = "tls-server-end-point:" + certificate_digest
        public_key = HttpCredSSPAuth._get_rsa_public_key(server_cert)
        # The _RSAPublicKey must be 'wrapped' using the negotiated GSSAPI mechanism and send to the server along with
        # the final SPNEGO token. This step of the CredSSP protocol is designed to thwart 'man-in-the-middle' attacks

        # Build and encrypt the response to the server
        ts_request = TSRequest()
        ts_request['negoTokens'] = context_generator.send(challenge_token)
        public_key_encrypted, signature = context.wrap_message(public_key)
        ts_request['pubKeyAuth'] = signature + public_key_encrypted

        tls_credssp.send(ts_request.getData())
        enc_type3 = tls_credssp.bio_read(8192)
        http_auth_response = yield self._set_credssp_header(response.request, enc_type3)

        # TLS decrypt the response, then ASN decode and check the error code
        auth_response = self._get_credssp_header(http_auth_response)
        if not auth_response or auth_response is None:
            raise Exception("The remote host rejected the challenge response")

        tls_credssp.bio_write(auth_response)
        ts_request = TSRequest()
        ts_request.fromString(tls_credssp.recv(8192))
        # TODO: Validate server cert?
        #a = ts_request['pubKeyAuth']
        # print ":".join("{:02x}".format(ord(c)) for c in a)

        # 4. Send the Credentials to be delegated, these are encrypted with both NTLM v2 and then by TLS
        tsp = TSPasswordCreds()
        tsp['domain'] = self.domain
        tsp['username'] = self.username
        tsp['password'] = self.password

        tsc = TSCredentials()
        tsc['type'] = 1
        tsc['credentials'] = tsp.getData()

        ts_request = TSRequest()
        ts_request['authInfo'] = context.wrap_message(tsc.getData())

        tls_credssp.send(ts_request.getData())
        final = tls_credssp.bio_read(8192)
        http_response = yield self._set_credssp_header(response.request, final)

        if http_response.status_code == 401:
            raise Exception('Authentication Failed')