From 290385a8a0454bed82906fea8329f550985e9fc6 Mon Sep 17 00:00:00 2001 From: Shreya Date: Sun, 31 Jan 2021 19:38:36 +0530 Subject: [PATCH] Zerologon's success on a machine shouldn't prevent other exploit attempts on the machine (ZL gathers credentials for other exploits) --- monkey/infection_monkey/exploit/HostExploiter.py | 7 +++++++ monkey/infection_monkey/exploit/zerologon.py | 12 ++++++++++++ monkey/infection_monkey/monkey.py | 11 +++++++---- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/monkey/infection_monkey/exploit/HostExploiter.py b/monkey/infection_monkey/exploit/HostExploiter.py index 274d07329..9188c4fa7 100644 --- a/monkey/infection_monkey/exploit/HostExploiter.py +++ b/monkey/infection_monkey/exploit/HostExploiter.py @@ -35,6 +35,13 @@ class HostExploiter(Plugin): # Usual values are 'vulnerability' or 'brute_force' EXPLOIT_TYPE = ExploitType.VULNERABILITY + # Specifies whether a machine, on which the exploit was successful, should be added to the set of exploited + # machines. This would then prevent any other exploits from being attempted on it. + # Sample use case - Zerologon exploiter: + # Exploited machine gives us useful credentials which can be used, but machine isn't compromised by Zerologon + # on its own. Some other exploit using PTH needs to be exploit it. + SHOULD_ADD_MACHINE_TO_EXPLOITED_SET = True + @property @abstractmethod def _EXPLOITED_SERVICE(self): diff --git a/monkey/infection_monkey/exploit/zerologon.py b/monkey/infection_monkey/exploit/zerologon.py index b4473c1f9..70888f54c 100644 --- a/monkey/infection_monkey/exploit/zerologon.py +++ b/monkey/infection_monkey/exploit/zerologon.py @@ -65,6 +65,7 @@ class ZerologonExploiter(HostExploiter): _TARGET_OS_TYPE = ['windows'] _EXPLOITED_SERVICE = 'Netlogon' EXPLOIT_TYPE = ExploitType.VULNERABILITY + SHOULD_ADD_MACHINE_TO_EXPLOITED_SET = False MAX_ATTEMPTS = 2000 OPTIONS_FOR_SECRETSDUMP =\ { @@ -227,6 +228,7 @@ class ZerologonExploiter(HostExploiter): if user in secret: hashes = secret.split(':')[2:4] # format of secret - "domain\uid:rid:lmhash:nthash:::" self.add_extracted_creds_to_exploit_info(user, hashes[0], hashes[1]) + self.add_extracted_creds_to_monkey_config(user, hashes[0], hashes[1]) return ':'.join(hashes) # format - "lmhash:nthash" def add_extracted_creds_to_exploit_info(self, user, lmhash, nthash): @@ -239,6 +241,16 @@ class ZerologonExploiter(HostExploiter): } }) + def add_extracted_creds_to_monkey_config(self, user, lmhash, nthash): # so other exploiters can use these creds + if user not in self._config.exploit_user_list: + self._config.exploit_user_list.append(user) + + if lmhash not in self._config.exploit_lm_hash_list: + self._config.exploit_lm_hash_list.append(lmhash) + + 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): return diff --git a/monkey/infection_monkey/monkey.py b/monkey/infection_monkey/monkey.py index 3a19e40ac..e001e6c43 100644 --- a/monkey/infection_monkey/monkey.py +++ b/monkey/infection_monkey/monkey.py @@ -208,7 +208,8 @@ class InfectionMonkey(object): if self.try_exploiting(machine, exploiter): host_exploited = True VictimHostTelem('T1210', ScanStatus.USED, machine=machine).send() - break + if exploiter.SHOULD_ADD_MACHINE_TO_EXPLOITED_SET: + break # if adding machine to exploited, won't try other exploits on it if not host_exploited: self._fail_exploitation_machines.add(machine) VictimHostTelem('T1210', ScanStatus.SCANNED, machine=machine).send() @@ -351,7 +352,8 @@ class InfectionMonkey(object): try: result = exploiter.exploit_host() if result: - self.successfully_exploited(machine, exploiter) + self.successfully_exploited(machine, exploiter) if exploiter.SHOULD_ADD_MACHINE_TO_EXPLOITED_SET else\ + self.successfully_exploited(machine, exploiter, False) return True else: LOG.info("Failed exploiting %r with exploiter %s", machine, exploiter.__class__.__name__) @@ -369,13 +371,14 @@ class InfectionMonkey(object): exploiter.send_exploit_telemetry(result) return False - def successfully_exploited(self, machine, exploiter): + def successfully_exploited(self, machine, exploiter, should_add_machine_to_exploited_set=True): """ Workflow of registering successfully exploited machine :param machine: machine that was exploited :param exploiter: exploiter that succeeded """ - self._exploited_machines.add(machine) + if should_add_machine_to_exploited_set: + self._exploited_machines.add(machine) LOG.info("Successfully propagated to %s using %s", machine, exploiter.__class__.__name__)