From 2c96ace9083848c582730cc0d0e4bec926c85d62 Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Wed, 22 Jul 2020 18:06:49 +0300 Subject: [PATCH] Mimikatz, Azure collectors moved to system info collectors in config, "Behaviour" renamed to "Post breach" in config --- .../data/system_info_collectors_names.py | 2 + monkey/infection_monkey/config.py | 10 --- monkey/infection_monkey/monkey.py | 15 ++-- .../infection_monkey/system_info/__init__.py | 3 +- .../system_info/windows_info_collector.py | 3 +- .../system_info_collector_classes.py | 30 +++++-- .../cc/services/config_schema/internal.py | 24 ++++++ .../cc/services/config_schema/monkey.py | 82 +++++-------------- .../cc/services/post_breach_files.py | 8 +- .../configuration-components/UiSchema.js | 2 +- .../ui/src/components/pages/ConfigurePage.js | 8 +- 11 files changed, 94 insertions(+), 93 deletions(-) diff --git a/monkey/common/data/system_info_collectors_names.py b/monkey/common/data/system_info_collectors_names.py index 831bbe142..175a054e1 100644 --- a/monkey/common/data/system_info_collectors_names.py +++ b/monkey/common/data/system_info_collectors_names.py @@ -2,3 +2,5 @@ AWS_COLLECTOR = "AwsCollector" HOSTNAME_COLLECTOR = "HostnameCollector" ENVIRONMENT_COLLECTOR = "EnvironmentCollector" PROCESS_LIST_COLLECTOR = "ProcessListCollector" +MIMIKATZ_COLLECTOR = "MimikatzCollector" +AZURE_CRED_COLLECTOR = "AzureCollector" diff --git a/monkey/infection_monkey/config.py b/monkey/infection_monkey/config.py index 0413bdcd3..b87ef9ed8 100644 --- a/monkey/infection_monkey/config.py +++ b/monkey/infection_monkey/config.py @@ -267,16 +267,6 @@ class Configuration(object): # Shares to not check if they're writable. sambacry_shares_not_to_check = ["IPC$", "print$"] - # system info collection - collect_system_info = True - should_use_mimikatz = True - - ########################### - # systeminfo config - ########################### - - extract_azure_creds = True - ########################### # post breach actions ########################### diff --git a/monkey/infection_monkey/monkey.py b/monkey/infection_monkey/monkey.py index e01338a48..444bde452 100644 --- a/monkey/infection_monkey/monkey.py +++ b/monkey/infection_monkey/monkey.py @@ -190,7 +190,8 @@ class InfectionMonkey(object): 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 '')) + ( + ':' + self._default_server_port if self._default_server_port else '')) else: machine.set_default_server(self._default_server) LOG.debug("Default server for machine: %r set to %s" % (machine, machine.default_server)) @@ -241,11 +242,10 @@ class InfectionMonkey(object): LOG.debug("Running with depth: %d" % WormConfiguration.depth) def collect_system_info_if_configured(self): - if WormConfiguration.collect_system_info: - LOG.debug("Calling system info collection") - system_info_collector = SystemInfoCollector() - system_info = system_info_collector.get_info() - SystemInfoTelem(system_info).send() + LOG.debug("Calling system info collection") + system_info_collector = SystemInfoCollector() + system_info = system_info_collector.get_info() + SystemInfoTelem(system_info).send() def shutdown_by_not_alive_config(self): if not WormConfiguration.alive: @@ -386,7 +386,8 @@ class InfectionMonkey(object): :raises PlannedShutdownException if couldn't find the server. """ if not ControlClient.find_server(default_tunnel=self._default_tunnel): - raise PlannedShutdownException("Monkey couldn't find server with {} default tunnel.".format(self._default_tunnel)) + raise PlannedShutdownException( + "Monkey couldn't find server with {} default tunnel.".format(self._default_tunnel)) self._default_server = WormConfiguration.current_server LOG.debug("default server set to: %s" % self._default_server) diff --git a/monkey/infection_monkey/system_info/__init__.py b/monkey/infection_monkey/system_info/__init__.py index 7761a412b..05bb3a4d0 100644 --- a/monkey/infection_monkey/system_info/__init__.py +++ b/monkey/infection_monkey/system_info/__init__.py @@ -4,6 +4,7 @@ from enum import IntEnum import psutil +from common.data.system_info_collectors_names import AZURE_CRED_COLLECTOR from infection_monkey.network.info import get_host_subnets from infection_monkey.system_info.azure_cred_collector import AzureCollector from infection_monkey.system_info.netstat_collector import NetstatCollector @@ -91,7 +92,7 @@ class InfoCollector(object): # noinspection PyBroadException try: from infection_monkey.config import WormConfiguration - if not WormConfiguration.extract_azure_creds: + if AZURE_CRED_COLLECTOR not in WormConfiguration.system_info_collector_classes: return LOG.debug("Harvesting creds if on an Azure machine") azure_collector = AzureCollector() diff --git a/monkey/infection_monkey/system_info/windows_info_collector.py b/monkey/infection_monkey/system_info/windows_info_collector.py index 7eb80377d..d6b3cbec8 100644 --- a/monkey/infection_monkey/system_info/windows_info_collector.py +++ b/monkey/infection_monkey/system_info/windows_info_collector.py @@ -2,6 +2,7 @@ import logging import os import sys +from common.data.system_info_collectors_names import MIMIKATZ_COLLECTOR from infection_monkey.system_info.windows_cred_collector.mimikatz_cred_collector import \ MimikatzCredentialCollector @@ -44,7 +45,7 @@ class WindowsInfoCollector(InfoCollector): # TODO: Think about returning self.get_wmi_info() self.get_installed_packages() from infection_monkey.config import WormConfiguration - if WormConfiguration.should_use_mimikatz: + if MIMIKATZ_COLLECTOR in WormConfiguration.system_info_collector_classes: self.get_mimikatz_info() return self.info diff --git a/monkey/monkey_island/cc/services/config_schema/definitions/system_info_collector_classes.py b/monkey/monkey_island/cc/services/config_schema/definitions/system_info_collector_classes.py index c77b77b7c..8b960d1d8 100644 --- a/monkey/monkey_island/cc/services/config_schema/definitions/system_info_collector_classes.py +++ b/monkey/monkey_island/cc/services/config_schema/definitions/system_info_collector_classes.py @@ -1,7 +1,9 @@ from common.data.system_info_collectors_names import (AWS_COLLECTOR, ENVIRONMENT_COLLECTOR, HOSTNAME_COLLECTOR, - PROCESS_LIST_COLLECTOR) + PROCESS_LIST_COLLECTOR, + MIMIKATZ_COLLECTOR, + AZURE_CRED_COLLECTOR) SYSTEM_INFO_COLLECTOR_CLASSES = { "title": "System Information Collectors", @@ -15,7 +17,16 @@ SYSTEM_INFO_COLLECTOR_CLASSES = { ], "title": "Environment collector", "info": "Collects information about machine's environment (on premise/GCP/AWS).", - "attack_techniques": [] + "attack_techniques": ["T1082"] + }, + { + "type": "string", + "enum": [ + MIMIKATZ_COLLECTOR + ], + "title": "Mimikatz collector", + "info": "Collects credentials from Windows credential manager.", + "attack_techniques": ["T1003", "T1005"] }, { "type": "string", @@ -24,7 +35,7 @@ SYSTEM_INFO_COLLECTOR_CLASSES = { ], "title": "AWS collector", "info": "If on AWS, collects more information about the AWS instance currently running on.", - "attack_techniques": [] + "attack_techniques": ["T1082"] }, { "type": "string", @@ -33,7 +44,7 @@ SYSTEM_INFO_COLLECTOR_CLASSES = { ], "title": "Hostname collector", "info": "Collects machine's hostname.", - "attack_techniques": [] + "attack_techniques": ["T1082", "T1016"] }, { "type": "string", @@ -42,7 +53,16 @@ SYSTEM_INFO_COLLECTOR_CLASSES = { ], "title": "Process list collector", "info": "Collects a list of running processes on the machine.", - "attack_techniques": [] + "attack_techniques": ["T1082"] }, + { + "type": "string", + "enum": [ + AZURE_CRED_COLLECTOR + ], + "title": "Azure credential collector", + "info": "Collects password credentials from Azure VMs", + "attack_techniques": ["T1003", "T1005"] + } ] } diff --git a/monkey/monkey_island/cc/services/config_schema/internal.py b/monkey/monkey_island/cc/services/config_schema/internal.py index 755347538..b84137024 100644 --- a/monkey/monkey_island/cc/services/config_schema/internal.py +++ b/monkey/monkey_island/cc/services/config_schema/internal.py @@ -34,6 +34,30 @@ INTERNAL = { }, } }, + "monkey": { + "title": "Monkey", + "type": "object", + "properties": { + "self_delete_in_cleanup": { + "title": "Self delete on cleanup", + "type": "boolean", + "default": True, + "description": "Should the monkey delete its executable when going down" + }, + "use_file_logging": { + "title": "Use file logging", + "type": "boolean", + "default": True, + "description": "Should the monkey dump to a log file" + }, + "serialize_config": { + "title": "Serialize config", + "type": "boolean", + "default": False, + "description": "Should the monkey dump its config on startup" + } + } + }, "classes": { "title": "Classes", "type": "object", diff --git a/monkey/monkey_island/cc/services/config_schema/monkey.py b/monkey/monkey_island/cc/services/config_schema/monkey.py index 924a077d0..92f8d3cc1 100644 --- a/monkey/monkey_island/cc/services/config_schema/monkey.py +++ b/monkey/monkey_island/cc/services/config_schema/monkey.py @@ -2,7 +2,7 @@ from monkey_island.cc.services.utils.typographic_symbols import WARNING_SIGN from common.data.system_info_collectors_names import (AWS_COLLECTOR, ENVIRONMENT_COLLECTOR, HOSTNAME_COLLECTOR, - PROCESS_LIST_COLLECTOR) + PROCESS_LIST_COLLECTOR, MIMIKATZ_COLLECTOR, AZURE_CRED_COLLECTOR) MONKEY = { "title": "Monkey", @@ -18,27 +18,10 @@ MONKEY = { "default": True, "description": "Is the monkey alive" }, - "post_breach_actions": { - "title": "Post breach actions", - "type": "array", - "uniqueItems": True, - "items": { - "$ref": "#/definitions/post_breach_actions" - }, - "default": [ - "BackdoorUser", - "CommunicateAsNewUser", - "ModifyShellStartupFiles", - "HiddenFiles", - "TrapCommand", - "ChangeSetuidSetgid", - "ScheduleJobs" - ] - }, } }, - "behaviour": { - "title": "Behaviour", + "post_breach": { + "title": "Post breach", "type": "object", "properties": { "custom_PBA_linux_cmd": { @@ -81,52 +64,29 @@ MONKEY = { "type": "string", "default": "" }, - "self_delete_in_cleanup": { - "title": "Self delete on cleanup", - "type": "boolean", - "default": True, - "description": "Should the monkey delete its executable when going down" + "post_breach_actions": { + "title": "Post breach actions", + "type": "array", + "uniqueItems": True, + "items": { + "$ref": "#/definitions/post_breach_actions" + }, + "default": [ + "BackdoorUser", + "CommunicateAsNewUser", + "ModifyShellStartupFiles", + "HiddenFiles", + "TrapCommand", + "ChangeSetuidSetgid", + "ScheduleJobs" + ] }, - "use_file_logging": { - "title": "Use file logging", - "type": "boolean", - "default": True, - "description": "Should the monkey dump to a log file" - }, - "serialize_config": { - "title": "Serialize config", - "type": "boolean", - "default": False, - "description": "Should the monkey dump its config on startup" - } } }, "system_info": { "title": "System info", "type": "object", "properties": { - "extract_azure_creds": { - "title": "Harvest Azure Credentials", - "type": "boolean", - "default": True, - "attack_techniques": ["T1003"], - "description": - "Determine if the Monkey should try to harvest password credentials from Azure VMs" - }, - "collect_system_info": { - "title": "Collect system info", - "type": "boolean", - "default": True, - "attack_techniques": ["T1082", "T1005", "T1016"], - "description": "Determines whether to collect system info" - }, - "should_use_mimikatz": { - "title": "Should use Mimikatz", - "type": "boolean", - "default": True, - "attack_techniques": ["T1003"], - "description": "Determines whether to use Mimikatz" - }, "system_info_collector_classes": { "title": "System info collectors", "type": "array", @@ -138,7 +98,9 @@ MONKEY = { ENVIRONMENT_COLLECTOR, AWS_COLLECTOR, HOSTNAME_COLLECTOR, - PROCESS_LIST_COLLECTOR + PROCESS_LIST_COLLECTOR, + MIMIKATZ_COLLECTOR, + AZURE_CRED_COLLECTOR ] }, } diff --git a/monkey/monkey_island/cc/services/post_breach_files.py b/monkey/monkey_island/cc/services/post_breach_files.py index fe4f47ddd..e3e6266cb 100644 --- a/monkey/monkey_island/cc/services/post_breach_files.py +++ b/monkey/monkey_island/cc/services/post_breach_files.py @@ -9,8 +9,8 @@ __author__ = "VakarisZ" logger = logging.getLogger(__name__) # Where to find file names in config -PBA_WINDOWS_FILENAME_PATH = ['monkey', 'behaviour', 'PBA_windows_filename'] -PBA_LINUX_FILENAME_PATH = ['monkey', 'behaviour', 'PBA_linux_filename'] +PBA_WINDOWS_FILENAME_PATH = ['monkey', 'post_breach', 'PBA_windows_filename'] +PBA_LINUX_FILENAME_PATH = ['monkey', 'post_breach', 'PBA_linux_filename'] UPLOADS_DIR = Path('monkey_island', 'cc', 'userUploads') @@ -41,5 +41,5 @@ def set_config_PBA_files(config_json): if monkey_island.cc.services.config.ConfigService.get_config(): linux_filename = monkey_island.cc.services.config.ConfigService.get_config_value(PBA_LINUX_FILENAME_PATH) windows_filename = monkey_island.cc.services.config.ConfigService.get_config_value(PBA_WINDOWS_FILENAME_PATH) - config_json['monkey']['behaviour']['PBA_linux_filename'] = linux_filename - config_json['monkey']['behaviour']['PBA_windows_filename'] = windows_filename + config_json['monkey']['post_breach']['PBA_linux_filename'] = linux_filename + config_json['monkey']['post_breach']['PBA_windows_filename'] = windows_filename diff --git a/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js b/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js index 6185ca647..a6e22cd77 100644 --- a/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js +++ b/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js @@ -24,7 +24,7 @@ export default function UiSchema(props) { 'ui:widget': AdvancedMultiSelect } }, - behaviour: { + post_breach: { custom_PBA_linux_cmd: { 'ui:widget': 'textarea', 'ui:emptyValue': '' 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 e2042fa69..ffef85739 100644 --- a/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js +++ b/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js @@ -334,8 +334,8 @@ class ConfigurePageComponent extends AuthComponent { {this.renderBasicNetworkWarning()}
{ let config = this.state.configuration - config.monkey.behaviour.PBA_windows_filename = filename + config.monkey.post_breach.PBA_windows_filename = filename this.setState({ configuration: config }) @@ -359,7 +359,7 @@ class ConfigurePageComponent extends AuthComponent { setPbaFilenameLinux = (filename) => { let config = this.state.configuration - config.monkey.behaviour.PBA_linux_filename = filename + config.monkey.post_breach.PBA_linux_filename = filename this.setState({ configuration: config })