From 8783574442e24d31813f208dff94b4431eb21a72 Mon Sep 17 00:00:00 2001 From: "Czar.Echavez" Date: Fri, 27 Oct 2023 10:17:59 +0100 Subject: [PATCH] #1961: os scan set up --- .../simulator/file_system/file_system.py | 5 +++ .../simulator/network/hardware/base.py | 34 ++++++++++++++++++- .../simulator/system/services/service.py | 5 --- .../_network/_hardware/test_node_actions.py | 31 +++++++++++++++++ 4 files changed, 69 insertions(+), 6 deletions(-) diff --git a/src/primaite/simulator/file_system/file_system.py b/src/primaite/simulator/file_system/file_system.py index 55af71c4..cddd276a 100644 --- a/src/primaite/simulator/file_system/file_system.py +++ b/src/primaite/simulator/file_system/file_system.py @@ -231,6 +231,11 @@ class FileSystem(SimComponent): state["folders"] = {folder.name: folder.describe_state() for folder in self.folders.values()} return state + def scan(self): + """Scan all the folders and files in the file system.""" + for folder_id in self.folders: + self.folders[folder_id].scan() + def create_folder(self, folder_name: str) -> Folder: """ Creates a Folder and adds it to the list of folders. diff --git a/src/primaite/simulator/network/hardware/base.py b/src/primaite/simulator/network/hardware/base.py index 7099e4c7..153a0a15 100644 --- a/src/primaite/simulator/network/hardware/base.py +++ b/src/primaite/simulator/network/hardware/base.py @@ -978,7 +978,7 @@ class Node(SimComponent): self._application_request_manager = RequestManager() rm.add_request("application", RequestType(func=self._application_request_manager)) - rm.add_request("scan", RequestType(func=lambda request, context: ...)) # TODO implement OS scan + rm.add_request("scan", RequestType(func=lambda request, context: self.scan(reveal_to_red=True))) rm.add_request("shutdown", RequestType(func=lambda request, context: self.power_off())) rm.add_request("startup", RequestType(func=lambda request, context: self.power_on())) @@ -986,6 +986,10 @@ class Node(SimComponent): rm.add_request("logon", RequestType(func=lambda request, context: ...)) # TODO implement logon request rm.add_request("logoff", RequestType(func=lambda request, context: ...)) # TODO implement logoff request + self._os_request_manager = RequestManager() + self._os_request_manager.add_request("scan", RequestType(func=lambda request, context: self.scan())) + rm.add_request("os", RequestType(func=self._os_request_manager)) + return rm def _install_system_software(self): @@ -1086,6 +1090,34 @@ class Node(SimComponent): self.operating_state = NodeOperatingState.OFF self.sys_log.info("Turned off") + def scan(self): + """ + Scan the node and all the items within it. + + Scans the: + - Processes + - Services + - Applications + - Folders + - Files + + to the red agent. + """ + # scan processes + for process_id in self.processes: + self.processes[process_id].scan() + + # scan services + for service_id in self.services: + self.services[service_id].scan() + + # scan applications + for application_id in self.applications: + self.applications[application_id].scan() + + # scan file system + self.file_system.scan() + def power_on(self): """Power on the Node, enabling its NICs if it is in the OFF state.""" if self.operating_state == NodeOperatingState.OFF: diff --git a/src/primaite/simulator/system/services/service.py b/src/primaite/simulator/system/services/service.py index 24de027c..079f1dcf 100644 --- a/src/primaite/simulator/system/services/service.py +++ b/src/primaite/simulator/system/services/service.py @@ -82,11 +82,6 @@ class Service(IOSoftware): """ pass - def scan(self) -> None: - """Update the service visible states.""" - # update the visible operating state - self.health_state_visible = self.health_state_actual - def stop(self) -> None: """Stop the service.""" if self.operating_state in [ServiceOperatingState.RUNNING, ServiceOperatingState.PAUSED]: diff --git a/tests/unit_tests/_primaite/_simulator/_network/_hardware/test_node_actions.py b/tests/unit_tests/_primaite/_simulator/_network/_hardware/test_node_actions.py index e03e1d28..de4e0745 100644 --- a/tests/unit_tests/_primaite/_simulator/_network/_hardware/test_node_actions.py +++ b/tests/unit_tests/_primaite/_simulator/_network/_hardware/test_node_actions.py @@ -1,6 +1,9 @@ import pytest from primaite.simulator.network.hardware.base import Node, NodeOperatingState +from primaite.simulator.system.processes.process import Process +from primaite.simulator.system.services.service import Service +from primaite.simulator.system.software import SoftwareHealthState @pytest.fixture @@ -39,3 +42,31 @@ def test_node_shutdown(node): idx += 1 assert node.operating_state == NodeOperatingState.OFF + + +def test_node_os_scan(node): + """Test OS Scanning.""" + # add process to node + node.processes["process"] = Process(name="process") + node.processes["process"].health_state_actual = SoftwareHealthState.COMPROMISED + assert node.processes["process"].health_state_visible == SoftwareHealthState.GOOD + + # add services to node + service = Service(name="service") + service.health_state_actual = SoftwareHealthState.COMPROMISED + node.install_service(service=service) + + # add application to node + + # add file to node + + # run os scan + node.apply_request(["os", "scan"]) + + # apply time steps + for i in range(20): + node.apply_timestep(timestep=i) + + # should update the state of all items + assert node.processes["process"].health_state_visible == SoftwareHealthState.COMPROMISED + assert service.health_state_visible == SoftwareHealthState.COMPROMISED