From d1efa1a790260c23ca56a6fa8ddb635be26a0eb1 Mon Sep 17 00:00:00 2001 From: Ilija Lazoroski Date: Wed, 3 Aug 2022 16:50:31 +0200 Subject: [PATCH 1/9] Common: Strip out newline in version --- monkey/common/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monkey/common/version.py b/monkey/common/version.py index 67060ae2f..e5b63dc73 100644 --- a/monkey/common/version.py +++ b/monkey/common/version.py @@ -9,7 +9,7 @@ PATCH = "0" build_file_path = Path(__file__).parent.joinpath("BUILD") with open(build_file_path, "r") as build_file: - BUILD = build_file.read() + BUILD = build_file.read().strip() def get_version(build=BUILD): From 133bf757740d10b856395e459ae4c958bbd4a4c7 Mon Sep 17 00:00:00 2001 From: Ilija Lazoroski Date: Wed, 3 Aug 2022 17:00:08 +0200 Subject: [PATCH 2/9] Island: Register deployment convention --- monkey/monkey_island/cc/services/initialize.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/monkey/monkey_island/cc/services/initialize.py b/monkey/monkey_island/cc/services/initialize.py index 2d2678ac3..7bb1063be 100644 --- a/monkey/monkey_island/cc/services/initialize.py +++ b/monkey/monkey_island/cc/services/initialize.py @@ -1,3 +1,4 @@ +import json import logging from pathlib import Path @@ -33,6 +34,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.server_utils.island_logger import get_log_file_path +from monkey_island.cc.deployment import Deployment from monkey_island.cc.services import AWSService, IslandModeService, RepositoryService from monkey_island.cc.services.attack.technique_reports.T1003 import T1003, T1003GetReportData from monkey_island.cc.services.run_local_monkey import LocalMonkeyRunService @@ -50,6 +52,7 @@ from .reporting.report import ReportService logger = logging.getLogger(__name__) AGENT_BINARIES_PATH = Path(MONKEY_ISLAND_ABS_PATH) / "cc" / "binaries" +DEPLOYMENT_FILE_PATH = Path(MONKEY_ISLAND_ABS_PATH) / "cc" / "deployment.json" REPOSITORY_KEY_FILE_NAME = "repository_key.bin" @@ -89,6 +92,7 @@ def _register_conventions(container: DIContainer, data_dir: Path): DEFAULT_RANSOMWARE_AGENT_CONFIGURATION, ) container.register_convention(Path, "island_log_file_path", get_log_file_path(data_dir)) + container.register_convention(Deployment, "deployment", _get_depyloyment_from_file(DEPLOYMENT_FILE_PATH)) def _register_repositories(container: DIContainer, data_dir: Path): @@ -145,6 +149,20 @@ def _log_agent_binary_hashes(agent_binary_repository: IAgentBinaryRepository): for os, binary_sha256_hash in agent_hashes.items(): logger.info(f"{os} agent: SHA-256 hash: {binary_sha256_hash}") +def _get_depyloyment_from_file(file_path: Path) -> Deployment: + try: + with open(file_path, "r") as deployment_info_file: + deployment_info = json.load(deployment_info_file) + return Deployment[deployment_info["deployment"].upper()] + except FileNotFoundError as ex: + logger.debug(f"Deployment file {file_path} is not found. Exception: {ex}") + except KeyError as ex: + logger.debug(f"Invalid key in the deployment file. Exception: {ex}") + except json.JSONDecodeError as ex: + logger.debug(f"Invalid deployment info file. Exception: {ex}") + except Exception as ex: + logger.debug(f"Couldn't get deployment info from {file_path}. Exception: {ex}.") + def _register_services(container: DIContainer): container.register_instance(AWSService, container.resolve(AWSService)) From 682e52c38f5fc4ccff0568ddb850812dc608c486 Mon Sep 17 00:00:00 2001 From: Ilija Lazoroski Date: Wed, 3 Aug 2022 17:01:14 +0200 Subject: [PATCH 3/9] Island: Register version_number convetnion --- monkey/monkey_island/cc/services/initialize.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/monkey/monkey_island/cc/services/initialize.py b/monkey/monkey_island/cc/services/initialize.py index 7bb1063be..114a1b8c9 100644 --- a/monkey/monkey_island/cc/services/initialize.py +++ b/monkey/monkey_island/cc/services/initialize.py @@ -13,6 +13,7 @@ from common.agent_configuration import ( from common.aws import AWSInstance from common.common_consts.telem_categories import TelemCategoryEnum from common.utils.file_utils import get_binary_io_sha256_hash +from common.version import get_version from monkey_island.cc.repository import ( AgentBinaryRepository, FileAgentConfigurationRepository, @@ -93,6 +94,7 @@ def _register_conventions(container: DIContainer, data_dir: Path): ) container.register_convention(Path, "island_log_file_path", get_log_file_path(data_dir)) container.register_convention(Deployment, "deployment", _get_depyloyment_from_file(DEPLOYMENT_FILE_PATH)) + container.register_convention(str, "version_number", get_version()) def _register_repositories(container: DIContainer, data_dir: Path): From fb12c777a6b3be812fc01fd5d6d1df836f1c8f17 Mon Sep 17 00:00:00 2001 From: Ilija Lazoroski Date: Wed, 3 Aug 2022 17:01:52 +0200 Subject: [PATCH 4/9] Island: Register Version instance --- monkey/monkey_island/cc/services/initialize.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/monkey/monkey_island/cc/services/initialize.py b/monkey/monkey_island/cc/services/initialize.py index 114a1b8c9..2ff9963a8 100644 --- a/monkey/monkey_island/cc/services/initialize.py +++ b/monkey/monkey_island/cc/services/initialize.py @@ -14,6 +14,7 @@ from common.aws import AWSInstance from common.common_consts.telem_categories import TelemCategoryEnum from common.utils.file_utils import get_binary_io_sha256_hash from common.version import get_version +from monkey_island.cc.deployment import Deployment from monkey_island.cc.repository import ( AgentBinaryRepository, FileAgentConfigurationRepository, @@ -35,7 +36,6 @@ 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.server_utils.island_logger import get_log_file_path -from monkey_island.cc.deployment import Deployment from monkey_island.cc.services import AWSService, IslandModeService, RepositoryService from monkey_island.cc.services.attack.technique_reports.T1003 import T1003, T1003GetReportData from monkey_island.cc.services.run_local_monkey import LocalMonkeyRunService @@ -46,6 +46,7 @@ from monkey_island.cc.services.telemetry.processing.processing import ( TELEMETRY_CATEGORY_TO_PROCESSING_FUNC, ) from monkey_island.cc.setup.mongo.mongo_setup import MONGO_URL +from monkey_island.cc.version import Version from . import AuthenticationService from .reporting.report import ReportService @@ -66,7 +67,7 @@ def initialize_services(data_dir: Path) -> DIContainer: container.register_instance( ILockableEncryptor, RepositoryEncryptor(data_dir / REPOSITORY_KEY_FILE_NAME) ) - + container.register_instance(Version, container.resolve(Version)) _register_repositories(container, data_dir) _register_services(container) @@ -93,7 +94,9 @@ def _register_conventions(container: DIContainer, data_dir: Path): DEFAULT_RANSOMWARE_AGENT_CONFIGURATION, ) container.register_convention(Path, "island_log_file_path", get_log_file_path(data_dir)) - container.register_convention(Deployment, "deployment", _get_depyloyment_from_file(DEPLOYMENT_FILE_PATH)) + container.register_convention( + Deployment, "deployment", _get_depyloyment_from_file(DEPLOYMENT_FILE_PATH) + ) container.register_convention(str, "version_number", get_version()) @@ -151,6 +154,7 @@ def _log_agent_binary_hashes(agent_binary_repository: IAgentBinaryRepository): for os, binary_sha256_hash in agent_hashes.items(): logger.info(f"{os} agent: SHA-256 hash: {binary_sha256_hash}") + def _get_depyloyment_from_file(file_path: Path) -> Deployment: try: with open(file_path, "r") as deployment_info_file: From 6feb261254d08919b94a602e9de022bf23bba5ce Mon Sep 17 00:00:00 2001 From: Ilija Lazoroski Date: Wed, 3 Aug 2022 17:04:39 +0200 Subject: [PATCH 5/9] Island: Use Version object in Version endpoint --- monkey/monkey_island/cc/resources/version.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/monkey/monkey_island/cc/resources/version.py b/monkey/monkey_island/cc/resources/version.py index 961b1175d..1513a0c99 100644 --- a/monkey/monkey_island/cc/resources/version.py +++ b/monkey/monkey_island/cc/resources/version.py @@ -1,8 +1,7 @@ import logging -from common.version import get_version from monkey_island.cc.resources.AbstractResource import AbstractResource -from monkey_island.cc.services.version_update import VersionUpdateService +from monkey_island.cc.version import Version logger = logging.getLogger(__name__) @@ -10,14 +9,14 @@ logger = logging.getLogger(__name__) class Version(AbstractResource): urls = ["/api/island/version"] - def __init__(self): - super(Version, self).__init__() + def __init__(self, version: Version): + self._version = version # We don't secure this since it doesn't give out any private info and we want UI to know version # even when not authenticated def get(self): return { - "current_version": get_version(), - "newer_version": VersionUpdateService.get_newer_version(), - "download_link": VersionUpdateService.get_download_link(), + "current_version": self._version.version_number, + "newer_version": self._version.latest_version, + "download_link": self._version.download_url, } From 582bc46f8ca99e977f0ab2614117d2acef99bdb3 Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Wed, 3 Aug 2022 13:24:30 -0400 Subject: [PATCH 6/9] Island: Rename keys in Version resource --- monkey/monkey_island/cc/resources/version.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/monkey/monkey_island/cc/resources/version.py b/monkey/monkey_island/cc/resources/version.py index 1513a0c99..ffd42dd94 100644 --- a/monkey/monkey_island/cc/resources/version.py +++ b/monkey/monkey_island/cc/resources/version.py @@ -16,7 +16,7 @@ class Version(AbstractResource): # even when not authenticated def get(self): return { - "current_version": self._version.version_number, - "newer_version": self._version.latest_version, + "version_number": self._version.version_number, + "latest_version": self._version.latest_version, "download_link": self._version.download_url, } From 449207876fb7ee02fc379f96e0f9cfe2c6342aa4 Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Wed, 3 Aug 2022 13:33:29 -0400 Subject: [PATCH 7/9] Island: Register Deployment as instance, not convention --- monkey/monkey_island/cc/services/initialize.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/monkey/monkey_island/cc/services/initialize.py b/monkey/monkey_island/cc/services/initialize.py index 2ff9963a8..cbc4262b2 100644 --- a/monkey/monkey_island/cc/services/initialize.py +++ b/monkey/monkey_island/cc/services/initialize.py @@ -62,6 +62,7 @@ def initialize_services(data_dir: Path) -> DIContainer: container = DIContainer() _register_conventions(container, data_dir) + container.register_instance(Deployment, _get_depyloyment_from_file(DEPLOYMENT_FILE_PATH)) container.register_instance(AWSInstance, AWSInstance()) container.register_instance(MongoClient, MongoClient(MONGO_URL, serverSelectionTimeoutMS=100)) container.register_instance( @@ -94,9 +95,6 @@ def _register_conventions(container: DIContainer, data_dir: Path): DEFAULT_RANSOMWARE_AGENT_CONFIGURATION, ) container.register_convention(Path, "island_log_file_path", get_log_file_path(data_dir)) - container.register_convention( - Deployment, "deployment", _get_depyloyment_from_file(DEPLOYMENT_FILE_PATH) - ) container.register_convention(str, "version_number", get_version()) From 833e3b82bcda2889ed87621f52fd3435b6925267 Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Wed, 3 Aug 2022 14:24:46 -0400 Subject: [PATCH 8/9] Island: Crash if deployment cannot be determined --- monkey/monkey_island/cc/services/initialize.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/monkey/monkey_island/cc/services/initialize.py b/monkey/monkey_island/cc/services/initialize.py index cbc4262b2..e83ce4441 100644 --- a/monkey/monkey_island/cc/services/initialize.py +++ b/monkey/monkey_island/cc/services/initialize.py @@ -158,14 +158,13 @@ def _get_depyloyment_from_file(file_path: Path) -> Deployment: with open(file_path, "r") as deployment_info_file: deployment_info = json.load(deployment_info_file) return Deployment[deployment_info["deployment"].upper()] - except FileNotFoundError as ex: - logger.debug(f"Deployment file {file_path} is not found. Exception: {ex}") - except KeyError as ex: - logger.debug(f"Invalid key in the deployment file. Exception: {ex}") - except json.JSONDecodeError as ex: - logger.debug(f"Invalid deployment info file. Exception: {ex}") - except Exception as ex: - logger.debug(f"Couldn't get deployment info from {file_path}. Exception: {ex}.") + except KeyError as err: + raise Exception( + f"The deployment file ({file_path}) did not contain the expected data: " + f"missing key {err}" + ) + except Exception as err: + raise Exception(f"Failed to fetch the deployment from {file_path}: {err}") def _register_services(container: DIContainer): From 78356ec7e15dc95458d6ab7ff97f787f025eea13 Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Wed, 3 Aug 2022 14:34:28 -0400 Subject: [PATCH 9/9] Island: Add TODO about Deployment and initialize_services() --- monkey/monkey_island/cc/services/initialize.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/monkey/monkey_island/cc/services/initialize.py b/monkey/monkey_island/cc/services/initialize.py index e83ce4441..f8056cebc 100644 --- a/monkey/monkey_island/cc/services/initialize.py +++ b/monkey/monkey_island/cc/services/initialize.py @@ -153,6 +153,8 @@ def _log_agent_binary_hashes(agent_binary_repository: IAgentBinaryRepository): logger.info(f"{os} agent: SHA-256 hash: {binary_sha256_hash}") +# TODO: The deployment should probably be passed into initialize_services(), but we can rework that +# when we refactor this file. def _get_depyloyment_from_file(file_path: Path) -> Deployment: try: with open(file_path, "r") as deployment_info_file: