Merge remote-tracking branch 'origin/dev' into feature/2137-refactor-request-api

This commit is contained in:
Marek Wolan
2024-01-08 10:39:24 +00:00
8 changed files with 223 additions and 156 deletions

View File

@@ -1 +1 @@
3.0.0b2dev
3.0.0b4dev

View File

@@ -167,6 +167,7 @@ agents:
- type: NODE_SERVICE_RESTART
- type: NODE_SERVICE_DISABLE
- type: NODE_SERVICE_ENABLE
- type: NODE_SERVICE_PATCH
- type: NODE_FILE_SCAN
- type: NODE_FILE_CHECKHASH
- type: NODE_FILE_DELETE
@@ -197,111 +198,110 @@ agents:
1:
action: NODE_SERVICE_SCAN
options:
node_id: 2
service_id: 1
node_id: 1
service_id: 0
# stop webapp service
2:
action: NODE_SERVICE_STOP
options:
node_id: 2
service_id: 1
node_id: 1
service_id: 0
# start webapp service
3:
action: "NODE_SERVICE_START"
options:
node_id: 2
service_id: 1
node_id: 1
service_id: 0
4:
action: "NODE_SERVICE_PAUSE"
options:
node_id: 2
service_id: 1
node_id: 1
service_id: 0
5:
action: "NODE_SERVICE_RESUME"
options:
node_id: 2
service_id: 1
node_id: 1
service_id: 0
6:
action: "NODE_SERVICE_RESTART"
options:
node_id: 2
service_id: 1
node_id: 1
service_id: 0
7:
action: "NODE_SERVICE_DISABLE"
options:
node_id: 2
service_id: 1
node_id: 1
service_id: 0
8:
action: "NODE_SERVICE_ENABLE"
options:
node_id: 2
service_id: 1
9:
node_id: 1
service_id: 0
9: # check database.db file
action: "NODE_FILE_SCAN"
options:
node_id: 3
node_id: 2
folder_id: 1
file_id: 1
file_id: 0
10:
action: "NODE_FILE_CHECKHASH"
options:
node_id: 3
node_id: 2
folder_id: 1
file_id: 1
file_id: 0
11:
action: "NODE_FILE_DELETE"
options:
node_id: 3
node_id: 2
folder_id: 1
file_id: 1
file_id: 0
12:
action: "NODE_FILE_REPAIR"
options:
node_id: 3
node_id: 2
folder_id: 1
file_id: 1
file_id: 0
13:
action: "NODE_FILE_RESTORE"
action: "NODE_SERVICE_PATCH"
options:
node_id: 3
folder_id: 1
file_id: 1
node_id: 2
service_id: 0
14:
action: "NODE_FOLDER_SCAN"
options:
node_id: 3
node_id: 2
folder_id: 1
15:
action: "NODE_FOLDER_CHECKHASH"
options:
node_id: 3
node_id: 2
folder_id: 1
16:
action: "NODE_FOLDER_REPAIR"
options:
node_id: 3
node_id: 2
folder_id: 1
17:
action: "NODE_FOLDER_RESTORE"
options:
node_id: 3
node_id: 2
folder_id: 1
18:
action: "NODE_OS_SCAN"
options:
node_id: 3
19:
node_id: 2
19: # shutdown client 1
action: "NODE_SHUTDOWN"
options:
node_id: 6
node_id: 5
20:
action: "NODE_STARTUP"
options:
node_id: 6
node_id: 5
21:
action: "NODE_RESET"
options:
node_id: 6
node_id: 5
22:
action: "NETWORK_ACL_ADDRULE"
options:
@@ -486,9 +486,6 @@ agents:
options:
nodes:
# - node_name: router_1
# - node_name: switch_1
# - node_name: switch_2
- node_name: domain_controller
- node_name: web_server
applications:
@@ -504,6 +501,7 @@ agents:
- node_name: security_suite
- node_name: client_1
- node_name: client_2
max_folders_per_node: 2
max_files_per_folder: 2
max_services_per_node: 2

View File

@@ -165,6 +165,7 @@ agents:
- type: NODE_SERVICE_RESTART
- type: NODE_SERVICE_DISABLE
- type: NODE_SERVICE_ENABLE
- type: NODE_SERVICE_PATCH
- type: NODE_FILE_SCAN
- type: NODE_FILE_CHECKHASH
- type: NODE_FILE_DELETE
@@ -195,111 +196,110 @@ agents:
1:
action: NODE_SERVICE_SCAN
options:
node_id: 2
service_id: 1
node_id: 1
service_id: 0
# stop webapp service
2:
action: NODE_SERVICE_STOP
options:
node_id: 2
service_id: 1
node_id: 1
service_id: 0
# start webapp service
3:
action: "NODE_SERVICE_START"
options:
node_id: 2
service_id: 1
node_id: 1
service_id: 0
4:
action: "NODE_SERVICE_PAUSE"
options:
node_id: 2
service_id: 1
node_id: 1
service_id: 0
5:
action: "NODE_SERVICE_RESUME"
options:
node_id: 2
service_id: 1
node_id: 1
service_id: 0
6:
action: "NODE_SERVICE_RESTART"
options:
node_id: 2
service_id: 1
node_id: 1
service_id: 0
7:
action: "NODE_SERVICE_DISABLE"
options:
node_id: 2
service_id: 1
node_id: 1
service_id: 0
8:
action: "NODE_SERVICE_ENABLE"
options:
node_id: 2
service_id: 1
9:
node_id: 1
service_id: 0
9: # check database.db file
action: "NODE_FILE_SCAN"
options:
node_id: 3
node_id: 2
folder_id: 1
file_id: 1
file_id: 0
10:
action: "NODE_FILE_CHECKHASH"
options:
node_id: 3
node_id: 2
folder_id: 1
file_id: 1
file_id: 0
11:
action: "NODE_FILE_DELETE"
options:
node_id: 3
node_id: 2
folder_id: 1
file_id: 1
file_id: 0
12:
action: "NODE_FILE_REPAIR"
options:
node_id: 3
node_id: 2
folder_id: 1
file_id: 1
file_id: 0
13:
action: "NODE_FILE_RESTORE"
action: "NODE_SERVICE_PATCH"
options:
node_id: 3
folder_id: 1
file_id: 1
node_id: 2
service_id: 0
14:
action: "NODE_FOLDER_SCAN"
options:
node_id: 3
node_id: 2
folder_id: 1
15:
action: "NODE_FOLDER_CHECKHASH"
options:
node_id: 3
node_id: 2
folder_id: 1
16:
action: "NODE_FOLDER_REPAIR"
options:
node_id: 3
node_id: 2
folder_id: 1
17:
action: "NODE_FOLDER_RESTORE"
options:
node_id: 3
node_id: 2
folder_id: 1
18:
action: "NODE_OS_SCAN"
options:
node_id: 3
19:
node_id: 2
19: # shutdown client 1
action: "NODE_SHUTDOWN"
options:
node_id: 6
node_id: 5
20:
action: "NODE_STARTUP"
options:
node_id: 6
node_id: 5
21:
action: "NODE_RESET"
options:
node_id: 6
node_id: 5
22:
action: "NETWORK_ACL_ADDRULE"
options:
@@ -403,93 +403,94 @@ agents:
38:
action: "NETWORK_NIC_DISABLE"
options:
node_id: 1
node_id: 0
nic_id: 1
39:
action: "NETWORK_NIC_ENABLE"
options:
node_id: 1
node_id: 0
nic_id: 1
40:
action: "NETWORK_NIC_DISABLE"
options:
node_id: 2
node_id: 1
nic_id: 1
41:
action: "NETWORK_NIC_ENABLE"
options:
node_id: 2
node_id: 1
nic_id: 1
42:
action: "NETWORK_NIC_DISABLE"
options:
node_id: 3
node_id: 2
nic_id: 1
43:
action: "NETWORK_NIC_ENABLE"
options:
node_id: 3
node_id: 2
nic_id: 1
44:
action: "NETWORK_NIC_DISABLE"
options:
node_id: 4
node_id: 3
nic_id: 1
45:
action: "NETWORK_NIC_ENABLE"
options:
node_id: 4
node_id: 3
nic_id: 1
46:
action: "NETWORK_NIC_DISABLE"
options:
node_id: 5
node_id: 4
nic_id: 1
47:
action: "NETWORK_NIC_ENABLE"
options:
node_id: 5
node_id: 4
nic_id: 1
48:
action: "NETWORK_NIC_DISABLE"
options:
node_id: 5
node_id: 4
nic_id: 2
49:
action: "NETWORK_NIC_ENABLE"
options:
node_id: 5
node_id: 4
nic_id: 2
50:
action: "NETWORK_NIC_DISABLE"
options:
node_id: 6
node_id: 5
nic_id: 1
51:
action: "NETWORK_NIC_ENABLE"
options:
node_id: 6
node_id: 5
nic_id: 1
52:
action: "NETWORK_NIC_DISABLE"
options:
node_id: 7
node_id: 6
nic_id: 1
53:
action: "NETWORK_NIC_ENABLE"
options:
node_id: 7
node_id: 6
nic_id: 1
options:
nodes:
- node_ref: router_1
- node_ref: switch_1
- node_ref: switch_2
- node_ref: domain_controller
- node_ref: web_server
services:
- service_ref: web_server_web_service
- node_ref: database_server
services:
- service_ref: database_service
- node_ref: backup_server
- node_ref: security_suite
- node_ref: client_1
@@ -597,6 +598,7 @@ agents:
- type: NODE_SERVICE_RESTART
- type: NODE_SERVICE_DISABLE
- type: NODE_SERVICE_ENABLE
- type: NODE_SERVICE_PATCH
- type: NODE_FILE_SCAN
- type: NODE_FILE_CHECKHASH
- type: NODE_FILE_DELETE
@@ -627,111 +629,110 @@ agents:
1:
action: NODE_SERVICE_SCAN
options:
node_id: 2
service_id: 1
node_id: 1
service_id: 0
# stop webapp service
2:
action: NODE_SERVICE_STOP
options:
node_id: 2
service_id: 1
node_id: 1
service_id: 0
# start webapp service
3:
action: "NODE_SERVICE_START"
options:
node_id: 2
service_id: 1
node_id: 1
service_id: 0
4:
action: "NODE_SERVICE_PAUSE"
options:
node_id: 2
service_id: 1
node_id: 1
service_id: 0
5:
action: "NODE_SERVICE_RESUME"
options:
node_id: 2
service_id: 1
node_id: 1
service_id: 0
6:
action: "NODE_SERVICE_RESTART"
options:
node_id: 2
service_id: 1
node_id: 1
service_id: 0
7:
action: "NODE_SERVICE_DISABLE"
options:
node_id: 2
service_id: 1
node_id: 1
service_id: 0
8:
action: "NODE_SERVICE_ENABLE"
options:
node_id: 2
service_id: 1
9:
node_id: 1
service_id: 0
9: # check database.db file
action: "NODE_FILE_SCAN"
options:
node_id: 3
node_id: 2
folder_id: 1
file_id: 1
file_id: 0
10:
action: "NODE_FILE_CHECKHASH"
options:
node_id: 3
node_id: 2
folder_id: 1
file_id: 1
file_id: 0
11:
action: "NODE_FILE_DELETE"
options:
node_id: 3
node_id: 2
folder_id: 1
file_id: 1
file_id: 0
12:
action: "NODE_FILE_REPAIR"
options:
node_id: 3
node_id: 2
folder_id: 1
file_id: 1
file_id: 0
13:
action: "NODE_FILE_RESTORE"
action: "NODE_SERVICE_PATCH"
options:
node_id: 3
folder_id: 1
file_id: 1
node_id: 2
service_id: 0
14:
action: "NODE_FOLDER_SCAN"
options:
node_id: 3
node_id: 2
folder_id: 1
15:
action: "NODE_FOLDER_CHECKHASH"
options:
node_id: 3
node_id: 2
folder_id: 1
16:
action: "NODE_FOLDER_REPAIR"
options:
node_id: 3
node_id: 2
folder_id: 1
17:
action: "NODE_FOLDER_RESTORE"
options:
node_id: 3
node_id: 2
folder_id: 1
18:
action: "NODE_OS_SCAN"
options:
node_id: 3
19:
node_id: 2
19: # shutdown client 1
action: "NODE_SHUTDOWN"
options:
node_id: 6
node_id: 5
20:
action: "NODE_STARTUP"
options:
node_id: 6
node_id: 5
21:
action: "NODE_RESET"
options:
node_id: 6
node_id: 5
22:
action: "NETWORK_ACL_ADDRULE"
options:
@@ -835,93 +836,94 @@ agents:
38:
action: "NETWORK_NIC_DISABLE"
options:
node_id: 1
node_id: 0
nic_id: 1
39:
action: "NETWORK_NIC_ENABLE"
options:
node_id: 1
node_id: 0
nic_id: 1
40:
action: "NETWORK_NIC_DISABLE"
options:
node_id: 2
node_id: 1
nic_id: 1
41:
action: "NETWORK_NIC_ENABLE"
options:
node_id: 2
node_id: 1
nic_id: 1
42:
action: "NETWORK_NIC_DISABLE"
options:
node_id: 3
node_id: 2
nic_id: 1
43:
action: "NETWORK_NIC_ENABLE"
options:
node_id: 3
node_id: 2
nic_id: 1
44:
action: "NETWORK_NIC_DISABLE"
options:
node_id: 4
node_id: 3
nic_id: 1
45:
action: "NETWORK_NIC_ENABLE"
options:
node_id: 4
node_id: 3
nic_id: 1
46:
action: "NETWORK_NIC_DISABLE"
options:
node_id: 5
node_id: 4
nic_id: 1
47:
action: "NETWORK_NIC_ENABLE"
options:
node_id: 5
node_id: 4
nic_id: 1
48:
action: "NETWORK_NIC_DISABLE"
options:
node_id: 5
node_id: 4
nic_id: 2
49:
action: "NETWORK_NIC_ENABLE"
options:
node_id: 5
node_id: 4
nic_id: 2
50:
action: "NETWORK_NIC_DISABLE"
options:
node_id: 6
node_id: 5
nic_id: 1
51:
action: "NETWORK_NIC_ENABLE"
options:
node_id: 6
node_id: 5
nic_id: 1
52:
action: "NETWORK_NIC_DISABLE"
options:
node_id: 7
node_id: 6
nic_id: 1
53:
action: "NETWORK_NIC_ENABLE"
options:
node_id: 7
node_id: 6
nic_id: 1
options:
nodes:
- node_ref: router_1
- node_ref: switch_1
- node_ref: switch_2
- node_ref: domain_controller
- node_ref: web_server
services:
- service_ref: web_server_web_service
- node_ref: database_server
services:
- service_ref: database_service
- node_ref: backup_server
- node_ref: security_suite
- node_ref: client_1

View File

@@ -156,6 +156,14 @@ class NodeServiceEnableAction(NodeServiceAbstractAction):
self.verb: str = "enable"
class NodeServicePatchAction(NodeServiceAbstractAction):
"""Action which patches a service."""
def __init__(self, manager: "ActionManager", num_nodes: int, num_services: int, **kwargs) -> None:
super().__init__(manager=manager, num_nodes=num_nodes, num_services=num_services)
self.verb: str = "patch"
class NodeApplicationAbstractAction(AbstractAction):
"""
Base class for application actions.
@@ -559,6 +567,7 @@ class ActionManager:
"NODE_SERVICE_RESTART": NodeServiceRestartAction,
"NODE_SERVICE_DISABLE": NodeServiceDisableAction,
"NODE_SERVICE_ENABLE": NodeServiceEnableAction,
"NODE_SERVICE_PATCH": NodeServicePatchAction,
"NODE_APPLICATION_EXECUTE": NodeApplicationExecuteAction,
"NODE_FILE_SCAN": NodeFileScanAction,
"NODE_FILE_CHECKHASH": NodeFileCheckhashAction,

View File

@@ -102,6 +102,11 @@ class Folder(FileSystemItemABC):
name="delete",
request_type=RequestType(func=lambda request, context: self.remove_file_by_id(file_uuid=request[0])),
)
self._file_request_manager = RequestManager()
rm.add_request(
name="file",
request_type=RequestType(func=lambda request, context: self._file_request_manager),
)
return rm
def describe_state(self) -> Dict:
@@ -254,6 +259,7 @@ class Folder(FileSystemItemABC):
# add to list
self.files[file.uuid] = file
self._files_by_name[file.name] = file
self._file_request_manager.add_request(file.uuid, RequestType(func=file._request_manager))
file.folder = self
def remove_file(self, file: Optional[File]):
@@ -273,6 +279,7 @@ class Folder(FileSystemItemABC):
self.deleted_files[file.uuid] = file
file.delete()
self.sys_log.info(f"Removed file {file.name} (id: {file.uuid})")
self._file_request_manager.remove_request(file.uuid)
else:
_LOGGER.debug(f"File with UUID {file.uuid} was not found.")

View File

@@ -55,3 +55,8 @@ class Simulation(SimComponent):
}
)
return state
def apply_timestep(self, timestep: int) -> None:
"""Apply a timestep to the simulation."""
super().apply_timestep(timestep)
self.network.apply_timestep(timestep)

View File

@@ -91,6 +91,10 @@ class Software(SimComponent):
"The FileSystem of the Node the Software is installed on."
folder: Optional[Folder] = None
"The folder on the file system the Software uses."
patching_duration: int = 2
"The number of ticks it takes to patch the software."
_patching_countdown: Optional[int] = None
"Current number of ticks left to patch the software."
def set_original_state(self):
"""Sets the original state."""
@@ -113,6 +117,12 @@ class Software(SimComponent):
func=lambda request, context: self.set_health_state(SoftwareHealthState.COMPROMISED),
),
)
rm.add_request(
"patch",
RequestType(
func=lambda request, context: self.patch(),
),
)
rm.add_request("scan", RequestType(func=lambda request, context: self.scan()))
return rm
@@ -183,10 +193,33 @@ class Software(SimComponent):
"""Update the observed health status to match the actual health status."""
self.health_state_visible = self.health_state_actual
def patch(self) -> None:
"""Perform a patch on the software."""
self._patching_countdown = self.patching_duration
self.set_health_state(SoftwareHealthState.PATCHING)
def _update_patch_status(self) -> None:
"""Update the patch status of the software."""
self._patching_countdown -= 1
if self._patching_countdown <= 0:
self.set_health_state(SoftwareHealthState.GOOD)
self._patching_countdown = None
self.patching_count += 1
def reveal_to_red(self) -> None:
"""Reveals the software to the red agent."""
self.revealed_to_red = True
def apply_timestep(self, timestep: int) -> None:
"""
Apply a single timestep to the software.
:param timestep: The current timestep of the simulation.
"""
super().apply_timestep(timestep)
if self.health_state_actual == SoftwareHealthState.PATCHING:
self._update_patch_status()
class IOSoftware(Software):
"""

View File

@@ -78,3 +78,16 @@ def test_service_enable(service):
service.apply_request(["enable"])
assert service.operating_state == ServiceOperatingState.STOPPED
def test_service_patch(service):
"""Test that a service can be patched and that it takes two timesteps to complete."""
service.start()
assert service.health_state_actual == SoftwareHealthState.GOOD
service.apply_request(["patch"])
assert service.health_state_actual == SoftwareHealthState.PATCHING
service.apply_timestep(1)
assert service.health_state_actual == SoftwareHealthState.PATCHING
service.apply_timestep(2)
assert service.health_state_actual == SoftwareHealthState.GOOD