diff --git a/CHANGELOG.md b/CHANGELOG.md index b51cc9321..c5e2d74ad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ Changelog](https://keepachangelog.com/en/1.0.0/). - The setup procedure for custom server_config.json files to be simpler. #1576 - The order and content of Monkey Island's initialization logging to give clearer instructions to the user and avoid confusion. #1684 +- The process list collection system info collector to now be a post-breach action. #1697 ### Removed - VSFTPD exploiter. #1533 diff --git a/docs/content/development/adding-exploits.md b/docs/content/development/adding-exploits.md index 1f4698820..468d17055 100644 --- a/docs/content/development/adding-exploits.md +++ b/docs/content/development/adding-exploits.md @@ -14,7 +14,7 @@ An exploit is a sequence of commands that takes advantage of a security vulnerab ### Do I need a new Exploit? -If all you want to do is execute a shell command, configure the required commands in the Monkey Island's post-breach action (PBA) configuration section or [add a new PBA](../adding-post-breach-actions/). If you would like the Infection Monkey agent to collect specific information, [add a new System Info Collector](../adding-system-info-collectors/). +If all you want to do is execute a shell command, configure the required commands in the Monkey Island's post-breach action (PBA) configuration section or [add a new PBA](../adding-post-breach-actions/). However, if you have your eye on an interesting CVE that you would like the Infection Monkey to support, you must add a new exploit. Keep reading to learn how to add a new exploit. diff --git a/docs/content/development/adding-system-info-collectors.md b/docs/content/development/adding-system-info-collectors.md deleted file mode 100644 index e865bcfd6..000000000 --- a/docs/content/development/adding-system-info-collectors.md +++ /dev/null @@ -1,101 +0,0 @@ ---- -title: "Adding System Info Collectors" -date: 2020-06-09T11:03:42+03:00 -draft: false -tags: ["contribute"] -weight: 80 ---- - -## What does this guide cover? - -This guide will show you how to create a new _System Info Collector_ for the Infection Monkey. System Info Collectors are modules that each of the Infection Monkey agents runs that collect specific information and send it back to the Monkey Island as part of the System Info Telemetry. - -### Do I need a new System Info Collector? - -If all you want to do is execute a shell command, then there's no need to add a new System Info Collector - just configure the required commands in the Monkey Island's post-breach action (PBA) section! Also, if there is a relevant System Info Collector and you only need to add more information to it, simply expand the existing one. Otherwise, you must add a new System Info Collector. - -## How to add a new System Info Collector - -### Modify the Infection Monkey Agent - -#### Framework - -1. Create your new System Info Collector in the following directory: `monkey/infection_monkey/system_info/collectors` by first creating a new file with the name of your System Info Collector. -2. In that file, create a class that inherits from the `SystemInfoCollector` class: - -```py -from infection_monkey.system_info.system_info_collector import SystemInfoCollector - -class MyNewCollector(SystemInfoCollector): -``` - -3. Set the System Info Collector name in the constructor, like so: - -```py -class MyNewCollector(SystemInfoCollector): - def __init__(self): - super(MyNewCollector, self).__init__(name="MyNewCollector") -``` - -#### Implementation - -Override the `collect` method with your own implementation. See the `process_list_collector.py` System Info Collector for reference. You can log during collection as well. - -### Modify the Monkey Island - -#### Configuration - -##### Definitions - -You'll need to add your Sytem Info Collector to the `monkey_island/cc/services/config_schema.py` file, under `definitions/system_info_collectors_classes/anyOf`, like so: - -```json -"system_info_collectors_classes": { - "title": "System Information Collectors", - "type": "string", - "anyOf": [ - { - "type": "string", - "enum": [ - "HostnameCollector" - ], - "title": "Which Environment this machine is on (on prem/cloud)", - "attack_techniques": [] - }, - { <================================= - "type": "string", <================================= - "enum": [ <================================= - "MyNewCollector" <================================= - ], <================================= - "title": "My new title", <================================= - "attack_techniques": [] <================================= - }, - ], -}, -``` - -##### properties - -Also, you can add the System Info Collector to be used by default by adding it to the `default` key under `properties/monkey/system_info/system_info_collectors_classes`: - -```json -"system_info_collectors_classes": { - "title": "System info collectors", - "type": "array", - "uniqueItems": True, - "items": { - "$ref": "#/definitions/system_info_collectors_classes" - }, - "default": [ - "HostnameCollector", - "MyNewCollector" <================================= - ], - "description": "Determines which system information collectors will collect information." -}, -``` - -#### Telemetry processing - -1. Add a process function under `monkey_island/cc/telemetry/processing/system_info_collectors/{DATA_NAME_HERE}.py`. The function should parse the System Info Collector's result. See `processing/system_info_collectors/environment.py` for example. - -2. Add that function to `SYSTEM_INFO_COLLECTOR_TO_TELEMETRY_PROCESSORS` under `monkey_island/cc/services/telemetry/processing/system_info_collectors/system_info_telemetry_dispatcher.py`. diff --git a/envs/monkey_zoo/blackbox/config_templates/smb_mimikatz.py b/envs/monkey_zoo/blackbox/config_templates/smb_mimikatz.py index 37b452801..25003eb20 100644 --- a/envs/monkey_zoo/blackbox/config_templates/smb_mimikatz.py +++ b/envs/monkey_zoo/blackbox/config_templates/smb_mimikatz.py @@ -17,7 +17,6 @@ class SmbMimikatz(ConfigTemplate): "internal.network.tcp_scanner.HTTP_PORTS": [], "internal.network.tcp_scanner.tcp_target_ports": [445], "monkey.system_info.system_info_collector_classes": [ - "ProcessListCollector", "MimikatzCollector", ], } diff --git a/envs/monkey_zoo/blackbox/config_templates/wmi_mimikatz.py b/envs/monkey_zoo/blackbox/config_templates/wmi_mimikatz.py index 7ff3ab84f..430547a73 100644 --- a/envs/monkey_zoo/blackbox/config_templates/wmi_mimikatz.py +++ b/envs/monkey_zoo/blackbox/config_templates/wmi_mimikatz.py @@ -16,7 +16,6 @@ class WmiMimikatz(ConfigTemplate): "internal.network.tcp_scanner.HTTP_PORTS": [], "internal.network.tcp_scanner.tcp_target_ports": [135], "monkey.system_info.system_info_collector_classes": [ - "ProcessListCollector", "MimikatzCollector", ], } diff --git a/monkey/common/common_consts/post_breach_consts.py b/monkey/common/common_consts/post_breach_consts.py index 01d314482..19b6c4f19 100644 --- a/monkey/common/common_consts/post_breach_consts.py +++ b/monkey/common/common_consts/post_breach_consts.py @@ -9,3 +9,4 @@ POST_BREACH_TIMESTOMPING = "Modify files' timestamps" POST_BREACH_SIGNED_SCRIPT_PROXY_EXEC = "Signed script proxy execution" POST_BREACH_ACCOUNT_DISCOVERY = "Account discovery" POST_BREACH_CLEAR_CMD_HISTORY = "Clear command history" +POST_BREACH_PROCESS_LIST_COLLECTION = "Collect running processes" diff --git a/monkey/common/common_consts/system_info_collectors_names.py b/monkey/common/common_consts/system_info_collectors_names.py index 075d6ff45..711843b19 100644 --- a/monkey/common/common_consts/system_info_collectors_names.py +++ b/monkey/common/common_consts/system_info_collectors_names.py @@ -1,2 +1 @@ -PROCESS_LIST_COLLECTOR = "ProcessListCollector" MIMIKATZ_COLLECTOR = "MimikatzCollector" diff --git a/monkey/infection_monkey/master/automated_master.py b/monkey/infection_monkey/master/automated_master.py index 28994d673..c29e3c6f3 100644 --- a/monkey/infection_monkey/master/automated_master.py +++ b/monkey/infection_monkey/master/automated_master.py @@ -176,6 +176,9 @@ class AutomatedMaster(IMaster): ) def _run_pba(self, pba: Tuple[str, Dict]): + # TODO: This is the class's name right now. We need `display_name` (see the + # ProcessListCollection PBA). This is shown in the Security report as the PBA + # name and is checked against in the T1082's mongo query in the ATT&CK report. name = pba[0] options = pba[1] diff --git a/monkey/infection_monkey/system_info/collectors/process_list_collector.py b/monkey/infection_monkey/post_breach/actions/collect_processes_list.py similarity index 55% rename from monkey/infection_monkey/system_info/collectors/process_list_collector.py rename to monkey/infection_monkey/post_breach/actions/collect_processes_list.py index 12cdf8aeb..181fd5988 100644 --- a/monkey/infection_monkey/system_info/collectors/process_list_collector.py +++ b/monkey/infection_monkey/post_breach/actions/collect_processes_list.py @@ -2,31 +2,36 @@ import logging import psutil -from common.common_consts.system_info_collectors_names import PROCESS_LIST_COLLECTOR -from infection_monkey.system_info.system_info_collector import SystemInfoCollector +from common.common_consts.post_breach_consts import POST_BREACH_PROCESS_LIST_COLLECTION +from infection_monkey.post_breach.pba import PBA logger = logging.getLogger(__name__) # Linux doesn't have WindowsError +applicable_exceptions = psutil.AccessDenied try: - WindowsError + applicable_exceptions = (psutil.AccessDenied, WindowsError) except NameError: - # noinspection PyShadowingBuiltins - WindowsError = psutil.AccessDenied + pass -class ProcessListCollector(SystemInfoCollector): +class ProcessListCollection(PBA): + # TODO: (?) Move all PBA consts into their classes + display_name = POST_BREACH_PROCESS_LIST_COLLECTION + def __init__(self): - super().__init__(name=PROCESS_LIST_COLLECTOR) + super().__init__(POST_BREACH_PROCESS_LIST_COLLECTION) - def collect(self) -> dict: + def run(self): """ - Adds process information from the host to the system information. + Collects process information from the host. Currently lists process name, ID, parent ID, command line and the full image path of each process. """ logger.debug("Reading process list") + processes = {} + success_state = False for process in psutil.process_iter(): try: processes[process.pid] = { @@ -36,10 +41,10 @@ class ProcessListCollector(SystemInfoCollector): "cmdline": " ".join(process.cmdline()), "full_image_path": process.exe(), } - except (psutil.AccessDenied, WindowsError): - # we may be running as non root and some processes are impossible to acquire in - # Windows/Linux. - # In this case we'll just add what we know. + success_state = True + except applicable_exceptions: + # We may be running as non root and some processes are impossible to acquire in + # Windows/Linux. In this case, we'll just add what we know. processes[process.pid] = { "name": "null", "pid": process.pid, @@ -49,4 +54,4 @@ class ProcessListCollector(SystemInfoCollector): } continue - return {"process_list": processes} + return self.command, (processes, success_state) diff --git a/monkey/infection_monkey/puppet/mock_puppet.py b/monkey/infection_monkey/puppet/mock_puppet.py index ec3984685..082ce523b 100644 --- a/monkey/infection_monkey/puppet/mock_puppet.py +++ b/monkey/infection_monkey/puppet/mock_puppet.py @@ -12,6 +12,7 @@ from infection_monkey.i_puppet import ( PortStatus, PostBreachData, ) +from infection_monkey.post_breach.actions.collect_processes_list import ProcessListCollection DOT_1 = "10.0.0.1" DOT_2 = "10.0.0.2" diff --git a/monkey/monkey_island/cc/services/attack/technique_reports/T1082.py b/monkey/monkey_island/cc/services/attack/technique_reports/T1082.py index ad1bc6281..4c79916ef 100644 --- a/monkey/monkey_island/cc/services/attack/technique_reports/T1082.py +++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1082.py @@ -1,3 +1,4 @@ +from common.common_consts.post_breach_consts import POST_BREACH_PROCESS_LIST_COLLECTION from common.utils.attack_utils import ScanStatus from monkey_island.cc.database import mongo from monkey_island.cc.services.attack.technique_reports import AttackTechnique @@ -7,16 +8,18 @@ class T1082(AttackTechnique): tech_id = "T1082" relevant_systems = ["Linux", "Windows"] unscanned_msg = "Monkey didn't gather any system info on the network." - scanned_msg = "" + scanned_msg = "Monkey tried gathering system info on the network but failed." used_msg = "Monkey gathered system info from machines in the network." + # TODO: Remove the second item from this list after the TODO in `_run_pba()` in + # `automated_master.py` is resolved. + pba_names = [POST_BREACH_PROCESS_LIST_COLLECTION, "ProcessListCollection"] - query = [ + query_for_system_info_collectors = [ {"$match": {"telem_category": "system_info", "data.network_info": {"$exists": True}}}, { "$project": { "machine": {"hostname": "$data.hostname", "ips": "$data.network_info.networks"}, "aws": "$data.aws", - "process_list": "$data.process_list", "ssh_info": "$data.ssh_info", "azure_info": "$data.Azure", } @@ -30,15 +33,6 @@ class T1082(AttackTechnique): "used": {"$and": [{"$gt": ["$aws", {}]}]}, "name": {"$literal": "Amazon Web Services info"}, }, - { - "used": { - "$and": [ - {"$ifNull": ["$process_list", False]}, - {"$gt": ["$process_list", {}]}, - ] - }, - "name": {"$literal": "Running process list"}, - }, { "used": { "$and": [{"$ifNull": ["$ssh_info", False]}, {"$ne": ["$ssh_info", []]}] @@ -62,19 +56,64 @@ class T1082(AttackTechnique): {"$replaceRoot": {"newRoot": "$_id"}}, ] + query_for_running_processes_list = [ + { + "$match": { + "$and": [ + {"telem_category": "post_breach"}, + {"$or": [{"data.name": pba_name} for pba_name in pba_names]}, + {"$or": [{"data.os": os} for os in relevant_systems]}, + ] + } + }, + { + "$project": { + "_id": 0, + "machine": { + "hostname": {"$arrayElemAt": ["$data.hostname", 0]}, + "ips": [{"$arrayElemAt": ["$data.ip", 0]}], + }, + "collections": [ + { + "used": {"$arrayElemAt": [{"$arrayElemAt": ["$data.result", 0]}, 1]}, + "name": {"$literal": "List of running processes"}, + } + ], + } + }, + ] + @staticmethod def get_report_data(): def get_technique_status_and_data(): - system_info = list(mongo.db.telemetry.aggregate(T1082.query)) - if system_info: - status = ScanStatus.USED.value - else: - status = ScanStatus.UNSCANNED.value - return (status, system_info) + system_info_data = list( + mongo.db.telemetry.aggregate(T1082.query_for_system_info_collectors) + ) + system_info_status = ( + ScanStatus.USED.value if system_info_data else ScanStatus.UNSCANNED.value + ) - status, system_info = get_technique_status_and_data() + pba_data = list(mongo.db.telemetry.aggregate(T1082.query_for_running_processes_list)) + successful_PBAs = mongo.db.telemetry.count( + { + "$and": [ + {"$or": [{"data.name": pba_name} for pba_name in T1082.pba_names]}, + {"$or": [{"data.os": os} for os in T1082.relevant_systems]}, + {"data.result.1": True}, + ] + } + ) + pba_status = ScanStatus.USED.value if successful_PBAs else ScanStatus.SCANNED.value + + technique_data = system_info_data + pba_data + # ScanStatus values are in order of precedence; used > scanned > unscanned + technique_status = max(system_info_status, pba_status) + + return (technique_status, technique_data) + + status, technique_data = get_technique_status_and_data() data = {"title": T1082.technique_title()} - data.update({"system_info": system_info}) + data.update({"technique_data": technique_data}) data.update(T1082.get_mitigation_by_status(status)) data.update(T1082.get_message_and_status(status)) diff --git a/monkey/monkey_island/cc/services/config_schema/definitions/post_breach_actions.py b/monkey/monkey_island/cc/services/config_schema/definitions/post_breach_actions.py index 7d62ac36e..e76b2c254 100644 --- a/monkey/monkey_island/cc/services/config_schema/definitions/post_breach_actions.py +++ b/monkey/monkey_island/cc/services/config_schema/definitions/post_breach_actions.py @@ -94,5 +94,13 @@ POST_BREACH_ACTIONS = { "info": "Attempts to clear the command history.", "attack_techniques": ["T1146"], }, + { + "type": "string", + "enum": ["ProcessListCollection"], + "title": "Process List Collector", + "safe": True, + "info": "Collects a list of running processes on the machine.", + "attack_techniques": ["T1082"], + }, ], } 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 5e446513c..2f8c38ee8 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,6 +1,5 @@ from common.common_consts.system_info_collectors_names import ( MIMIKATZ_COLLECTOR, - PROCESS_LIST_COLLECTOR, ) SYSTEM_INFO_COLLECTOR_CLASSES = { @@ -16,13 +15,5 @@ SYSTEM_INFO_COLLECTOR_CLASSES = { "info": "Collects credentials from Windows credential manager.", "attack_techniques": ["T1003", "T1005"], }, - { - "type": "string", - "enum": [PROCESS_LIST_COLLECTOR], - "title": "Process List Collector", - "safe": True, - "info": "Collects a list of running processes on the machine.", - "attack_techniques": ["T1082"], - }, ], } diff --git a/monkey/monkey_island/cc/services/config_schema/monkey.py b/monkey/monkey_island/cc/services/config_schema/monkey.py index 80719d4c2..ba5c88661 100644 --- a/monkey/monkey_island/cc/services/config_schema/monkey.py +++ b/monkey/monkey_island/cc/services/config_schema/monkey.py @@ -1,6 +1,5 @@ from common.common_consts.system_info_collectors_names import ( MIMIKATZ_COLLECTOR, - PROCESS_LIST_COLLECTOR, ) MONKEY = { @@ -71,6 +70,7 @@ MONKEY = { "ScheduleJobs", "Timestomping", "AccountDiscovery", + "ProcessListCollection", ], }, }, @@ -85,7 +85,6 @@ MONKEY = { "uniqueItems": True, "items": {"$ref": "#/definitions/system_info_collector_classes"}, "default": [ - PROCESS_LIST_COLLECTOR, MIMIKATZ_COLLECTOR, ], }, diff --git a/monkey/monkey_island/cc/services/telemetry/processing/post_breach.py b/monkey/monkey_island/cc/services/telemetry/processing/post_breach.py index 5506ff54d..8392d3613 100644 --- a/monkey/monkey_island/cc/services/telemetry/processing/post_breach.py +++ b/monkey/monkey_island/cc/services/telemetry/processing/post_breach.py @@ -1,8 +1,14 @@ import copy -from common.common_consts.post_breach_consts import POST_BREACH_COMMUNICATE_AS_BACKDOOR_USER +from common.common_consts.post_breach_consts import ( + POST_BREACH_COMMUNICATE_AS_BACKDOOR_USER, + POST_BREACH_PROCESS_LIST_COLLECTION, +) from monkey_island.cc.database import mongo from monkey_island.cc.models import Monkey +from monkey_island.cc.services.telemetry.zero_trust_checks.antivirus_existence import ( + check_antivirus_existence, +) from monkey_island.cc.services.telemetry.zero_trust_checks.communicate_as_backdoor_user import ( check_new_user_communication, ) @@ -10,15 +16,22 @@ from monkey_island.cc.services.telemetry.zero_trust_checks.communicate_as_backdo EXECUTION_WITHOUT_OUTPUT = "(PBA execution produced no output)" -def process_communicate_as_backdoor_user_telemetry(telemetry_json): - current_monkey = Monkey.get_single_monkey_by_guid(telemetry_json["monkey_guid"]) +def process_communicate_as_backdoor_user_telemetry(telemetry_json, current_monkey): message = telemetry_json["data"]["result"][0] success = telemetry_json["data"]["result"][1] check_new_user_communication(current_monkey, success, message) +def process_process_list_collection_telemetry(telemetry_json, current_monkey): + check_antivirus_existence(telemetry_json, current_monkey) + + POST_BREACH_TELEMETRY_PROCESSING_FUNCS = { POST_BREACH_COMMUNICATE_AS_BACKDOOR_USER: process_communicate_as_backdoor_user_telemetry, + # TODO: Remove the line below and un-comment the next one after the TODO in `_run_pba()` in + # `automated_master.py` is resolved. + "ProcessListCollection": process_process_list_collection_telemetry, + # POST_BREACH_PROCESS_LIST_COLLECTION: process_process_list_collection_telemetry, } @@ -44,7 +57,10 @@ def process_post_breach_telemetry(telemetry_json): post_breach_action_name = telemetry_json["data"]["name"] if post_breach_action_name in POST_BREACH_TELEMETRY_PROCESSING_FUNCS: - POST_BREACH_TELEMETRY_PROCESSING_FUNCS[post_breach_action_name](telemetry_json) + current_monkey = Monkey.get_single_monkey_by_guid(telemetry_json["monkey_guid"]) + POST_BREACH_TELEMETRY_PROCESSING_FUNCS[post_breach_action_name]( + telemetry_json, current_monkey + ) telemetry_json["data"] = convert_telem_data_to_list(telemetry_json["data"]) diff --git a/monkey/monkey_island/cc/services/telemetry/processing/system_info_collectors/system_info_telemetry_dispatcher.py b/monkey/monkey_island/cc/services/telemetry/processing/system_info_collectors/system_info_telemetry_dispatcher.py index 13e0a9298..7faae8eb2 100644 --- a/monkey/monkey_island/cc/services/telemetry/processing/system_info_collectors/system_info_telemetry_dispatcher.py +++ b/monkey/monkey_island/cc/services/telemetry/processing/system_info_collectors/system_info_telemetry_dispatcher.py @@ -1,16 +1,11 @@ import logging import typing -from common.common_consts.system_info_collectors_names import PROCESS_LIST_COLLECTOR -from monkey_island.cc.services.telemetry.zero_trust_checks.antivirus_existence import ( - check_antivirus_existence, -) logger = logging.getLogger(__name__) -SYSTEM_INFO_COLLECTOR_TO_TELEMETRY_PROCESSORS = { - PROCESS_LIST_COLLECTOR: [check_antivirus_existence], -} + +SYSTEM_INFO_COLLECTOR_TO_TELEMETRY_PROCESSORS = {} class SystemInfoTelemetryDispatcher(object): diff --git a/monkey/monkey_island/cc/services/telemetry/zero_trust_checks/antivirus_existence.py b/monkey/monkey_island/cc/services/telemetry/zero_trust_checks/antivirus_existence.py index d2f154a9e..4e8a86fb4 100644 --- a/monkey/monkey_island/cc/services/telemetry/zero_trust_checks/antivirus_existence.py +++ b/monkey/monkey_island/cc/services/telemetry/zero_trust_checks/antivirus_existence.py @@ -1,7 +1,6 @@ import json import common.common_consts.zero_trust_consts as zero_trust_consts -from monkey_island.cc.models import Monkey from monkey_island.cc.models.zero_trust.event import Event from monkey_island.cc.services.telemetry.zero_trust_checks.known_anti_viruses import ( ANTI_VIRUS_KNOWN_PROCESS_NAMES, @@ -11,9 +10,7 @@ from monkey_island.cc.services.zero_trust.monkey_findings.monkey_zt_finding_serv ) -def check_antivirus_existence(process_list_json, monkey_guid): - current_monkey = Monkey.get_single_monkey_by_guid(monkey_guid) - +def check_antivirus_existence(telemetry_json, current_monkey): process_list_event = Event.create_event( title="Process list", message="Monkey on {} scanned the process list".format(current_monkey.hostname), @@ -21,7 +18,7 @@ def check_antivirus_existence(process_list_json, monkey_guid): ) events = [process_list_event] - av_processes = filter_av_processes(process_list_json["process_list"]) + av_processes = filter_av_processes(telemetry_json["data"]["result"][0]) for process in av_processes: events.append( diff --git a/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1082.js b/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1082.js index 790cb8271..a82adcf09 100644 --- a/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1082.js +++ b/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1082.js @@ -37,9 +37,9 @@ class T1082 extends React.Component { {this.props.data.status === ScanStatus.USED ? : ''} diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/security/PostBreachParser.js b/monkey/monkey_island/cc/ui/src/components/report-components/security/PostBreachParser.js index 4bb420f71..843ca89dd 100644 --- a/monkey/monkey_island/cc/ui/src/components/report-components/security/PostBreachParser.js +++ b/monkey/monkey_island/cc/ui/src/components/report-components/security/PostBreachParser.js @@ -5,6 +5,10 @@ export default function parsePbaResults(results) { const SHELL_STARTUP_NAME = 'Modify shell startup file'; const CMD_HISTORY_NAME = 'Clear command history'; +// TODO: Remove line 10 and un-comment line 11 after the TODO in `_run_pba()` in +// `automated_master.py` is resolved. +const PROCESS_LIST_COLLECTION = 'ProcessListCollection'; +// const PROCESS_LIST_COLLECTION = 'Process list collection'; const multipleResultsPbas = [SHELL_STARTUP_NAME, CMD_HISTORY_NAME] @@ -41,10 +45,17 @@ function aggregateMultipleResultsPba(results) { } } + function modifyProcessListCollectionResult(result) { + result[0] = "Found " + Object.keys(result[0]).length.toString() + " running processes"; + } + // check for pbas with multiple results and aggregate their results - for (let i = 0; i < results.length; i++) + for (let i = 0; i < results.length; i++) { if (multipleResultsPbas.includes(results[i].name)) aggregateResults(results[i]); + if (results[i].name === PROCESS_LIST_COLLECTION) + modifyProcessListCollectionResult(results[i].result); + } // if no modifications were made to the results, i.e. if no pbas had mutiple results, return `results` as it is let noResultsModifications = true; diff --git a/monkey/tests/data_for_tests/monkey_configs/automated_master_config.json b/monkey/tests/data_for_tests/monkey_configs/automated_master_config.json index e7290d822..5556d8c23 100644 --- a/monkey/tests/data_for_tests/monkey_configs/automated_master_config.json +++ b/monkey/tests/data_for_tests/monkey_configs/automated_master_config.json @@ -104,7 +104,6 @@ } }, "system_info_collector_classes": [ - "ProcessListCollector", "MimikatzCollector" ] } diff --git a/monkey/tests/data_for_tests/monkey_configs/flat_config.json b/monkey/tests/data_for_tests/monkey_configs/flat_config.json index 563eb21d5..5693307f2 100644 --- a/monkey/tests/data_for_tests/monkey_configs/flat_config.json +++ b/monkey/tests/data_for_tests/monkey_configs/flat_config.json @@ -101,7 +101,6 @@ "smb_service_name": "InfectionMonkey", "subnet_scan_list": ["192.168.1.50", "192.168.56.0/24", "10.0.33.0/30"], "system_info_collector_classes": [ - "ProcessListCollector", "MimikatzCollector" ], "tcp_scan_timeout": 3000, 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 69e6f4416..38c51042d 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 @@ -146,9 +146,7 @@ }, "system_info": { "system_info_collector_classes": [ - "environmentcollector", "hostnamecollector", - "processlistcollector", "mimikatzcollector" ] } diff --git a/vulture_allowlist.py b/vulture_allowlist.py index 2d8163f29..dde79f032 100644 --- a/vulture_allowlist.py +++ b/vulture_allowlist.py @@ -98,7 +98,6 @@ Timestomping # unused class (monkey/infection_monkey/post_breach/actions/timest SignedScriptProxyExecution # unused class (monkey/infection_monkey/post_breach/actions/use_signed_scripts.py:15) EnvironmentCollector # unused class (monkey/infection_monkey/system_info/collectors/environment_collector.py:19) HostnameCollector # unused class (monkey/infection_monkey/system_info/collectors/hostname_collector.py:10) -ProcessListCollector # unused class (monkey/infection_monkey/system_info/collectors/process_list_collector.py:18) _.coinit_flags # unused attribute (monkey/infection_monkey/system_info/windows_info_collector.py:11) _.representations # unused attribute (monkey/monkey_island/cc/app.py:180) _.log_message # unused method (monkey/infection_monkey/transport/http.py:188)