Exemplo n.º 1
0
    def test_skip_me(self):
        auth = PasswordAuthentication('SERVER2012', 'Administrator', 'Pa55w0rd', compatibility=3)
        ntlm_context = NtlmContext(auth, session_security='none', hostname='thor')
        context = ntlm_context.initialize_security_context()

        token = context.send(None)
        # token.dump_flags()

        encoded = base64.b64encode(token)
        session = Session()
        session.headers.update({'Authorization': 'NTLM ' + encoded})
        response = session.post("http://192.168.137.238:80")

        ntlm_regex = re.compile('(?:.*,)*\s*NTLM\s*([^,]*),?', re.I)
        authreq = response.headers.get('www-authenticate', None)
        if authreq:
            match_obj = ntlm_regex.search(authreq)
            if match_obj and len(match_obj.group(1)) > 0:
                encoded = match_obj.group(1)

        challenge = base64.b64decode(encoded)
        # challenge.dump_flags()

        print binascii.hexlify(challenge)
        response_token = context.send(challenge)
        # response_token.dump_flags()

        encoded_response_token = base64.b64encode(response_token)
        session.headers.update({'Authorization': 'NTLM ' + encoded_response_token})
        response = session.get("http://192.168.137.238:80/")
        print response.content
Exemplo n.º 2
0
 def test_that_initialize_security_context_generates_negotiate_token(self):
     ntlm_context = NtlmContext(self.auth,
                                hostname='thor',
                                session_security='none')
     context = ntlm_context.initialize_security_context()
     token = context.send(None)
     self.assertEqual(self.tokens.negotiate, token)
Exemplo n.º 3
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.º 4
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.º 5
0
    def handle_401(self, response, **kwargs):
        self.context = NtlmContext(self.password_authenticator, session_security='encrypt')
        credssp_processor = self._credssp_processor(self.context)
        next(credssp_processor)

        while response.status_code == 401:
            # This is required
            response.content
            response.raw.release_conn()
            client_request = credssp_processor.send(response)
            response = response.connection.send(client_request, **kwargs)

        return response
Exemplo n.º 6
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')