From a71ded8ecf05aa9e0a2d6284d569a82ac1f1c144 Mon Sep 17 00:00:00 2001 From: Archer Bowen Date: Tue, 11 Mar 2025 12:58:59 +0000 Subject: [PATCH] #3110 UC2 Notebook changes: - YAML obs nest dict updated - `friendly_output_red_action` updated - `NMNE` section moved into the same timestep that the attack takes place. - General OBS print is neater and less bloated - ACL's code snippets assumed that ACL's indexed at 1 (as they did previously). However, this is no longer the case. (Updated config to reflect this) - Remove un-necessary env.reset(). (We already reset at the start of the notebook - users can just run-run the notebook) --- .../_package_data/data_manipulation.yaml | 12 +- .../Data-Manipulation-E2E-Demonstration.ipynb | 145 +++++++++--------- tests/assets/configs/data_manipulation.yaml | 12 +- 3 files changed, 83 insertions(+), 86 deletions(-) diff --git a/src/primaite/config/_package_data/data_manipulation.yaml b/src/primaite/config/_package_data/data_manipulation.yaml index 7d9fdf36..70dd6030 100644 --- a/src/primaite/config/_package_data/data_manipulation.yaml +++ b/src/primaite/config/_package_data/data_manipulation.yaml @@ -404,7 +404,7 @@ agents: action: "router-acl-add-rule" options: target_router: router_1 - position: 1 + position: 0 permission: DENY src_ip: 192.168.10.21 # client 1 dst_ip: ALL # ALL @@ -417,7 +417,7 @@ agents: action: "router-acl-add-rule" options: target_router: router_1 - position: 2 + position: 1 permission: DENY src_ip: 192.168.10.22 # client 2 dst_ip: ALL # ALL @@ -430,7 +430,7 @@ agents: action: "router-acl-add-rule" options: target_router: router_1 - position: 3 + position: 2 permission: DENY src_ip: 192.168.10.21 # client 1 dst_ip: 192.168.1.12 # web server @@ -443,7 +443,7 @@ agents: action: "router-acl-add-rule" options: target_router: router_1 - position: 4 + position: 3 permission: DENY src_ip: 192.168.10.22 # client 2 dst_ip: 192.168.1.12 # web server @@ -456,7 +456,7 @@ agents: action: "router-acl-add-rule" options: target_router: router_1 - position: 5 + position: 4 permission: DENY src_ip: 192.168.10.21 # client 1 dst_ip: 192.168.1.14 # database @@ -469,7 +469,7 @@ agents: action: "router-acl-add-rule" options: target_router: router_1 - position: 6 + position: 5 permission: DENY src_ip: 192.168.10.22 # client 2 dst_ip: 192.168.1.14 # database diff --git a/src/primaite/notebooks/Data-Manipulation-E2E-Demonstration.ipynb b/src/primaite/notebooks/Data-Manipulation-E2E-Demonstration.ipynb index 159d2caa..036f4872 100644 --- a/src/primaite/notebooks/Data-Manipulation-E2E-Demonstration.ipynb +++ b/src/primaite/notebooks/Data-Manipulation-E2E-Demonstration.ipynb @@ -121,42 +121,50 @@ "## Observation Space\n", "\n", "The blue agent's observation space is structured as nested dictionary with the following information:\n", - "```\n", + "``` yaml\n", "\n", + "- ICS\n", + "- LINKS\n", + " - \n", + " - PROTOCOLS\n", + " - \n", + " - load\n", "- NODES\n", - " - \n", + " - \n", " - SERVICES\n", - " - \n", + " - \n", " - operating_status\n", " - health_status\n", " - FOLDERS\n", - " - \n", + " - \n", " - health_status\n", " - FILES\n", - " - \n", + " - \n", " - health_status\n", " - NETWORK_INTERFACES\n", - " - \n", + " - \n", " - nic_status\n", " - nmne\n", " - inbound\n", " - outbound\n", " - operating_status\n", - "- LINKS\n", - " - \n", - " - PROTOCOLS\n", - " - ALL\n", - " - load\n", - "- ACL\n", - " - \n", - " - position\n", - " - permission\n", - " - source_node_id\n", - " - source_port\n", - " - dest_node_id\n", - " - dest_port\n", - " - protocol\n", - "- ICS\n", + " - users \n", + " - local_login\n", + " - remote_sessions\n", + " - \n", + " - ACL\n", + " - \n", + " - position\n", + " - permission\n", + " - source_node_id\n", + " - source_port\n", + " - dest_node_id\n", + " - dest_port\n", + " - protocol\n", + " - users \n", + " - local_login\n", + " - remote_session\n", + "\n", "```\n", "\n", "### Mappings\n", @@ -447,13 +455,20 @@ " red_info : AgentHistoryItem = info['agent_actions']['data_manipulation_attacker']\n", " red_action = red_info.action\n", " if red_action == 'do-nothing':\n", - " red_str = 'DO NOTHING'\n", + " red_str = \"do-nothing\"\n", " elif red_action == 'node-application-execute':\n", - " client = \"client 1\" if red_info.parameters['node_name'] == 0 else \"client 2\"\n", + " client = \"client 1\" if red_info.parameters['node_name'] == \"client_1\" else \"client_2\"\n", " red_str = f\"ATTACK from {client}\"\n", " return red_str" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Also, the NMNE outbound of either client 1 (node 5) or client 2 (node 6) has increased from 0 to 1. This tells us which client is being used by the red agent." + ] + }, { "cell_type": "code", "execution_count": null, @@ -462,7 +477,25 @@ "source": [ "for step in range(35):\n", " obs, reward, terminated, truncated, info = env.step(0)\n", - " print(f\"step: {env.game.step_counter}, Red action: {friendly_output_red_action(info)}, Blue reward:{reward:.2f}\" )" + " red_info : AgentHistoryItem = info['agent_actions']['data_manipulation_attacker']\n", + " red_action = red_info.action\n", + " if red_action == 'do-nothing':\n", + " pass\n", + " else:\n", + " # Immediate drop in reward from the red agent attack.\n", + " print(f\"step: {env.game.step_counter}, Red action: {friendly_output_red_action(info)}, Blue reward: {reward:.2f}\" )\n", + " print(f\"step: {env.game.step_counter}, client 1 NMNE: {obs['NODES']['HOST5']['NICS'][1]['NMNE']}\")\n", + " print(f\"step: {env.game.step_counter}, client 2 NMNE: {obs['NODES']['HOST6']['NICS'][1]['NMNE']}\")\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Reward drops even further as green agents are unable to access the web-server after the red agent attack\n", + "print(f\"step: {env.game.step_counter}, Current (Post Attack) Blue reward: {reward:.2f}\" )" ] }, { @@ -472,20 +505,11 @@ "Now the reward is -0.8, let's have a look at blue agent's observation." ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "pprint(obs['NODES'])" - ] - }, { "cell_type": "markdown", "metadata": {}, "source": [ - "The true statuses of the database file and webapp are not updated. The blue agent needs to perform a scan to see that they have degraded." + "The true statuses of the database file and web-server are not updated. The blue agent needs to perform a scan to see that they have degraded." ] }, { @@ -495,26 +519,19 @@ "outputs": [], "source": [ "obs, reward, terminated, truncated, info = env.step(9) # scan database file\n", - "obs, reward, terminated, truncated, info = env.step(1) # scan webapp service\n", - "\n", - "pprint(obs['NODES'])\n" + "print(f\"step: {env.game.step_counter}, database file obs: {obs['NODES']['HOST2']['FOLDERS'][1]['FILES']}\")\n", + "obs, reward, terminated, truncated, info = env.step(1) # scan web-server service\n", + "print(f\"step: {env.game.step_counter}, webserver status {obs['NODES']['HOST1']['SERVICES'][1]}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Now service 1 on HOST1 has `health_status = 3`, indicating that the webapp is compromised.\n", + "Now service 1 on HOST1 has `health_status = 3`, indicating that the web-server is compromised.\n", "File 1 in folder 1 on HOST2 has `health_status = 2`, indicating that the database file is compromised." ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Also, the NMNE outbound of either client 1 (node 6) or client 2 (node 7) has increased from 0 to 1. This tells us which client is being used by the red agent." - ] - }, { "cell_type": "markdown", "metadata": {}, @@ -533,7 +550,7 @@ "print(f\"Red action: {info['agent_actions']['data_manipulation_attacker'].action}\" )\n", "print(f\"Green action: {info['agent_actions']['client_1_green_user'].action}\" )\n", "print(f\"Green action: {info['agent_actions']['client_2_green_user'].action}\" )\n", - "print(f\"Blue reward:{reward}\" )" + "print(f\"Blue reward: {reward}\" )" ] }, { @@ -556,9 +573,9 @@ "obs, reward, terminated, truncated, info = env.step(0) # do nothing\n", "print(f\"step: {env.game.step_counter}\")\n", "print(f\"Red action: {info['agent_actions']['data_manipulation_attacker'].action}\" )\n", - "print(f\"Green action: {info['agent_actions']['client_2_green_user']}\" )\n", - "print(f\"Green action: {info['agent_actions']['client_1_green_user']}\" )\n", - "print(f\"Blue reward:{reward:.2f}\" )" + "print(f\"Green action: {info['agent_actions']['client_2_green_user'].action}\" )\n", + "print(f\"Green action: {info['agent_actions']['client_1_green_user'].action}\" )\n", + "print(f\"Blue reward: {reward:.2f}\" )" ] }, { @@ -603,7 +620,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Let's also have a look at the ACL observation to verify our new ACL rule at positions 5 and 6." + "Let's also have a look at the ACL observation to verify our new ACL rule at positions 4 and 5." ] }, { @@ -612,7 +629,8 @@ "metadata": {}, "outputs": [], "source": [ - "obs['NODES']['ROUTER0']" + "pprint(obs['NODES']['ROUTER0']['ACL'][4])\n", + "pprint(obs['NODES']['ROUTER0']['ACL'][5])" ] }, { @@ -685,36 +703,15 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Reset the environment, you can rerun the other cells to verify that the attack works the same every episode. (except the red agent will move between `client_1` and `client_2`.)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "env.reset()" + "You can rerun the notebook to verify that the attack works the same every episode. (except the red agent will move between `client_1` and `client_2`.)" ] } ], "metadata": { "kernelspec": { - "display_name": ".venv", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.12" } }, "nbformat": 4, diff --git a/tests/assets/configs/data_manipulation.yaml b/tests/assets/configs/data_manipulation.yaml index 59f97644..ea92aab8 100644 --- a/tests/assets/configs/data_manipulation.yaml +++ b/tests/assets/configs/data_manipulation.yaml @@ -403,7 +403,7 @@ agents: action: "router-acl-add-rule" options: target_router: router_1 - position: 1 + position: 0 permission: DENY src_ip: 192.168.10.21 # client 1 dst_ip: ALL # ALL @@ -416,7 +416,7 @@ agents: action: "router-acl-add-rule" options: target_router: router_1 - position: 2 + position: 1 permission: DENY src_ip: 192.168.10.22 # client 2 dst_ip: ALL # ALL @@ -429,7 +429,7 @@ agents: action: "router-acl-add-rule" options: target_router: router_1 - position: 3 + position: 2 permission: DENY src_ip: 192.168.10.21 # client 1 dst_ip: 192.168.1.12 # web server @@ -442,7 +442,7 @@ agents: action: "router-acl-add-rule" options: target_router: router_1 - position: 4 + position: 3 permission: DENY src_ip: 192.168.10.22 # client 2 dst_ip: 192.168.1.12 # web server @@ -455,7 +455,7 @@ agents: action: "router-acl-add-rule" options: target_router: router_1 - position: 5 + position: 4 permission: DENY src_ip: 192.168.10.21 # client 1 dst_ip: 192.168.1.14 # database @@ -468,7 +468,7 @@ agents: action: "router-acl-add-rule" options: target_router: router_1 - position: 6 + position: 5 permission: DENY src_ip: 192.168.10.22 # client 2 dst_ip: 192.168.1.14 # database