diff --git a/.swm/OwcKMnALpn7tuBaJY1US.swm b/.swm/OwcKMnALpn7tuBaJY1US.swm deleted file mode 100644 index 5555018fa..000000000 --- a/.swm/OwcKMnALpn7tuBaJY1US.swm +++ /dev/null @@ -1,197 +0,0 @@ -{ - "id": "OwcKMnALpn7tuBaJY1US", - "name": "Add a new System Info Collector", - "task": { - "dod": "Add a system info collector that collects the machine hostname.", - "tests": [], - "hints": [ - "First thing you should do is take a look at a different collector (like HostnameCollector) and 100% understand how it runs, how results are relayed back to the server, and how the server processes the data.", - "Try to run \"socket.getfqdn()\".", - "Take a look at SystemInfoCollector - that's the base class you'll need to implement.", - "Make sure you add the new collector to the configuration in all relevant places, including making it ON by default!" - ] - }, - "content": [ - { - "type": "text", - "text": "# What are system info collectors?\n\nWell, the name pretty much explains it. They are Monkey classes which collect various information regarding the victim system, such as Environment, SSH Info, Process List and more. \n\n## What should I add? \n\nA system info collector which collects the hostname of the system.\n\n## Test manually\n\nOnce you're done, make sure that your collector:\n* Appears in the Island configuration, and is enabled by default\n* The collector actually runs when executing a Monkey.\n* Results show up in the relevant places:\n * The infection map.\n * The security report.\n * The relevant MITRE techniques.\n\n**There are a lot of hints for this unit - don't be afraid to use them!**" - }, - { - "type": "snippet", - "path": "monkey/common/common_consts/system_info_collectors_names.py", - "comments": [], - "firstLineNumber": 1, - "lines": [ - " AWS_COLLECTOR = \"AwsCollector\"", - "*HOSTNAME_COLLECTOR = \"HostnameCollector\"", - "+# SWIMMER: Collector name goes here.", - " PROCESS_LIST_COLLECTOR = \"ProcessListCollector\"", - " MIMIKATZ_COLLECTOR = \"MimikatzCollector\"" - ] - }, - { - "type": "snippet", - "path": "monkey/infection_monkey/system_info/collectors/hostname_collector.py", - "comments": [], - "firstLineNumber": 1, - "lines": [ - " import logging", - " import socket", - "*", - "*from common.common_consts.system_info_collectors_names import HOSTNAME_COLLECTOR", - "*from infection_monkey.system_info.system_info_collector import SystemInfoCollector", - " ", - " logger = logging.getLogger(__name__)", - " ", - "*", - "+# SWIMMER: The collector class goes here.", - "*class HostnameCollector(SystemInfoCollector):", - "* def __init__(self):", - "* super().__init__(name=HOSTNAME_COLLECTOR)", - "*", - "* def collect(self) -> dict:", - "* return {\"hostname\": socket.getfqdn()}" - ] - }, - { - "type": "snippet", - "path": "monkey/monkey_island/cc/services/config_schema/definitions/system_info_collector_classes.py", - "comments": [], - "firstLineNumber": 4, - "lines": [ - "* HOSTNAME_COLLECTOR,", - " MIMIKATZ_COLLECTOR,", - " PROCESS_LIST_COLLECTOR,", - " )" - ] - }, - { - "type": "snippet", - "path": "monkey/monkey_island/cc/services/config_schema/definitions/system_info_collector_classes.py", - "comments": [], - "firstLineNumber": 37, - "lines": [ - " \"currently running on.\",", - " \"attack_techniques\": [\"T1082\"],", - " },", - "* {", - "* \"type\": \"string\",", - "* \"enum\": [HOSTNAME_COLLECTOR],", - "* \"title\": \"Hostname Collector\",", - "* \"safe\": True,", - "* \"info\": \"Collects machine's hostname.\",", - "* \"attack_techniques\": [\"T1082\", \"T1016\"],", - "* },", - " {", - " \"type\": \"string\",", - " \"enum\": [PROCESS_LIST_COLLECTOR]," - ] - }, - { - "type": "snippet", - "path": "monkey/monkey_island/cc/services/config_schema/monkey.py", - "comments": [], - "firstLineNumber": 1, - "lines": [ - " from common.common_consts.system_info_collectors_names import (", - " AWS_COLLECTOR,", - "* HOSTNAME_COLLECTOR,", - " MIMIKATZ_COLLECTOR,", - " PROCESS_LIST_COLLECTOR,", - " )" - ] - }, - { - "type": "snippet", - "path": "monkey/monkey_island/cc/services/config_schema/monkey.py", - "comments": [], - "firstLineNumber": 91, - "lines": [ - " \"default\": [", - " AWS_COLLECTOR,", - "* HOSTNAME_COLLECTOR,", - " PROCESS_LIST_COLLECTOR,", - " MIMIKATZ_COLLECTOR," - ] - }, - { - "type": "snippet", - "path": "monkey/monkey_island/cc/services/telemetry/processing/system_info_collectors/hostname.py", - "comments": [], - "firstLineNumber": 1, - "lines": [ - " import logging", - " ", - "*from monkey_island.cc.models.monkey import Monkey", - "+# SWIMMER: This will be useful :) monkey_island.cc.models.monkey.Monkey has the useful", - "+# \"get_single_monkey_by_guid\" and \"set_hostname\" methods.", - " ", - " logger = logging.getLogger(__name__)", - " ", - " ", - "*def process_hostname_telemetry(collector_results, monkey_guid):", - "+# SWIMMER: Processing function goes here.", - "* Monkey.get_single_monkey_by_guid(monkey_guid).set_hostname(collector_results[\"hostname\"])" - ] - }, - { - "type": "snippet", - "path": "monkey/monkey_island/cc/services/telemetry/processing/system_info_collectors/system_info_telemetry_dispatcher.py", - "comments": [], - "firstLineNumber": 1, - "lines": [ - " import logging", - " import typing", - " ", - " from common.common_consts.system_info_collectors_names import (", - " AWS_COLLECTOR,", - "* HOSTNAME_COLLECTOR," - ] - }, - { - "type": "snippet", - "path": "monkey/monkey_island/cc/services/telemetry/processing/system_info_collectors/system_info_telemetry_dispatcher.py", - "comments": [], - "firstLineNumber": 25, - "lines": [ - " SYSTEM_INFO_COLLECTOR_TO_TELEMETRY_PROCESSORS = {", - " AWS_COLLECTOR: [process_aws_telemetry],", - "* HOSTNAME_COLLECTOR: [process_hostname_telemetry],", - " PROCESS_LIST_COLLECTOR: [check_antivirus_existence],", - " }", - " " - ] - }, - { - "type": "snippet", - "lines": [ - "*from monkey_island.cc.services.telemetry.processing.system_info_collectors.hostname import (", - "* process_hostname_telemetry,", - "*)", - " from monkey_island.cc.services.telemetry.zero_trust_checks.antivirus_existence import (", - " check_antivirus_existence,", - " )" - ], - "firstLineNumber": 12, - "path": "monkey/monkey_island/cc/services/telemetry/processing/system_info_collectors/system_info_telemetry_dispatcher.py", - "comments": [] - }, - { - "type": "text", - "text": "System info collectors are useful to get more data for various things, such as ZT tests or MITRE techniques. Take a look at some other techniques!" - } - ], - "symbols": {}, - "file_version": "2.0.3", - "meta": { - "app_version": "0.5.7-0", - "file_blobs": { - "monkey/common/common_consts/system_info_collectors_names.py": "175a054e1408805a4cebbe27e2f9616db40988cf", - "monkey/infection_monkey/system_info/collectors/hostname_collector.py": "0aeecd9fb7bde83cccd4501ec03e0da199ec5fc3", - "monkey/monkey_island/cc/services/config_schema/definitions/system_info_collector_classes.py": "072640352fc9d50fe09752cfc951dab7d99271af", - "monkey/monkey_island/cc/services/config_schema/monkey.py": "da06123a95eebf7f0a68861815ee644bb37c8db6", - "monkey/monkey_island/cc/services/telemetry/processing/system_info_collectors/hostname.py": "e2de4519cbd71bba70e81cf3ff61817437d95a21", - "monkey/monkey_island/cc/services/telemetry/processing/system_info_collectors/system_info_telemetry_dispatcher.py": "7ce4b6fcfbce0d6cd8a60297213c5be1699b22df" - } - } -} diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a455996d..5cf8edab4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,7 @@ Changelog](https://keepachangelog.com/en/1.0.0/). - Removed environment system info collector #1535 - Azure credential collector, because it was broken (not gathering credentials). #1535 - Custom monkey directory name config option. #1537 +- Hostname system info collector. #1535 ### Fixed - A bug in network map page that caused delay of telemetry log loading. #1545 diff --git a/docs/content/development/adding-system-info-collectors.md b/docs/content/development/adding-system-info-collectors.md index 3e924bd4e..e865bcfd6 100644 --- a/docs/content/development/adding-system-info-collectors.md +++ b/docs/content/development/adding-system-info-collectors.md @@ -39,7 +39,7 @@ class MyNewCollector(SystemInfoCollector): #### Implementation -Override the `collect` method with your own implementation. See the `hostname_collector.py` System Info Collector for reference. You can log during collection as well. +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 diff --git a/envs/monkey_zoo/blackbox/config_templates/base_template.py b/envs/monkey_zoo/blackbox/config_templates/base_template.py index e323e9098..dbc235cd7 100644 --- a/envs/monkey_zoo/blackbox/config_templates/base_template.py +++ b/envs/monkey_zoo/blackbox/config_templates/base_template.py @@ -9,10 +9,7 @@ class BaseTemplate(ConfigTemplate): "basic_network.scope.local_network_scan": False, "basic_network.scope.depth": 1, "internal.classes.finger_classes": ["PingScanner", "HTTPFinger"], - "internal.monkey.system_info.system_info_collector_classes": [ - "EnvironmentCollector", - "HostnameCollector", - ], + "internal.monkey.system_info.system_info_collector_classes": [], "monkey.post_breach.post_breach_actions": [], "internal.general.keep_tunnel_open_time": 0, } diff --git a/envs/monkey_zoo/blackbox/config_templates/smb_mimikatz.py b/envs/monkey_zoo/blackbox/config_templates/smb_mimikatz.py index 8c970d2d4..37b452801 100644 --- a/envs/monkey_zoo/blackbox/config_templates/smb_mimikatz.py +++ b/envs/monkey_zoo/blackbox/config_templates/smb_mimikatz.py @@ -17,8 +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": [ - "EnvironmentCollector", - "HostnameCollector", "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 8c484e7b2..7ff3ab84f 100644 --- a/envs/monkey_zoo/blackbox/config_templates/wmi_mimikatz.py +++ b/envs/monkey_zoo/blackbox/config_templates/wmi_mimikatz.py @@ -16,8 +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": [ - "EnvironmentCollector", - "HostnameCollector", "ProcessListCollector", "MimikatzCollector", ], diff --git a/monkey/common/common_consts/system_info_collectors_names.py b/monkey/common/common_consts/system_info_collectors_names.py index f87fff4bd..d65c45b7b 100644 --- a/monkey/common/common_consts/system_info_collectors_names.py +++ b/monkey/common/common_consts/system_info_collectors_names.py @@ -1,4 +1,3 @@ AWS_COLLECTOR = "AwsCollector" -HOSTNAME_COLLECTOR = "HostnameCollector" PROCESS_LIST_COLLECTOR = "ProcessListCollector" MIMIKATZ_COLLECTOR = "MimikatzCollector" diff --git a/monkey/infection_monkey/system_info/collectors/hostname_collector.py b/monkey/infection_monkey/system_info/collectors/hostname_collector.py deleted file mode 100644 index 0aeecd9fb..000000000 --- a/monkey/infection_monkey/system_info/collectors/hostname_collector.py +++ /dev/null @@ -1,15 +0,0 @@ -import logging -import socket - -from common.common_consts.system_info_collectors_names import HOSTNAME_COLLECTOR -from infection_monkey.system_info.system_info_collector import SystemInfoCollector - -logger = logging.getLogger(__name__) - - -class HostnameCollector(SystemInfoCollector): - def __init__(self): - super().__init__(name=HOSTNAME_COLLECTOR) - - def collect(self) -> dict: - return {"hostname": socket.getfqdn()} diff --git a/monkey/monkey_island/cc/models/monkey.py b/monkey/monkey_island/cc/models/monkey.py index 888d1c569..24c8363d3 100644 --- a/monkey/monkey_island/cc/models/monkey.py +++ b/monkey/monkey_island/cc/models/monkey.py @@ -122,16 +122,6 @@ class Monkey(Document): """ return Monkey.get_single_monkey_by_id(object_id).hostname - def set_hostname(self, hostname): - """ - Sets a new hostname for a machine and clears the cache for getting it. - :param hostname: The new hostname for the machine. - """ - self.hostname = hostname - self.save() - Monkey.get_hostname_by_id.delete(self.id) - Monkey.get_label_by_id.delete(self.id) - def get_network_info(self): """ Formats network info from monkey's model @@ -139,10 +129,8 @@ class Monkey(Document): """ return {"ips": self.ip_addresses, "hostname": self.hostname} - @ring.lru( - # data has TTL of 1 second. This is useful for rapid calls for report generation. - expire=1 - ) + # data has TTL of 1 second. This is useful for rapid calls for report generation. + @ring.lru(expire=1) @staticmethod def is_monkey(object_id): try: 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 514ee3183..b77087a48 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 ( AWS_COLLECTOR, - HOSTNAME_COLLECTOR, MIMIKATZ_COLLECTOR, PROCESS_LIST_COLLECTOR, ) @@ -27,14 +26,6 @@ SYSTEM_INFO_COLLECTOR_CLASSES = { "currently running on.", "attack_techniques": ["T1082"], }, - { - "type": "string", - "enum": [HOSTNAME_COLLECTOR], - "title": "Hostname Collector", - "safe": True, - "info": "Collects machine's hostname.", - "attack_techniques": ["T1082", "T1016"], - }, { "type": "string", "enum": [PROCESS_LIST_COLLECTOR], diff --git a/monkey/monkey_island/cc/services/config_schema/monkey.py b/monkey/monkey_island/cc/services/config_schema/monkey.py index 68155970f..97fdbd19b 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 ( AWS_COLLECTOR, - HOSTNAME_COLLECTOR, MIMIKATZ_COLLECTOR, PROCESS_LIST_COLLECTOR, ) @@ -88,7 +87,6 @@ MONKEY = { "items": {"$ref": "#/definitions/system_info_collector_classes"}, "default": [ AWS_COLLECTOR, - HOSTNAME_COLLECTOR, PROCESS_LIST_COLLECTOR, MIMIKATZ_COLLECTOR, ], diff --git a/monkey/monkey_island/cc/services/telemetry/processing/system_info_collectors/hostname.py b/monkey/monkey_island/cc/services/telemetry/processing/system_info_collectors/hostname.py deleted file mode 100644 index e2de4519c..000000000 --- a/monkey/monkey_island/cc/services/telemetry/processing/system_info_collectors/hostname.py +++ /dev/null @@ -1,9 +0,0 @@ -import logging - -from monkey_island.cc.models.monkey import Monkey - -logger = logging.getLogger(__name__) - - -def process_hostname_telemetry(collector_results, monkey_guid): - Monkey.get_single_monkey_by_guid(monkey_guid).set_hostname(collector_results["hostname"]) 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 7683cac6f..702cffe2c 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,17 +1,10 @@ import logging import typing -from common.common_consts.system_info_collectors_names import ( - AWS_COLLECTOR, - HOSTNAME_COLLECTOR, - PROCESS_LIST_COLLECTOR, -) +from common.common_consts.system_info_collectors_names import AWS_COLLECTOR, PROCESS_LIST_COLLECTOR from monkey_island.cc.services.telemetry.processing.system_info_collectors.aws import ( process_aws_telemetry, ) -from monkey_island.cc.services.telemetry.processing.system_info_collectors.hostname import ( - process_hostname_telemetry, -) from monkey_island.cc.services.telemetry.zero_trust_checks.antivirus_existence import ( check_antivirus_existence, ) @@ -20,7 +13,6 @@ logger = logging.getLogger(__name__) SYSTEM_INFO_COLLECTOR_TO_TELEMETRY_PROCESSORS = { AWS_COLLECTOR: [process_aws_telemetry], - HOSTNAME_COLLECTOR: [process_hostname_telemetry], PROCESS_LIST_COLLECTOR: [check_antivirus_existence], } diff --git a/monkey/tests/unit_tests/monkey_island/cc/models/test_monkey.py b/monkey/tests/unit_tests/monkey_island/cc/models/test_monkey.py index 90fd9032a..f5a00e5e7 100644 --- a/monkey/tests/unit_tests/monkey_island/cc/models/test_monkey.py +++ b/monkey/tests/unit_tests/monkey_island/cc/models/test_monkey.py @@ -134,17 +134,14 @@ class TestMonkey: assert cache_info_after_query_2.hits == 1 assert cache_info_after_query_2.misses == 1 - # set hostname deletes the id from the cache. - linux_monkey.set_hostname("Another hostname") - - # should be a miss + # should be a another hit, since the monkey ID is already cached label = Monkey.get_label_by_id(linux_monkey.id) logger.debug("3) ID: {} label: {}".format(linux_monkey.id, label)) cache_info_after_query_3 = Monkey.get_label_by_id.storage.backend.cache_info() logger.debug("Cache info: {}".format(str(cache_info_after_query_3))) # still 1 hit only - assert cache_info_after_query_3.hits == 1 - assert cache_info_after_query_3.misses == 2 + assert cache_info_after_query_3.hits == 2 + assert cache_info_after_query_3.misses == 1 @pytest.mark.usefixtures("uses_database") def test_is_monkey(self): diff --git a/vulture_allowlist.py b/vulture_allowlist.py index ae4f95b55..b57fe73ab 100644 --- a/vulture_allowlist.py +++ b/vulture_allowlist.py @@ -97,7 +97,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) AwsCollector # unused class (monkey/infection_monkey/system_info/collectors/aws_collector.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)