diff --git a/.swm/AzD8XysWg1BBXCjCDkfq.swm b/.swm/AzD8XysWg1BBXCjCDkfq.swm index 29ad78526..708d8e8c5 100644 --- a/.swm/AzD8XysWg1BBXCjCDkfq.swm +++ b/.swm/AzD8XysWg1BBXCjCDkfq.swm @@ -17,13 +17,13 @@ "type": "snippet", "path": "monkey/infection_monkey/config.py", "comments": [], - "firstLineNumber": 124, + "firstLineNumber": 103, "lines": [ " exploiter_classes = []", " system_info_collector_classes = []", " ", - "* # how many victims to look for in a single scan iteration\r", - "* victims_max_find = 100\r", + "* # how many victims to look for in a single scan iteration", + "* victims_max_find = 100", " ", " # how many victims to exploit before stopping", " victims_max_exploit = 100" @@ -35,23 +35,23 @@ "comments": [], "firstLineNumber": 220, "lines": [ - " if not self._keep_running or not WormConfiguration.alive:", - " break", + " if not WormConfiguration.alive:", + " logger.info(\"Marked not alive from configuration\")", " ", - "* machines = self._network.get_victim_machines(", - "* max_find=WormConfiguration.victims_max_find,", - "* stop_callback=ControlClient.check_for_stop,", - "* )", - " is_empty = True", - " for machine in machines:", - " if ControlClient.check_for_stop():" + "* machines = self._network.get_victim_machines(", + "* max_find=WormConfiguration.victims_max_find,", + "* stop_callback=ControlClient.check_for_stop,", + "* )", + " for machine in machines:", + " if ControlClient.check_for_stop():", + " break" ] }, { "type": "snippet", "path": "monkey/monkey_island/cc/services/config_schema/internal.py", "comments": [], - "firstLineNumber": 42, + "firstLineNumber": 28, "lines": [ " \"title\": \"Monkey\",", " \"type\": \"object\",", @@ -74,13 +74,13 @@ } ], "symbols": {}, - "file_version": "2.0.1", + "file_version": "2.0.3", "meta": { - "app_version": "0.4.9-1", + "app_version": "0.6.6-2", "file_blobs": { - "monkey/infection_monkey/config.py": "0bede1c57949987f5c8025bd9b8f7aa29d02a6af", - "monkey/infection_monkey/monkey.py": "89d2fa8452dee70f6d2985a9bb452f0159ea8219", - "monkey/monkey_island/cc/services/config_schema/internal.py": "1ce1c864b1df332b65e16b4ce9ed533affd73f9c" + "monkey/infection_monkey/config.py": "8f4984ba6563564343282765ab498efca5d89ba8", + "monkey/infection_monkey/monkey.py": "4160a36e0e624404d77526472d51dd07bba49e5a", + "monkey/monkey_island/cc/services/config_schema/internal.py": "86318eaf19b9991a8af5de861a3eb085238e17a4" } } } diff --git a/CHANGELOG.md b/CHANGELOG.md index 5cf8edab4..22cc8d781 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ Changelog](https://keepachangelog.com/en/1.0.0/). - Azure credential collector, because it was broken (not gathering credentials). #1535 - Custom monkey directory name config option. #1537 - Hostname system info collector. #1535 +- Max iterations and timeout between iterations config options. #1600 ### Fixed - A bug in network map page that caused delay of telemetry log loading. #1545 diff --git a/monkey/infection_monkey/config.py b/monkey/infection_monkey/config.py index 8d33af8fd..8f4984ba6 100644 --- a/monkey/infection_monkey/config.py +++ b/monkey/infection_monkey/config.py @@ -99,12 +99,6 @@ class Configuration(object): # sets whether or not the monkey is alive. if false will stop scanning and exploiting alive = True - # how long to wait between scan iterations - timeout_between_iterations = 100 - - # how many scan iterations to perform on each run - max_iterations = 1 - finger_classes = [] exploiter_classes = [] system_info_collector_classes = [] @@ -124,9 +118,6 @@ class Configuration(object): # Configuration servers to try to connect to, in this order. command_servers = ["192.0.2.0:5000"] - # sets whether or not to retry failed hosts on next scan - retry_failed_explotation = True - keep_tunnel_open_time = 60 ########################### diff --git a/monkey/infection_monkey/example.conf b/monkey/infection_monkey/example.conf index 556bdfcaa..dcb3b3138 100644 --- a/monkey/infection_monkey/example.conf +++ b/monkey/infection_monkey/example.conf @@ -43,7 +43,6 @@ "MSSQLFingerprint", "ElasticFinger" ], - "max_iterations": 3, "monkey_log_path_windows": "%temp%\\~df1563.tmp", "monkey_log_path_linux": "/tmp/user-1563", "ms08_067_exploit_attempts": 5, @@ -51,7 +50,6 @@ "ping_scan_timeout": 10000, "smb_download_timeout": 300, "smb_service_name": "InfectionMonkey", - "retry_failed_explotation": true, "self_delete_in_cleanup": true, "skip_exploit_if_file_exist": false, "exploit_user_list": [], @@ -77,7 +75,6 @@ 7001, 8088 ], - "timeout_between_iterations": 10, "victims_max_exploit": 100, "victims_max_find": 100, "post_breach_actions": [] diff --git a/monkey/infection_monkey/monkey.py b/monkey/infection_monkey/monkey.py index cc9045408..4160a36e0 100644 --- a/monkey/infection_monkey/monkey.py +++ b/monkey/infection_monkey/monkey.py @@ -208,98 +208,80 @@ class InfectionMonkey(object): raise PlannedShutdownException("Marked 'not alive' from configuration.") def propagate(self): - for iteration_index in range(WormConfiguration.max_iterations): - ControlClient.keepalive() - ControlClient.load_control_config() + ControlClient.keepalive() + ControlClient.load_control_config() - self._network.initialize() + self._network.initialize() - self._fingerprint = HostFinger.get_instances() + self._fingerprint = HostFinger.get_instances() - self._exploiters = HostExploiter.get_classes() + self._exploiters = HostExploiter.get_classes() - if not self._keep_running or not WormConfiguration.alive: + if not WormConfiguration.alive: + logger.info("Marked not alive from configuration") + + machines = self._network.get_victim_machines( + max_find=WormConfiguration.victims_max_find, + stop_callback=ControlClient.check_for_stop, + ) + for machine in machines: + if ControlClient.check_for_stop(): break - machines = self._network.get_victim_machines( - max_find=WormConfiguration.victims_max_find, - stop_callback=ControlClient.check_for_stop, - ) - is_empty = True - for machine in machines: - if ControlClient.check_for_stop(): - break - - is_empty = False - for finger in self._fingerprint: - logger.info( - "Trying to get OS fingerprint from %r with module %s", - machine, - finger.__class__.__name__, - ) - try: - finger.get_host_fingerprint(machine) - except BaseException as exc: - logger.error( - "Failed to run fingerprinter %s, exception %s" - % finger.__class__.__name__, - str(exc), - ) - - ScanTelem(machine).send() - - # skip machines that we've already exploited - if machine in self._exploited_machines: - logger.debug("Skipping %r - already exploited", machine) - continue - elif machine in self._fail_exploitation_machines: - if WormConfiguration.retry_failed_explotation: - logger.debug("%r - exploitation failed before, trying again", machine) - else: - logger.debug("Skipping %r - exploitation failed before", machine) - continue - - if self._monkey_tunnel: - self._monkey_tunnel.set_tunnel_for_host(machine) - if self._default_server: - if self._network.on_island(self._default_server): - machine.set_default_server( - get_interface_to_target(machine.ip_addr) - + (":" + self._default_server_port if self._default_server_port else "") - ) - else: - machine.set_default_server(self._default_server) - logger.debug( - "Default server for machine: %r set to %s" - % (machine, machine.default_server) - ) - - # Order exploits according to their type - self._exploiters = sorted( - self._exploiters, key=lambda exploiter_: exploiter_.EXPLOIT_TYPE.value + for finger in self._fingerprint: + logger.info( + "Trying to get OS fingerprint from %r with module %s", + machine, + finger.__class__.__name__, ) - host_exploited = False - for exploiter in [exploiter(machine) for exploiter in self._exploiters]: - if self.try_exploiting(machine, exploiter): - host_exploited = True - VictimHostTelem("T1210", ScanStatus.USED, machine=machine).send() - if exploiter.RUNS_AGENT_ON_SUCCESS: - 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() - if not self._keep_running: - break + try: + finger.get_host_fingerprint(machine) + except BaseException as exc: + logger.error( + "Failed to run fingerprinter %s, exception %s" % finger.__class__.__name__, + str(exc), + ) - if (not is_empty) and (WormConfiguration.max_iterations > iteration_index + 1): - time_to_sleep = WormConfiguration.timeout_between_iterations - logger.info("Sleeping %d seconds before next life cycle iteration", time_to_sleep) - time.sleep(time_to_sleep) + ScanTelem(machine).send() - if self._keep_running and WormConfiguration.alive: - logger.info("Reached max iterations (%d)", WormConfiguration.max_iterations) - elif not WormConfiguration.alive: + # skip machines that we've already exploited + if machine in self._exploited_machines: + logger.debug("Skipping %r - already exploited", machine) + continue + + if self._monkey_tunnel: + self._monkey_tunnel.set_tunnel_for_host(machine) + if self._default_server: + if self._network.on_island(self._default_server): + machine.set_default_server( + get_interface_to_target(machine.ip_addr) + + (":" + self._default_server_port if self._default_server_port else "") + ) + else: + machine.set_default_server(self._default_server) + logger.debug( + "Default server for machine: %r set to %s" % (machine, machine.default_server) + ) + + # Order exploits according to their type + self._exploiters = sorted( + self._exploiters, key=lambda exploiter_: exploiter_.EXPLOIT_TYPE.value + ) + host_exploited = False + for exploiter in [exploiter(machine) for exploiter in self._exploiters]: + if self.try_exploiting(machine, exploiter): + host_exploited = True + VictimHostTelem("T1210", ScanStatus.USED, machine=machine).send() + if exploiter.RUNS_AGENT_ON_SUCCESS: + 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() + if not self._keep_running: + break + + if not WormConfiguration.alive: logger.info("Marked not alive from configuration") def upgrade_to_64_if_needed(self): diff --git a/monkey/monkey_island/cc/services/config_schema/monkey.py b/monkey/monkey_island/cc/services/config_schema/monkey.py index 97fdbd19b..480aa0852 100644 --- a/monkey/monkey_island/cc/services/config_schema/monkey.py +++ b/monkey/monkey_island/cc/services/config_schema/monkey.py @@ -93,35 +93,5 @@ MONKEY = { }, }, }, - "persistent_scanning": { - "title": "Persistent scanning", - "type": "object", - "properties": { - "max_iterations": { - "title": "Max iterations", - "type": "integer", - "default": 1, - "minimum": 1, - "description": "Determines how many iterations of the monkey's full lifecycle " - "should occur " - "(how many times to do the scan)", - }, - "timeout_between_iterations": { - "title": "Wait time between iterations", - "type": "integer", - "default": 100, - "minimum": 0, - "description": "Determines for how long (in seconds) should the monkey wait " - "before starting another scan", - }, - "retry_failed_explotation": { - "title": "Retry failed exploitation", - "type": "boolean", - "default": True, - "description": "Determines whether the monkey should retry exploiting machines" - " it didn't successfully exploit on previous scans", - }, - }, - }, }, } diff --git a/monkey/tests/data_for_tests/monkey_configs/monkey_config_standard.json b/monkey/tests/data_for_tests/monkey_configs/monkey_config_standard.json index d27f142e7..112d649d8 100644 --- a/monkey/tests/data_for_tests/monkey_configs/monkey_config_standard.json +++ b/monkey/tests/data_for_tests/monkey_configs/monkey_config_standard.json @@ -163,11 +163,6 @@ "processlistcollector", "mimikatzcollector" ] - }, - "persistent_scanning": { - "max_iterations": 1, - "timeout_between_iterations": 100, - "retry_failed_explotation": true } } }