From 5675724843f04f8576dbff23e88cf4b4dcdca66c Mon Sep 17 00:00:00 2001 From: Shreya Malviya Date: Wed, 21 Sep 2022 14:33:16 +0530 Subject: [PATCH 01/21] Island: Add SET_MODE to IslandEventTopic --- monkey/monkey_island/cc/event_queue/i_island_event_queue.py | 1 + 1 file changed, 1 insertion(+) diff --git a/monkey/monkey_island/cc/event_queue/i_island_event_queue.py b/monkey/monkey_island/cc/event_queue/i_island_event_queue.py index d2398df86..7e188875b 100644 --- a/monkey/monkey_island/cc/event_queue/i_island_event_queue.py +++ b/monkey/monkey_island/cc/event_queue/i_island_event_queue.py @@ -9,6 +9,7 @@ class IslandEventTopic(Enum): AGENT_CONNECTED = auto() CLEAR_SIMULATION_DATA = auto() RESET_AGENT_CONFIGURATION = auto() + SET_MODE = auto() class IIslandEventQueue(ABC): From 67e280fd7ae8093978da43f992cde7d1f882d5cf Mon Sep 17 00:00:00 2001 From: Shreya Malviya Date: Wed, 21 Sep 2022 14:38:08 +0530 Subject: [PATCH 02/21] Island: Publish SET_MODE event in IslandMode's PUT --- monkey/monkey_island/cc/resources/island_mode.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/monkey/monkey_island/cc/resources/island_mode.py b/monkey/monkey_island/cc/resources/island_mode.py index 84d2858c5..434cae551 100644 --- a/monkey/monkey_island/cc/resources/island_mode.py +++ b/monkey/monkey_island/cc/resources/island_mode.py @@ -4,6 +4,7 @@ from http import HTTPStatus from flask import request +from monkey_island.cc.event_queue import IIslandEventQueue, IslandEventTopic from monkey_island.cc.models import IslandMode as IslandModeEnum from monkey_island.cc.resources.AbstractResource import AbstractResource from monkey_island.cc.resources.request_authentication import jwt_required @@ -15,8 +16,11 @@ logger = logging.getLogger(__name__) class IslandMode(AbstractResource): urls = ["/api/island/mode"] - def __init__(self, island_mode_service: IslandModeService): + def __init__( + self, island_mode_service: IslandModeService, island_event_queue: IIslandEventQueue + ): self._island_mode_service = island_mode_service + self._island_event_queue = island_event_queue @jwt_required def put(self): @@ -24,6 +28,7 @@ class IslandMode(AbstractResource): mode = IslandModeEnum(request.json) self._island_mode_service.set_mode(mode) + self._island_event_queue.publish(topic=IslandEventTopic.SET_MODE, event=mode) return {}, HTTPStatus.NO_CONTENT except (AttributeError, json.decoder.JSONDecodeError): From f20f11265bb1b733c69062f4dcc679c36e555d2e Mon Sep 17 00:00:00 2001 From: Shreya Malviya Date: Wed, 21 Sep 2022 16:03:03 +0530 Subject: [PATCH 03/21] Island: Add set_island_mode Island event handler --- .../cc/island_event_handlers/__init__.py | 1 + .../island_event_handlers/set_island_mode.py | 32 +++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 monkey/monkey_island/cc/island_event_handlers/set_island_mode.py diff --git a/monkey/monkey_island/cc/island_event_handlers/__init__.py b/monkey/monkey_island/cc/island_event_handlers/__init__.py index 0c977976e..92e385715 100644 --- a/monkey/monkey_island/cc/island_event_handlers/__init__.py +++ b/monkey/monkey_island/cc/island_event_handlers/__init__.py @@ -1,2 +1,3 @@ from .reset_agent_configuration import reset_agent_configuration from .reset_machine_repository import reset_machine_repository +from .set_island_mode import set_island_mode diff --git a/monkey/monkey_island/cc/island_event_handlers/set_island_mode.py b/monkey/monkey_island/cc/island_event_handlers/set_island_mode.py new file mode 100644 index 000000000..9e13ccef2 --- /dev/null +++ b/monkey/monkey_island/cc/island_event_handlers/set_island_mode.py @@ -0,0 +1,32 @@ +from typing import Any + +from common.agent_configuration import AgentConfiguration +from monkey_island.cc.models import IslandMode +from monkey_island.cc.repository import IAgentConfigurationRepository + + +class set_island_mode: + """ + Callable class that sets the Island's mode + """ + + def __init__( + self, + agent_configuration_repository: IAgentConfigurationRepository, + default_agent_configuration: AgentConfiguration, + default_ransomware_agent_configuration: AgentConfiguration, + ): + self._agent_configuration_repository = agent_configuration_repository + self._default_agent_configuration = default_agent_configuration + self._default_ransomware_agent_configuration = default_ransomware_agent_configuration + + def __call__(self, event: Any = None): + mode = event + if mode == IslandMode.RANSOMWARE: + self._agent_configuration_repository.store_configuration( + self._default_ransomware_agent_configuration + ) + else: + self._agent_configuration_repository.store_configuration( + self._default_agent_configuration + ) From 8b8778399825f54705efc11994d9605bf8ee33b3 Mon Sep 17 00:00:00 2001 From: Shreya Malviya Date: Wed, 21 Sep 2022 16:07:00 +0530 Subject: [PATCH 04/21] Island: Subscribe set_island_mode to IslandEventTopic.SET_MODE --- monkey/monkey_island/cc/setup/island_event_handlers.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/monkey/monkey_island/cc/setup/island_event_handlers.py b/monkey/monkey_island/cc/setup/island_event_handlers.py index a69cf1731..274399eb2 100644 --- a/monkey/monkey_island/cc/setup/island_event_handlers.py +++ b/monkey/monkey_island/cc/setup/island_event_handlers.py @@ -5,6 +5,7 @@ from monkey_island.cc.event_queue import IIslandEventQueue, IslandEventTopic from monkey_island.cc.island_event_handlers import ( reset_agent_configuration, reset_machine_repository, + set_island_mode, ) from monkey_island.cc.repository import ( IAgentEventRepository, @@ -20,6 +21,7 @@ def setup_island_event_handlers(container: DIContainer): _subscribe_reset_agent_configuration_events(island_event_queue, container) _subscribe_clear_simulation_data_events(island_event_queue, container) + _subscribe_set_island_mode_events(island_event_queue, container) def _subscribe_reset_agent_configuration_events( @@ -52,3 +54,9 @@ def _subscribe_clear_simulation_data_events( ]: repository = container.resolve(i_repository) island_event_queue.subscribe(IslandEventTopic.CLEAR_SIMULATION_DATA, repository.reset) + + +def _subscribe_set_island_mode_events( + island_event_queue: IIslandEventQueue, container: DIContainer +): + island_event_queue.subscribe(IslandEventTopic.SET_MODE, container.resolve(set_island_mode)) From 822d9d6eec823a1b36fef99fa58d628fa9237ade Mon Sep 17 00:00:00 2001 From: Shreya Malviya Date: Wed, 21 Sep 2022 16:13:33 +0530 Subject: [PATCH 05/21] Island: Rename set_island_mode -> set_agent_configuration_per_island_mode --- monkey/monkey_island/cc/island_event_handlers/__init__.py | 2 +- ...d_mode.py => set_agent_configuration_per_island_mode.py} | 2 +- monkey/monkey_island/cc/setup/island_event_handlers.py | 6 ++++-- 3 files changed, 6 insertions(+), 4 deletions(-) rename monkey/monkey_island/cc/island_event_handlers/{set_island_mode.py => set_agent_configuration_per_island_mode.py} (96%) diff --git a/monkey/monkey_island/cc/island_event_handlers/__init__.py b/monkey/monkey_island/cc/island_event_handlers/__init__.py index 92e385715..11343c2fa 100644 --- a/monkey/monkey_island/cc/island_event_handlers/__init__.py +++ b/monkey/monkey_island/cc/island_event_handlers/__init__.py @@ -1,3 +1,3 @@ from .reset_agent_configuration import reset_agent_configuration from .reset_machine_repository import reset_machine_repository -from .set_island_mode import set_island_mode +from .set_agent_configuration_per_island_mode import set_agent_configuration_per_island_mode diff --git a/monkey/monkey_island/cc/island_event_handlers/set_island_mode.py b/monkey/monkey_island/cc/island_event_handlers/set_agent_configuration_per_island_mode.py similarity index 96% rename from monkey/monkey_island/cc/island_event_handlers/set_island_mode.py rename to monkey/monkey_island/cc/island_event_handlers/set_agent_configuration_per_island_mode.py index 9e13ccef2..654dd1ebc 100644 --- a/monkey/monkey_island/cc/island_event_handlers/set_island_mode.py +++ b/monkey/monkey_island/cc/island_event_handlers/set_agent_configuration_per_island_mode.py @@ -5,7 +5,7 @@ from monkey_island.cc.models import IslandMode from monkey_island.cc.repository import IAgentConfigurationRepository -class set_island_mode: +class set_agent_configuration_per_island_mode: """ Callable class that sets the Island's mode """ diff --git a/monkey/monkey_island/cc/setup/island_event_handlers.py b/monkey/monkey_island/cc/setup/island_event_handlers.py index 274399eb2..4f86cca33 100644 --- a/monkey/monkey_island/cc/setup/island_event_handlers.py +++ b/monkey/monkey_island/cc/setup/island_event_handlers.py @@ -5,7 +5,7 @@ from monkey_island.cc.event_queue import IIslandEventQueue, IslandEventTopic from monkey_island.cc.island_event_handlers import ( reset_agent_configuration, reset_machine_repository, - set_island_mode, + set_agent_configuration_per_island_mode, ) from monkey_island.cc.repository import ( IAgentEventRepository, @@ -59,4 +59,6 @@ def _subscribe_clear_simulation_data_events( def _subscribe_set_island_mode_events( island_event_queue: IIslandEventQueue, container: DIContainer ): - island_event_queue.subscribe(IslandEventTopic.SET_MODE, container.resolve(set_island_mode)) + island_event_queue.subscribe( + IslandEventTopic.SET_MODE, container.resolve(set_agent_configuration_per_island_mode) + ) From 9ce652f1a554ad0ea0a8c2888f99e59ef294c570 Mon Sep 17 00:00:00 2001 From: Shreya Malviya Date: Wed, 21 Sep 2022 16:14:45 +0530 Subject: [PATCH 06/21] Island: Rename IslandEventTopic.SET_MODE -> IslandEventTopic.SET_ISLAND_MODE --- monkey/monkey_island/cc/event_queue/i_island_event_queue.py | 2 +- monkey/monkey_island/cc/resources/island_mode.py | 2 +- monkey/monkey_island/cc/setup/island_event_handlers.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/monkey/monkey_island/cc/event_queue/i_island_event_queue.py b/monkey/monkey_island/cc/event_queue/i_island_event_queue.py index 7e188875b..cc81f8e26 100644 --- a/monkey/monkey_island/cc/event_queue/i_island_event_queue.py +++ b/monkey/monkey_island/cc/event_queue/i_island_event_queue.py @@ -9,7 +9,7 @@ class IslandEventTopic(Enum): AGENT_CONNECTED = auto() CLEAR_SIMULATION_DATA = auto() RESET_AGENT_CONFIGURATION = auto() - SET_MODE = auto() + SET_ISLAND_MODE = auto() class IIslandEventQueue(ABC): diff --git a/monkey/monkey_island/cc/resources/island_mode.py b/monkey/monkey_island/cc/resources/island_mode.py index 434cae551..0eb10c35e 100644 --- a/monkey/monkey_island/cc/resources/island_mode.py +++ b/monkey/monkey_island/cc/resources/island_mode.py @@ -28,7 +28,7 @@ class IslandMode(AbstractResource): mode = IslandModeEnum(request.json) self._island_mode_service.set_mode(mode) - self._island_event_queue.publish(topic=IslandEventTopic.SET_MODE, event=mode) + self._island_event_queue.publish(topic=IslandEventTopic.SET_ISLAND_MODE, event=mode) return {}, HTTPStatus.NO_CONTENT except (AttributeError, json.decoder.JSONDecodeError): diff --git a/monkey/monkey_island/cc/setup/island_event_handlers.py b/monkey/monkey_island/cc/setup/island_event_handlers.py index 4f86cca33..5921da731 100644 --- a/monkey/monkey_island/cc/setup/island_event_handlers.py +++ b/monkey/monkey_island/cc/setup/island_event_handlers.py @@ -60,5 +60,5 @@ def _subscribe_set_island_mode_events( island_event_queue: IIslandEventQueue, container: DIContainer ): island_event_queue.subscribe( - IslandEventTopic.SET_MODE, container.resolve(set_agent_configuration_per_island_mode) + IslandEventTopic.SET_ISLAND_MODE, container.resolve(set_agent_configuration_per_island_mode) ) From b4c1879bf9772a71d5b922b7c33ff406a0029e17 Mon Sep 17 00:00:00 2001 From: Shreya Malviya Date: Wed, 21 Sep 2022 16:20:05 +0530 Subject: [PATCH 07/21] Island: Add set_simulation_mode Island event handler --- .../cc/island_event_handlers/__init__.py | 1 + .../set_simulation_mode.py | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 monkey/monkey_island/cc/island_event_handlers/set_simulation_mode.py diff --git a/monkey/monkey_island/cc/island_event_handlers/__init__.py b/monkey/monkey_island/cc/island_event_handlers/__init__.py index 11343c2fa..0f111a31e 100644 --- a/monkey/monkey_island/cc/island_event_handlers/__init__.py +++ b/monkey/monkey_island/cc/island_event_handlers/__init__.py @@ -1,3 +1,4 @@ from .reset_agent_configuration import reset_agent_configuration from .reset_machine_repository import reset_machine_repository from .set_agent_configuration_per_island_mode import set_agent_configuration_per_island_mode +from .set_simulation_mode import set_simulation_mode diff --git a/monkey/monkey_island/cc/island_event_handlers/set_simulation_mode.py b/monkey/monkey_island/cc/island_event_handlers/set_simulation_mode.py new file mode 100644 index 000000000..3aff9d56d --- /dev/null +++ b/monkey/monkey_island/cc/island_event_handlers/set_simulation_mode.py @@ -0,0 +1,19 @@ +from typing import Any + +from monkey_island.cc.repository import ISimulationRepository + + +class set_simulation_mode: + """ + Callable class that sets the Island's mode + """ + + def __init__( + self, + simulation_repository: ISimulationRepository, + ): + self._simulation_repository = simulation_repository + + def __call__(self, event: Any = None): + mode = event + self._simulation_repository.set_mode(mode) From 5a96d5b570e6e6b5757923d110fc859a13018d31 Mon Sep 17 00:00:00 2001 From: Shreya Malviya Date: Wed, 21 Sep 2022 16:21:50 +0530 Subject: [PATCH 08/21] Island: Subscribe set_simulation_mode to IslandEventTopic.SET_ISLAND_MODE --- monkey/monkey_island/cc/setup/island_event_handlers.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/monkey/monkey_island/cc/setup/island_event_handlers.py b/monkey/monkey_island/cc/setup/island_event_handlers.py index 5921da731..65d9cff51 100644 --- a/monkey/monkey_island/cc/setup/island_event_handlers.py +++ b/monkey/monkey_island/cc/setup/island_event_handlers.py @@ -6,6 +6,7 @@ from monkey_island.cc.island_event_handlers import ( reset_agent_configuration, reset_machine_repository, set_agent_configuration_per_island_mode, + set_simulation_mode, ) from monkey_island.cc.repository import ( IAgentEventRepository, @@ -62,3 +63,6 @@ def _subscribe_set_island_mode_events( island_event_queue.subscribe( IslandEventTopic.SET_ISLAND_MODE, container.resolve(set_agent_configuration_per_island_mode) ) + island_event_queue.subscribe( + IslandEventTopic.SET_ISLAND_MODE, container.resolve(set_simulation_mode) + ) From 1f96ab5ea97eca3431f51684fe99848558006850 Mon Sep 17 00:00:00 2001 From: Shreya Malviya Date: Wed, 21 Sep 2022 16:26:04 +0530 Subject: [PATCH 09/21] Island: Extract event topic to a variable in all Island event handler subscribe functions --- .../cc/setup/island_event_handlers.py | 31 +++++++++---------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/monkey/monkey_island/cc/setup/island_event_handlers.py b/monkey/monkey_island/cc/setup/island_event_handlers.py index 65d9cff51..46429f292 100644 --- a/monkey/monkey_island/cc/setup/island_event_handlers.py +++ b/monkey/monkey_island/cc/setup/island_event_handlers.py @@ -28,25 +28,23 @@ def setup_island_event_handlers(container: DIContainer): def _subscribe_reset_agent_configuration_events( island_event_queue: IIslandEventQueue, container: DIContainer ): - island_event_queue.subscribe( - IslandEventTopic.RESET_AGENT_CONFIGURATION, container.resolve(reset_agent_configuration) - ) + topic = IslandEventTopic.RESET_AGENT_CONFIGURATION + + island_event_queue.subscribe(topic, container.resolve(reset_agent_configuration)) def _subscribe_clear_simulation_data_events( island_event_queue: IIslandEventQueue, container: DIContainer ): + topic = IslandEventTopic.CLEAR_SIMULATION_DATA + legacy_database_reset = partial(Database.reset_db, reset_config=False) - island_event_queue.subscribe(IslandEventTopic.CLEAR_SIMULATION_DATA, legacy_database_reset) + island_event_queue.subscribe(topic, legacy_database_reset) credentials_repository = container.resolve(ICredentialsRepository) - island_event_queue.subscribe( - IslandEventTopic.CLEAR_SIMULATION_DATA, credentials_repository.remove_stolen_credentials - ) + island_event_queue.subscribe(topic, credentials_repository.remove_stolen_credentials) - island_event_queue.subscribe( - IslandEventTopic.CLEAR_SIMULATION_DATA, container.resolve(reset_machine_repository) - ) + island_event_queue.subscribe(topic, container.resolve(reset_machine_repository)) for i_repository in [ INodeRepository, @@ -54,15 +52,14 @@ def _subscribe_clear_simulation_data_events( IAgentRepository, ]: repository = container.resolve(i_repository) - island_event_queue.subscribe(IslandEventTopic.CLEAR_SIMULATION_DATA, repository.reset) + island_event_queue.subscribe(topic, repository.reset) def _subscribe_set_island_mode_events( island_event_queue: IIslandEventQueue, container: DIContainer ): - island_event_queue.subscribe( - IslandEventTopic.SET_ISLAND_MODE, container.resolve(set_agent_configuration_per_island_mode) - ) - island_event_queue.subscribe( - IslandEventTopic.SET_ISLAND_MODE, container.resolve(set_simulation_mode) - ) + topic = IslandEventTopic.SET_ISLAND_MODE + + island_event_queue.subscribe(topic, container.resolve(set_agent_configuration_per_island_mode)) + + island_event_queue.subscribe(topic, container.resolve(set_simulation_mode)) From d9d388d41c63038f532ba741093973e4ef3a08da Mon Sep 17 00:00:00 2001 From: Shreya Malviya Date: Wed, 21 Sep 2022 16:31:24 +0530 Subject: [PATCH 10/21] Island: Get Island mode from simulation repository in IslandMode's GET --- monkey/monkey_island/cc/resources/island_mode.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/monkey/monkey_island/cc/resources/island_mode.py b/monkey/monkey_island/cc/resources/island_mode.py index 0eb10c35e..d3086f484 100644 --- a/monkey/monkey_island/cc/resources/island_mode.py +++ b/monkey/monkey_island/cc/resources/island_mode.py @@ -6,6 +6,7 @@ from flask import request from monkey_island.cc.event_queue import IIslandEventQueue, IslandEventTopic from monkey_island.cc.models import IslandMode as IslandModeEnum +from monkey_island.cc.repository import ISimulationRepository from monkey_island.cc.resources.AbstractResource import AbstractResource from monkey_island.cc.resources.request_authentication import jwt_required from monkey_island.cc.services import IslandModeService @@ -17,10 +18,14 @@ class IslandMode(AbstractResource): urls = ["/api/island/mode"] def __init__( - self, island_mode_service: IslandModeService, island_event_queue: IIslandEventQueue + self, + island_mode_service: IslandModeService, + island_event_queue: IIslandEventQueue, + simulation_repository: ISimulationRepository, ): self._island_mode_service = island_mode_service self._island_event_queue = island_event_queue + self._simulation_repository = simulation_repository @jwt_required def put(self): @@ -38,5 +43,5 @@ class IslandMode(AbstractResource): @jwt_required def get(self): - island_mode = self._island_mode_service.get_mode() + island_mode = self._simulation_repository.get_mode() return island_mode.value, HTTPStatus.OK From bc630e86e98284489fee839acee544d51748111a Mon Sep 17 00:00:00 2001 From: Shreya Malviya Date: Wed, 21 Sep 2022 16:36:44 +0530 Subject: [PATCH 11/21] Island: Remove IslandModeService from IslandMode resource --- monkey/monkey_island/cc/resources/island_mode.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/monkey/monkey_island/cc/resources/island_mode.py b/monkey/monkey_island/cc/resources/island_mode.py index d3086f484..d553e7ea5 100644 --- a/monkey/monkey_island/cc/resources/island_mode.py +++ b/monkey/monkey_island/cc/resources/island_mode.py @@ -9,7 +9,6 @@ from monkey_island.cc.models import IslandMode as IslandModeEnum from monkey_island.cc.repository import ISimulationRepository from monkey_island.cc.resources.AbstractResource import AbstractResource from monkey_island.cc.resources.request_authentication import jwt_required -from monkey_island.cc.services import IslandModeService logger = logging.getLogger(__name__) @@ -19,11 +18,9 @@ class IslandMode(AbstractResource): def __init__( self, - island_mode_service: IslandModeService, island_event_queue: IIslandEventQueue, simulation_repository: ISimulationRepository, ): - self._island_mode_service = island_mode_service self._island_event_queue = island_event_queue self._simulation_repository = simulation_repository @@ -31,10 +28,7 @@ class IslandMode(AbstractResource): def put(self): try: mode = IslandModeEnum(request.json) - - self._island_mode_service.set_mode(mode) self._island_event_queue.publish(topic=IslandEventTopic.SET_ISLAND_MODE, event=mode) - return {}, HTTPStatus.NO_CONTENT except (AttributeError, json.decoder.JSONDecodeError): return {}, HTTPStatus.BAD_REQUEST From 6933d25768dc3e9086b562b1e160228a0a835386 Mon Sep 17 00:00:00 2001 From: Shreya Malviya Date: Wed, 21 Sep 2022 16:38:57 +0530 Subject: [PATCH 12/21] Island: Remove IslandModeService --- monkey/monkey_island/cc/services/__init__.py | 1 - .../monkey_island/cc/services/initialize.py | 3 +- .../cc/services/island_mode_service.py | 46 ------------------- 3 files changed, 1 insertion(+), 49 deletions(-) delete mode 100644 monkey/monkey_island/cc/services/island_mode_service.py diff --git a/monkey/monkey_island/cc/services/__init__.py b/monkey/monkey_island/cc/services/__init__.py index 14c5664e9..d75734d59 100644 --- a/monkey/monkey_island/cc/services/__init__.py +++ b/monkey/monkey_island/cc/services/__init__.py @@ -1,4 +1,3 @@ from .authentication_service import AuthenticationService from .aws import AWSService -from .island_mode_service import IslandModeService diff --git a/monkey/monkey_island/cc/services/initialize.py b/monkey/monkey_island/cc/services/initialize.py index 9e6425215..830e010d7 100644 --- a/monkey/monkey_island/cc/services/initialize.py +++ b/monkey/monkey_island/cc/services/initialize.py @@ -47,7 +47,7 @@ from monkey_island.cc.repository import ( ) from monkey_island.cc.server_utils.consts import MONKEY_ISLAND_ABS_PATH from monkey_island.cc.server_utils.encryption import ILockableEncryptor, RepositoryEncryptor -from monkey_island.cc.services import AWSService, IslandModeService +from monkey_island.cc.services import AWSService from monkey_island.cc.services.attack.technique_reports.T1003 import T1003, T1003GetReportData from monkey_island.cc.services.run_local_monkey import LocalMonkeyRunService from monkey_island.cc.setup.mongo.mongo_setup import MONGO_URL @@ -175,7 +175,6 @@ def _log_agent_binary_hashes(agent_binary_repository: IAgentBinaryRepository): def _register_services(container: DIContainer): container.register_instance(AWSService, container.resolve(AWSService)) container.register_instance(LocalMonkeyRunService, container.resolve(LocalMonkeyRunService)) - container.register_instance(IslandModeService, container.resolve(IslandModeService)) container.register_instance(AuthenticationService, container.resolve(AuthenticationService)) diff --git a/monkey/monkey_island/cc/services/island_mode_service.py b/monkey/monkey_island/cc/services/island_mode_service.py deleted file mode 100644 index bc4869b9a..000000000 --- a/monkey/monkey_island/cc/services/island_mode_service.py +++ /dev/null @@ -1,46 +0,0 @@ -from common.agent_configuration import AgentConfiguration -from monkey_island.cc.models import IslandMode -from monkey_island.cc.repository import IAgentConfigurationRepository, ISimulationRepository - - -class IslandModeService: - def __init__( - self, - _agent_configuration_repository: IAgentConfigurationRepository, - simulation_repository: ISimulationRepository, - default_agent_configuration: AgentConfiguration, - default_ransomware_agent_configuration: AgentConfiguration, - ): - self._agent_configuration_repository = _agent_configuration_repository - self._simulation_repository = simulation_repository - self._default_agent_configuration = default_agent_configuration - self._default_ransomware_agent_configuration = default_ransomware_agent_configuration - - def get_mode(self): - """ - Get's the island's current mode - - :return The island's current mode - :raises RetrievalError: If the mode could not be retrieved - """ - return self._simulation_repository.get_mode() - - def set_mode(self, mode: IslandMode): - """ - Set the island's mode - - :param mode: The island's new mode - :raises StorageError: If the mode could not be saved - """ - self._simulation_repository.set_mode(mode) - self._set_configuration(mode) - - def _set_configuration(self, mode: IslandMode): - if mode == IslandMode.RANSOMWARE: - self._agent_configuration_repository.store_configuration( - self._default_ransomware_agent_configuration - ) - else: - self._agent_configuration_repository.store_configuration( - self._default_agent_configuration - ) From 4e0f2c89ec3a5a2690008ed79884427771608ece Mon Sep 17 00:00:00 2001 From: Shreya Malviya Date: Wed, 21 Sep 2022 16:39:24 +0530 Subject: [PATCH 13/21] UT: Remove test_island_mode_service.py --- .../cc/services/test_island_mode_service.py | 45 ------------------- 1 file changed, 45 deletions(-) delete mode 100644 monkey/tests/unit_tests/monkey_island/cc/services/test_island_mode_service.py diff --git a/monkey/tests/unit_tests/monkey_island/cc/services/test_island_mode_service.py b/monkey/tests/unit_tests/monkey_island/cc/services/test_island_mode_service.py deleted file mode 100644 index 1d12efb62..000000000 --- a/monkey/tests/unit_tests/monkey_island/cc/services/test_island_mode_service.py +++ /dev/null @@ -1,45 +0,0 @@ -import pytest -from tests.monkey_island import InMemoryAgentConfigurationRepository, InMemorySimulationRepository - -from common.agent_configuration import ( - DEFAULT_AGENT_CONFIGURATION, - DEFAULT_RANSOMWARE_AGENT_CONFIGURATION, -) -from monkey_island.cc.models import IslandMode -from monkey_island.cc.services import IslandModeService - - -@pytest.fixture -def agent_configuration_repository(): - return InMemoryAgentConfigurationRepository() - - -@pytest.fixture -def island_mode_service(agent_configuration_repository): - return IslandModeService( - agent_configuration_repository, - InMemorySimulationRepository(), - DEFAULT_AGENT_CONFIGURATION, - DEFAULT_RANSOMWARE_AGENT_CONFIGURATION, - ) - - -@pytest.mark.parametrize("mode", list(IslandMode)) -def test_set_mode(island_mode_service, mode): - island_mode_service.set_mode(mode) - assert island_mode_service.get_mode() == mode - - -@pytest.mark.parametrize( - "mode, expected_config", - [ - (IslandMode.UNSET, DEFAULT_AGENT_CONFIGURATION), - (IslandMode.ADVANCED, DEFAULT_AGENT_CONFIGURATION), - (IslandMode.RANSOMWARE, DEFAULT_RANSOMWARE_AGENT_CONFIGURATION), - ], -) -def test_set_mode_sets_config( - island_mode_service, agent_configuration_repository, mode, expected_config -): - island_mode_service.set_mode(mode) - assert agent_configuration_repository.get_configuration() == expected_config From fb2165b2e88c78dbbe425dfdab8f14bdf77f66ef Mon Sep 17 00:00:00 2001 From: Shreya Malviya Date: Wed, 21 Sep 2022 17:20:32 +0530 Subject: [PATCH 14/21] UT: Fix broken IslandMode tests --- .../cc/resources/test_island_mode.py | 31 ++++++++----------- 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/monkey/tests/unit_tests/monkey_island/cc/resources/test_island_mode.py b/monkey/tests/unit_tests/monkey_island/cc/resources/test_island_mode.py index 322f62502..1386bb6c7 100644 --- a/monkey/tests/unit_tests/monkey_island/cc/resources/test_island_mode.py +++ b/monkey/tests/unit_tests/monkey_island/cc/resources/test_island_mode.py @@ -5,27 +5,26 @@ import pytest from tests.common import StubDIContainer from tests.monkey_island import InMemorySimulationRepository +from monkey_island.cc.event_queue import IIslandEventQueue from monkey_island.cc.models import IslandMode -from monkey_island.cc.repository import RetrievalError +from monkey_island.cc.repository import ISimulationRepository from monkey_island.cc.resources.island_mode import IslandMode as IslandModeResource -from monkey_island.cc.services import IslandModeService - - -class MockIslandModeService(IslandModeService): - def __init__(self): - self._simulation_repository = InMemorySimulationRepository() - - def get_mode(self) -> IslandMode: - return self._simulation_repository.get_mode() - - def set_mode(self, mode: IslandMode): - self._simulation_repository.set_mode(mode) @pytest.fixture def flask_client(build_flask_client): container = StubDIContainer() - container.register_instance(IslandModeService, MockIslandModeService()) + + in_memory_simulation_repository = InMemorySimulationRepository() + container.register_instance(ISimulationRepository, in_memory_simulation_repository) + + def wrap_in_memory_simulation_repository_set_mode(topic, event): + mode = event + in_memory_simulation_repository.set_mode(mode) + + mock_island_event_queue = MagicMock(spec=IIslandEventQueue) + mock_island_event_queue.publish.side_effect = wrap_in_memory_simulation_repository_set_mode + container.register_instance(IIslandEventQueue, mock_island_event_queue) with build_flask_client(container) as flask_client: yield flask_client @@ -54,11 +53,7 @@ def test_island_mode_post__invalid_mode(flask_client): def test_island_mode_post__internal_server_error(build_flask_client): - mock_island_mode_service = MagicMock(spec=IslandModeService) - mock_island_mode_service.set_mode = MagicMock(side_effect=RetrievalError) - container = StubDIContainer() - container.register_instance(IslandModeService, mock_island_mode_service) with build_flask_client(container) as flask_client: resp = flask_client.put( From c1e15f8be5a0c36f68aad294186b46b41ed88b6f Mon Sep 17 00:00:00 2001 From: Shreya Malviya Date: Wed, 21 Sep 2022 17:41:54 +0530 Subject: [PATCH 15/21] Island: Fix docstring in set_agent_configuration_per_island_mode --- .../set_agent_configuration_per_island_mode.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monkey/monkey_island/cc/island_event_handlers/set_agent_configuration_per_island_mode.py b/monkey/monkey_island/cc/island_event_handlers/set_agent_configuration_per_island_mode.py index 654dd1ebc..7ed5e1188 100644 --- a/monkey/monkey_island/cc/island_event_handlers/set_agent_configuration_per_island_mode.py +++ b/monkey/monkey_island/cc/island_event_handlers/set_agent_configuration_per_island_mode.py @@ -7,7 +7,7 @@ from monkey_island.cc.repository import IAgentConfigurationRepository class set_agent_configuration_per_island_mode: """ - Callable class that sets the Island's mode + Callable class that sets the default Agent configuration as per the Island's mode """ def __init__( From add31fe397c8cd970e0f61c10bf2d1d6a3148597 Mon Sep 17 00:00:00 2001 From: Shreya Malviya Date: Wed, 21 Sep 2022 18:00:34 +0530 Subject: [PATCH 16/21] Island: Rename IslandModeEnum.SET_ISLAND_MODE's subscribers' arguments from 'event' to 'mode' --- .../set_agent_configuration_per_island_mode.py | 5 +---- .../cc/island_event_handlers/set_simulation_mode.py | 6 ++---- monkey/monkey_island/cc/resources/island_mode.py | 2 +- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/monkey/monkey_island/cc/island_event_handlers/set_agent_configuration_per_island_mode.py b/monkey/monkey_island/cc/island_event_handlers/set_agent_configuration_per_island_mode.py index 7ed5e1188..8385d0480 100644 --- a/monkey/monkey_island/cc/island_event_handlers/set_agent_configuration_per_island_mode.py +++ b/monkey/monkey_island/cc/island_event_handlers/set_agent_configuration_per_island_mode.py @@ -1,5 +1,3 @@ -from typing import Any - from common.agent_configuration import AgentConfiguration from monkey_island.cc.models import IslandMode from monkey_island.cc.repository import IAgentConfigurationRepository @@ -20,8 +18,7 @@ class set_agent_configuration_per_island_mode: self._default_agent_configuration = default_agent_configuration self._default_ransomware_agent_configuration = default_ransomware_agent_configuration - def __call__(self, event: Any = None): - mode = event + def __call__(self, mode: IslandMode): if mode == IslandMode.RANSOMWARE: self._agent_configuration_repository.store_configuration( self._default_ransomware_agent_configuration diff --git a/monkey/monkey_island/cc/island_event_handlers/set_simulation_mode.py b/monkey/monkey_island/cc/island_event_handlers/set_simulation_mode.py index 3aff9d56d..da15a8ac0 100644 --- a/monkey/monkey_island/cc/island_event_handlers/set_simulation_mode.py +++ b/monkey/monkey_island/cc/island_event_handlers/set_simulation_mode.py @@ -1,5 +1,4 @@ -from typing import Any - +from monkey_island.cc.models import IslandMode from monkey_island.cc.repository import ISimulationRepository @@ -14,6 +13,5 @@ class set_simulation_mode: ): self._simulation_repository = simulation_repository - def __call__(self, event: Any = None): - mode = event + def __call__(self, mode: IslandMode): self._simulation_repository.set_mode(mode) diff --git a/monkey/monkey_island/cc/resources/island_mode.py b/monkey/monkey_island/cc/resources/island_mode.py index d553e7ea5..f07e791aa 100644 --- a/monkey/monkey_island/cc/resources/island_mode.py +++ b/monkey/monkey_island/cc/resources/island_mode.py @@ -28,7 +28,7 @@ class IslandMode(AbstractResource): def put(self): try: mode = IslandModeEnum(request.json) - self._island_event_queue.publish(topic=IslandEventTopic.SET_ISLAND_MODE, event=mode) + self._island_event_queue.publish(topic=IslandEventTopic.SET_ISLAND_MODE, mode=mode) return {}, HTTPStatus.NO_CONTENT except (AttributeError, json.decoder.JSONDecodeError): return {}, HTTPStatus.BAD_REQUEST From 547637d151e13c4d8f78a0e2da83584793a42f1b Mon Sep 17 00:00:00 2001 From: Shreya Malviya Date: Wed, 21 Sep 2022 18:02:07 +0530 Subject: [PATCH 17/21] Island: Subscribe ISimulationRepository.set_mode to IslandEventTopic.SET_ISLAND_MODE --- monkey/monkey_island/cc/island_event_handlers/__init__.py | 1 - monkey/monkey_island/cc/setup/island_event_handlers.py | 5 +++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/monkey/monkey_island/cc/island_event_handlers/__init__.py b/monkey/monkey_island/cc/island_event_handlers/__init__.py index 0f111a31e..11343c2fa 100644 --- a/monkey/monkey_island/cc/island_event_handlers/__init__.py +++ b/monkey/monkey_island/cc/island_event_handlers/__init__.py @@ -1,4 +1,3 @@ from .reset_agent_configuration import reset_agent_configuration from .reset_machine_repository import reset_machine_repository from .set_agent_configuration_per_island_mode import set_agent_configuration_per_island_mode -from .set_simulation_mode import set_simulation_mode diff --git a/monkey/monkey_island/cc/setup/island_event_handlers.py b/monkey/monkey_island/cc/setup/island_event_handlers.py index 46429f292..ee37568f1 100644 --- a/monkey/monkey_island/cc/setup/island_event_handlers.py +++ b/monkey/monkey_island/cc/setup/island_event_handlers.py @@ -6,13 +6,13 @@ from monkey_island.cc.island_event_handlers import ( reset_agent_configuration, reset_machine_repository, set_agent_configuration_per_island_mode, - set_simulation_mode, ) from monkey_island.cc.repository import ( IAgentEventRepository, IAgentRepository, ICredentialsRepository, INodeRepository, + ISimulationRepository, ) from monkey_island.cc.services.database import Database @@ -62,4 +62,5 @@ def _subscribe_set_island_mode_events( island_event_queue.subscribe(topic, container.resolve(set_agent_configuration_per_island_mode)) - island_event_queue.subscribe(topic, container.resolve(set_simulation_mode)) + simulation_repository = container.resolve(ISimulationRepository) + island_event_queue.subscribe(topic, simulation_repository.set_mode) From 10e1177ef6b8c1a8cb9b14d41b3a8c9801de1bd7 Mon Sep 17 00:00:00 2001 From: Shreya Malviya Date: Wed, 21 Sep 2022 18:02:42 +0530 Subject: [PATCH 18/21] Island: Remove set_simulation_mode --- .../set_simulation_mode.py | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 monkey/monkey_island/cc/island_event_handlers/set_simulation_mode.py diff --git a/monkey/monkey_island/cc/island_event_handlers/set_simulation_mode.py b/monkey/monkey_island/cc/island_event_handlers/set_simulation_mode.py deleted file mode 100644 index da15a8ac0..000000000 --- a/monkey/monkey_island/cc/island_event_handlers/set_simulation_mode.py +++ /dev/null @@ -1,17 +0,0 @@ -from monkey_island.cc.models import IslandMode -from monkey_island.cc.repository import ISimulationRepository - - -class set_simulation_mode: - """ - Callable class that sets the Island's mode - """ - - def __init__( - self, - simulation_repository: ISimulationRepository, - ): - self._simulation_repository = simulation_repository - - def __call__(self, mode: IslandMode): - self._simulation_repository.set_mode(mode) From 1afafd20dd20da85e10f4c24319d6ab3c1eb6e28 Mon Sep 17 00:00:00 2001 From: Shreya Malviya Date: Wed, 21 Sep 2022 18:09:13 +0530 Subject: [PATCH 19/21] UT: Simplify some logic in test_island_mode.py's flask_client fixture --- .../monkey_island/cc/resources/test_island_mode.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/monkey/tests/unit_tests/monkey_island/cc/resources/test_island_mode.py b/monkey/tests/unit_tests/monkey_island/cc/resources/test_island_mode.py index 1386bb6c7..0b9403362 100644 --- a/monkey/tests/unit_tests/monkey_island/cc/resources/test_island_mode.py +++ b/monkey/tests/unit_tests/monkey_island/cc/resources/test_island_mode.py @@ -18,12 +18,10 @@ def flask_client(build_flask_client): in_memory_simulation_repository = InMemorySimulationRepository() container.register_instance(ISimulationRepository, in_memory_simulation_repository) - def wrap_in_memory_simulation_repository_set_mode(topic, event): - mode = event - in_memory_simulation_repository.set_mode(mode) - mock_island_event_queue = MagicMock(spec=IIslandEventQueue) - mock_island_event_queue.publish.side_effect = wrap_in_memory_simulation_repository_set_mode + mock_island_event_queue.publish.side_effect = ( + lambda topic, mode: in_memory_simulation_repository.set_mode(mode) + ) container.register_instance(IIslandEventQueue, mock_island_event_queue) with build_flask_client(container) as flask_client: From 60db495cee63a22426c922ce52389e46f9d32041 Mon Sep 17 00:00:00 2001 From: Shreya Malviya Date: Wed, 21 Sep 2022 18:43:26 +0530 Subject: [PATCH 20/21] UT: Use MagicMock to simulate internal server error in test_island_mode_post__invalid_mode() --- .../monkey_island/cc/resources/test_island_mode.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/monkey/tests/unit_tests/monkey_island/cc/resources/test_island_mode.py b/monkey/tests/unit_tests/monkey_island/cc/resources/test_island_mode.py index 0b9403362..7d48e3b2f 100644 --- a/monkey/tests/unit_tests/monkey_island/cc/resources/test_island_mode.py +++ b/monkey/tests/unit_tests/monkey_island/cc/resources/test_island_mode.py @@ -52,6 +52,12 @@ def test_island_mode_post__invalid_mode(flask_client): def test_island_mode_post__internal_server_error(build_flask_client): container = StubDIContainer() + in_memory_simulation_repository = InMemorySimulationRepository() + container.register_instance(ISimulationRepository, in_memory_simulation_repository) + + mock_island_event_queue = MagicMock(spec=IIslandEventQueue) + mock_island_event_queue.publish.side_effect = Exception + container.register_instance(IIslandEventQueue, mock_island_event_queue) with build_flask_client(container) as flask_client: resp = flask_client.put( From a8fb05f2b8f97b7503fc433c1e4ab3a30169ceba Mon Sep 17 00:00:00 2001 From: Shreya Malviya Date: Wed, 21 Sep 2022 18:53:12 +0530 Subject: [PATCH 21/21] Island: Simplify logic in test_island_mode.py with fixtures --- .../cc/resources/test_island_mode.py | 59 ++++++++++--------- 1 file changed, 32 insertions(+), 27 deletions(-) diff --git a/monkey/tests/unit_tests/monkey_island/cc/resources/test_island_mode.py b/monkey/tests/unit_tests/monkey_island/cc/resources/test_island_mode.py index 7d48e3b2f..ad099cd9c 100644 --- a/monkey/tests/unit_tests/monkey_island/cc/resources/test_island_mode.py +++ b/monkey/tests/unit_tests/monkey_island/cc/resources/test_island_mode.py @@ -12,20 +12,35 @@ from monkey_island.cc.resources.island_mode import IslandMode as IslandModeResou @pytest.fixture -def flask_client(build_flask_client): - container = StubDIContainer() +def flask_client_builder(build_flask_client): + def inner(side_effect=None): + container = StubDIContainer() - in_memory_simulation_repository = InMemorySimulationRepository() - container.register_instance(ISimulationRepository, in_memory_simulation_repository) + in_memory_simulation_repository = InMemorySimulationRepository() + container.register_instance(ISimulationRepository, in_memory_simulation_repository) - mock_island_event_queue = MagicMock(spec=IIslandEventQueue) - mock_island_event_queue.publish.side_effect = ( - lambda topic, mode: in_memory_simulation_repository.set_mode(mode) - ) - container.register_instance(IIslandEventQueue, mock_island_event_queue) + mock_island_event_queue = MagicMock(spec=IIslandEventQueue) + mock_island_event_queue.publish.side_effect = ( + side_effect + if side_effect + else lambda topic, mode: in_memory_simulation_repository.set_mode(mode) + ) + container.register_instance(IIslandEventQueue, mock_island_event_queue) - with build_flask_client(container) as flask_client: - yield flask_client + with build_flask_client(container) as flask_client: + return flask_client + + return inner + + +@pytest.fixture +def flask_client(flask_client_builder): + return flask_client_builder() + + +@pytest.fixture +def flask_client__internal_server_error(flask_client_builder): + return flask_client_builder(Exception) @pytest.mark.parametrize( @@ -50,22 +65,12 @@ def test_island_mode_post__invalid_mode(flask_client): assert resp.status_code == HTTPStatus.UNPROCESSABLE_ENTITY -def test_island_mode_post__internal_server_error(build_flask_client): - container = StubDIContainer() - in_memory_simulation_repository = InMemorySimulationRepository() - container.register_instance(ISimulationRepository, in_memory_simulation_repository) - - mock_island_event_queue = MagicMock(spec=IIslandEventQueue) - mock_island_event_queue.publish.side_effect = Exception - container.register_instance(IIslandEventQueue, mock_island_event_queue) - - with build_flask_client(container) as flask_client: - resp = flask_client.put( - IslandModeResource.urls[0], - json=IslandMode.RANSOMWARE.value, - follow_redirects=True, - ) - +def test_island_mode_post__internal_server_error(flask_client__internal_server_error): + resp = flask_client__internal_server_error.put( + IslandModeResource.urls[0], + json=IslandMode.RANSOMWARE.value, + follow_redirects=True, + ) assert resp.status_code == HTTPStatus.INTERNAL_SERVER_ERROR