diff --git a/monkey/infection_monkey/config.py b/monkey/infection_monkey/config.py index d00d55814..f7ec13af6 100644 --- a/monkey/infection_monkey/config.py +++ b/monkey/infection_monkey/config.py @@ -193,7 +193,11 @@ class Configuration(object): ms08_067_exploit_attempts = 5 user_to_add = "Monkey_IUSER_SUPPORT" - # User and password dictionaries for exploits. + ########################### + # ransomware config + ########################### + + ransomware = "" def get_exploit_user_password_pairs(self): """ diff --git a/monkey/infection_monkey/monkey.py b/monkey/infection_monkey/monkey.py index 7e188b74d..abd0b3f18 100644 --- a/monkey/infection_monkey/monkey.py +++ b/monkey/infection_monkey/monkey.py @@ -19,6 +19,7 @@ from infection_monkey.network.HostFinger import HostFinger from infection_monkey.network.network_scanner import NetworkScanner from infection_monkey.network.tools import get_interface_to_target, is_running_on_island from infection_monkey.post_breach.post_breach_handler import PostBreach +from infection_monkey.ransomware.ransomware_payload import RansomewarePayload from infection_monkey.system_info import SystemInfoCollector from infection_monkey.system_singleton import SystemSingleton from infection_monkey.telemetry.attack.t1106_telem import T1106Telem @@ -232,6 +233,8 @@ class InfectionMonkey(object): if not self._keep_running: break + RansomewarePayload(WormConfiguration.ransomware).run_payload() + if (not is_empty) and (WormConfiguration.max_iterations > iteration_index + 1): time_to_sleep = WormConfiguration.timeout_between_iterations LOG.info("Sleeping %d seconds before next life cycle iteration", time_to_sleep) diff --git a/monkey/infection_monkey/ransomware/ransomware_payload.py b/monkey/infection_monkey/ransomware/ransomware_payload.py new file mode 100644 index 000000000..941055062 --- /dev/null +++ b/monkey/infection_monkey/ransomware/ransomware_payload.py @@ -0,0 +1,27 @@ +import logging + +LOG = logging.getLogger(__name__) + + +class RansomewarePayload: + def __init__(self, config: dict): + self.config = config + + def run_payload(self): + LOG.info( + f"Windows dir configured for encryption is " f"{self.config['windows_dir_ransom']}" + ) + LOG.info(f"Linux dir configured for encryption is " f"{self.config['linux_dir_ransom']}") + + file_list = self._find_files() + self._encrypt_files(file_list) + + def _find_files(self): + return [] + + def _encrypt_files(self, file_list): + for file in file_list: + self._encrypt_file(file) + + def _encrypt_file(self, file): + pass diff --git a/monkey/monkey_island/cc/services/config.py b/monkey/monkey_island/cc/services/config.py index 7c7429756..acb12d48a 100644 --- a/monkey/monkey_island/cc/services/config.py +++ b/monkey/monkey_island/cc/services/config.py @@ -106,6 +106,10 @@ class ConfigService: config_json = ConfigService.get_config(is_initial_config, should_decrypt) flat_config_json = {} for i in config_json: + if i == "ransomware": + # Don't flatten the ransomware because ransomware payload expects a dictionary #1260 + flat_config_json[i] = config_json[i] + continue for j in config_json[i]: for k in config_json[i][j]: if isinstance(config_json[i][j][k], dict): diff --git a/monkey/monkey_island/cc/services/config_schema/config_schema.py b/monkey/monkey_island/cc/services/config_schema/config_schema.py index 3900b0675..fb1e35b45 100644 --- a/monkey/monkey_island/cc/services/config_schema/config_schema.py +++ b/monkey/monkey_island/cc/services/config_schema/config_schema.py @@ -10,6 +10,7 @@ from monkey_island.cc.services.config_schema.definitions.system_info_collector_c ) from monkey_island.cc.services.config_schema.internal import INTERNAL from monkey_island.cc.services.config_schema.monkey import MONKEY +from monkey_island.cc.services.config_schema.ransomware import RANSOMWARE SCHEMA = { "title": "Monkey", @@ -27,6 +28,7 @@ SCHEMA = { "basic": BASIC, "basic_network": BASIC_NETWORK, "monkey": MONKEY, + "ransomware": RANSOMWARE, "internal": INTERNAL, }, "options": {"collapsed": True}, diff --git a/monkey/monkey_island/cc/services/config_schema/ransomware.py b/monkey/monkey_island/cc/services/config_schema/ransomware.py new file mode 100644 index 000000000..74b5d3d67 --- /dev/null +++ b/monkey/monkey_island/cc/services/config_schema/ransomware.py @@ -0,0 +1,26 @@ +RANSOMWARE = { + "title": "Ransomware", + "type": "object", + "properties": { + "directories": { + "title": "Directories to encrypt", + "type": "object", + "properties": { + "linux_dir": { + "title": "Linux encryptable directory", + "type": "string", + "default": "", + "description": "Files in the specified directory will be encrypted " + "using bitflip to simulate ransomware.", + }, + "windows_dir": { + "title": "Windows encryptable directory", + "type": "string", + "default": "", + "description": "Files in the specified directory will be encrypted " + "using bitflip to simulate ransomware.", + }, + }, + } + }, +} diff --git a/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js b/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js index c6e27f476..ed827401b 100644 --- a/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js +++ b/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js @@ -30,7 +30,7 @@ class ConfigurePageComponent extends AuthComponent { this.currentFormData = {}; this.initialConfig = {}; this.initialAttackConfig = {}; - this.sectionsOrder = ['attack', 'basic', 'basic_network', 'monkey', 'internal']; + this.sectionsOrder = ['attack', 'basic', 'basic_network', 'ransomware', 'monkey', 'internal']; this.state = { attackConfig: {},