Files
PrimAITE/src/primaite/notebooks/Command-&-Control-E2E-Demonstration.ipynb

1202 lines
35 KiB
Plaintext
Raw Normal View History

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Command and Control Application Suite E2E Demonstration\n",
"\n",
"© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK\n",
"\n",
"This notebook demonstrates the current implementation of the command and control (C2) server and beacon applications in primAITE."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Imports\n",
"from primaite.config.load import data_manipulation_config_path\n",
"from primaite.session.environment import PrimaiteGymEnv\n",
"from primaite.simulator.network.hardware.nodes.network.router import Router\n",
"from primaite.game.agent.interface import AgentHistoryItem\n",
"import yaml\n",
"from pprint import pprint\n",
"from primaite.simulator.network.container import Network\n",
"from primaite.game.game import PrimaiteGame\n",
"from primaite.simulator.system.applications.application import ApplicationOperatingState\n",
"from primaite.simulator.system.applications.red_applications.c2.c2_beacon import C2Beacon\n",
"from primaite.simulator.system.applications.red_applications.c2.c2_server import C2Server\n",
"from primaite.simulator.system.applications.red_applications.c2.abstract_c2 import C2Command, C2Payload\n",
"from primaite.simulator.system.applications.red_applications.ransomware_script import RansomwareScript\n",
"from primaite.simulator.system.software import SoftwareHealthState\n",
"from primaite.simulator.network.hardware.nodes.host.computer import Computer\n",
"from primaite.simulator.network.hardware.nodes.host.server import Server"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## **Notebook Setup** | **Network Configuration:**\n",
"\n",
"This notebook uses the same network setup as UC2. Please refer to the main [UC2-E2E-Demo notebook for further reference](./Data-Manipulation-E2E-Demonstration.ipynb).\n",
"\n",
"However, this notebook will replaces with the red agent used in UC2 with a custom proxy red agent built for this notebook."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"custom_c2_agent = \"\"\"\n",
" - ref: CustomC2Agent\n",
" team: RED\n",
" type: ProxyAgent\n",
" observation_space: null\n",
" action_space:\n",
" action_list:\n",
" - type: DONOTHING\n",
" - type: NODE_APPLICATION_INSTALL\n",
" - type: NODE_APPLICATION_EXECUTE\n",
" - type: CONFIGURE_C2_BEACON\n",
" - type: C2_SERVER_RANSOMWARE_LAUNCH\n",
" - type: C2_SERVER_RANSOMWARE_CONFIGURE\n",
" - type: C2_SERVER_TERMINAL_COMMAND\n",
" options:\n",
" nodes:\n",
" - node_name: web_server\n",
" applications: \n",
" - application_name: C2Beacon\n",
" - node_name: client_1\n",
" applications: \n",
" - application_name: C2Server\n",
" max_folders_per_node: 1\n",
" max_files_per_folder: 1\n",
" max_services_per_node: 2\n",
" max_nics_per_node: 8\n",
" max_acl_rules: 10\n",
" ip_list:\n",
" - 192.168.1.21\n",
" - 192.168.1.14\n",
" wildcard_list:\n",
" - 0.0.0.1\n",
" action_map:\n",
" 0:\n",
" action: DONOTHING\n",
" options: {}\n",
" 1:\n",
" action: NODE_APPLICATION_INSTALL\n",
" options:\n",
" node_id: 0\n",
" application_name: C2Beacon\n",
" 2:\n",
" action: CONFIGURE_C2_BEACON\n",
" options:\n",
" node_id: 0\n",
" config:\n",
" c2_server_ip_address: 192.168.10.21\n",
" keep_alive_frequency:\n",
" masquerade_protocol:\n",
" masquerade_port:\n",
" 3:\n",
" action: NODE_APPLICATION_EXECUTE\n",
" options:\n",
" node_id: 0\n",
" application_id: 0 \n",
" 4:\n",
" action: C2_SERVER_TERMINAL_COMMAND\n",
" options:\n",
" node_id: 1\n",
" ip_address:\n",
" account:\n",
" username: admin\n",
" password: admin\n",
" commands:\n",
" - \n",
" - software_manager\n",
" - application\n",
" - install\n",
" - RansomwareScript\n",
" 5:\n",
" action: C2_SERVER_RANSOMWARE_CONFIGURE\n",
" options:\n",
" node_id: 1\n",
" config:\n",
" server_ip_address: 192.168.1.14\n",
" payload: ENCRYPT\n",
" 6:\n",
" action: C2_SERVER_RANSOMWARE_LAUNCH\n",
" options:\n",
" node_id: 1\n",
" 7:\n",
" action: CONFIGURE_C2_BEACON\n",
" options:\n",
" node_id: 0\n",
" config:\n",
" c2_server_ip_address: 192.168.10.21\n",
" keep_alive_frequency: 10\n",
" masquerade_protocol: TCP\n",
" masquerade_port: DNS\n",
"\n",
"\n",
"\n",
" reward_function:\n",
" reward_components:\n",
" - type: DUMMY\n",
"\"\"\"\n",
"c2_agent_yaml = yaml.safe_load(custom_c2_agent)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"with open(data_manipulation_config_path()) as f:\n",
" cfg = yaml.safe_load(f)\n",
" # removing all agents & adding the custom agent.\n",
" cfg['agents'] = {}\n",
" cfg['agents'] = c2_agent_yaml\n",
" \n",
"\n",
"env = PrimaiteGymEnv(env_config=cfg)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## **Notebook Setup** | Network Prerequisites\n",
"\n",
"Before the Red Agent is able to perform any C2 specific actions, the C2 Server needs to be installed and run before the episode begins.\n",
"\n",
"This is because higher fidelity environments (and the real-world) a C2 server would not be accessible by private network blue agent and the C2 Server would already be in place before the an adversary (Red Agent) before the narrative of the use case.\n",
"\n",
"The cells below installs and runs the C2 Server on the client_1 directly via the simulation API."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"client_1: Computer = env.game.simulation.network.get_node_by_hostname(\"client_1\")\n",
"client_1.software_manager.install(C2Server)\n",
"c2_server: C2Server = client_1.software_manager.software[\"C2Server\"]\n",
"c2_server.run()\n",
"client_1.software_manager.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## **Command and Control** | C2 Beacon Actions\n",
"\n",
"Before any C2 Server commands is able to accept any commands, it must first establish connection with a C2 beacon.\n",
"\n",
"This can be done by installing, configuring and then executing a C2 Beacon. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### **Command and Control** | C2 Beacon Actions | Installation"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"env.step(1)\n",
"web_server: Computer = env.game.simulation.network.get_node_by_hostname(\"web_server\")\n",
"web_server.software_manager.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### **Command and Control** | C2 Beacon Actions | Configuration"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"env.step(2)\n",
"c2_beacon: C2Beacon = web_server.software_manager.software[\"C2Beacon\"]\n",
"web_server.software_manager.show()\n",
"c2_beacon.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### **Command and Control** | C2 Beacon Actions | Establishing Connection"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"env.step(3) "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"c2_beacon.show()\n",
"c2_server.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## **Command and Control** | C2 Server Actions"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### **Command and Control** | C2 Server Actions | Executing Terminal Commands"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"env.step(4)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"client_1.software_manager.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### **Command and Control** | C2 Server Actions | Configuring Ransomware"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"env.step(5)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"env.step(6)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"ransomware_script: RansomwareScript = web_server.software_manager.software[\"RansomwareScript\"]\n",
"web_server.software_manager.show()\n",
"ransomware_script.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### **Command and Control** | C2 Server Actions | Launching Ransomware"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"env.step(6)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"database_server: Server = env.game.simulation.network.get_node_by_hostname(\"database_server\")\n",
"database_server.software_manager.file_system.show(full=True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## **Command and Control** | Blue Agent Relevance\n",
"\n",
"The next section of the notebook will demonstrate the impact that the command and control suite has to the Blue Agent's observation space as well as some potential actions that can be used to prevent the attack from being successfully.\n",
"\n",
"The code cell below re-creates the UC2 network and swaps out the previous custom red agent with a custom blue agent. \n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"custom_blue_agent_yaml = \"\"\" \n",
" - ref: defender\n",
" team: BLUE\n",
" type: ProxyAgent\n",
"\n",
" observation_space:\n",
" type: CUSTOM\n",
" options:\n",
" components:\n",
" - type: NODES\n",
" label: NODES\n",
" options:\n",
" hosts:\n",
" - hostname: web_server\n",
" applications:\n",
" - application_name: C2Beacon\n",
" - application_name: RansomwareScript\n",
" - hostname: database_server\n",
" folders:\n",
" - folder_name: database\n",
" files:\n",
" - file_name: database.db\n",
" - hostname: client_1\n",
" - hostname: client_2\n",
" num_services: 0\n",
" num_applications: 2\n",
" num_folders: 1\n",
" num_files: 1\n",
" num_nics: 0\n",
" include_num_access: false\n",
" include_nmne: false\n",
" monitored_traffic:\n",
" icmp:\n",
" - NONE\n",
" tcp:\n",
" - HTTP\n",
" routers:\n",
" - hostname: router_1\n",
" num_ports: 1\n",
" ip_list:\n",
" - 192.168.10.21\n",
" - 192.168.1.12\n",
" wildcard_list:\n",
" - 0.0.0.1\n",
" port_list:\n",
" - 80\n",
" protocol_list:\n",
" - ICMP\n",
" - TCP\n",
" - UDP\n",
" num_rules: 10\n",
"\n",
" - type: LINKS\n",
" label: LINKS\n",
" options:\n",
" link_references:\n",
" - router_1:eth-1<->switch_1:eth-8\n",
" - router_1:eth-2<->switch_2:eth-8\n",
" - switch_1:eth-1<->web_server:eth-1\n",
" - switch_1:eth-2<->web_server:eth-1\n",
" - switch_1:eth-3<->database_server:eth-1\n",
" - switch_1:eth-4<->backup_server:eth-1\n",
" - switch_1:eth-7<->security_suite:eth-1\n",
" - switch_2:eth-1<->client_1:eth-1\n",
" - switch_2:eth-2<->client_2:eth-1\n",
" - switch_2:eth-7<->security_suite:eth-2\n",
" - type: \"NONE\"\n",
" label: ICS\n",
" options: {}\n",
" \n",
" action_space:\n",
" action_list:\n",
" - type: NODE_APPLICATION_REMOVE\n",
" - type: NODE_SHUTDOWN\n",
" - type: ROUTER_ACL_ADDRULE\n",
" - type: DONOTHING\n",
" action_map:\n",
" 0:\n",
" action: DONOTHING\n",
" options: {}\n",
" 1:\n",
" action: NODE_APPLICATION_REMOVE\n",
" options:\n",
" node_id: 0\n",
" application_name: C2Beacon\n",
" 2:\n",
" action: NODE_SHUTDOWN\n",
" options:\n",
" node_id: 0\n",
" 3:\n",
" action: ROUTER_ACL_ADDRULE\n",
" options:\n",
" target_router: router_1\n",
" position: 1\n",
" permission: 2\n",
" source_ip_id: 2\n",
" dest_ip_id: 3\n",
" source_port_id: 2\n",
" dest_port_id: 2\n",
" protocol_id: 1\n",
" source_wildcard_id: 0\n",
" dest_wildcard_id: 0 \n",
"\n",
"\n",
" options:\n",
" nodes:\n",
" - node_name: web_server\n",
" applications:\n",
" - application_name: C2Beacon\n",
"\n",
" - node_name: database_server\n",
" folders:\n",
" - folder_name: database\n",
" files:\n",
" - file_name: database.db\n",
" services:\n",
" - service_name: DatabaseService\n",
" - node_name: router_1\n",
"\n",
" max_folders_per_node: 2\n",
" max_files_per_folder: 2\n",
" max_services_per_node: 2\n",
" max_nics_per_node: 8\n",
" max_acl_rules: 10\n",
" ip_list:\n",
" - 192.168.10.21\n",
" - 192.168.1.12\n",
" wildcard_list:\n",
" - 0.0.0.1\n",
" reward_function:\n",
" reward_components:\n",
" - type: DUMMY\n",
"\n",
" agent_settings:\n",
" flatten_obs: False\n",
"\"\"\"\n",
"custom_blue = yaml.safe_load(custom_blue_agent_yaml)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"with open(data_manipulation_config_path()) as f:\n",
" cfg = yaml.safe_load(f)\n",
" # removing all agents & adding the custom agent.\n",
" cfg['agents'] = {}\n",
" cfg['agents'] = custom_blue\n",
" \n",
"\n",
"blue_env = PrimaiteGymEnv(env_config=cfg)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Utility function for showing OBS changes between each time step.\n",
"\n",
"from deepdiff.diff import DeepDiff\n",
"\n",
"def display_obs_diffs(old, new, step_counter):\n",
" \"\"\"\n",
" Use DeepDiff to extract and display differences in old and new instances of\n",
" the observation space.\n",
"\n",
" :param old: observation space instance.\n",
" :param new: observation space instance.\n",
" :param step_counter: current step counter.\n",
" \"\"\"\n",
" print(\"\\nObservation space differences\")\n",
" print(\"-----------------------------\")\n",
" diff = DeepDiff(old, new)\n",
" print(f\"Step {step_counter}\")\n",
" for d,v in diff.get('values_changed', {}).items():\n",
" print(f\"{d}: {v['old_value']} -> {v['new_value']}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### **Command and Control** | Blue Agent Relevance | Observation Space\n",
"\n",
"This section demonstrates the OBS impact if the C2 suite is successfully installed and then used to install, configure and launch the ransomwarescript."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Resetting the environment and capturing the default observation space.\n",
"blue_env.reset()\n",
"default_obs, _, _, _, _ = blue_env.step(0)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Setting up the C2 Suite via the simulation API.\n",
"\n",
"client_1: Computer = blue_env.game.simulation.network.get_node_by_hostname(\"client_1\")\n",
"web_server: Server = blue_env.game.simulation.network.get_node_by_hostname(\"web_server\")\n",
"\n",
"# Installing the C2 Server.\n",
"client_1.software_manager.install(C2Server)\n",
"c2_server: C2Server = client_1.software_manager.software[\"C2Server\"]\n",
"c2_server.run()\n",
"\n",
"# Installing the C2 Beacon.\n",
"web_server.software_manager.install(C2Beacon)\n",
"c2_beacon: C2Beacon = web_server.software_manager.software[\"C2Beacon\"]\n",
"c2_beacon.configure(c2_server_ip_address=\"192.168.10.21\")\n",
"c2_beacon.establish()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Capturing the observation impacts of the previous code cell: C2 Suite setup.\n",
"c2_configuration_obs, _, _, _, _ = blue_env.step(0)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"display_obs_diffs(default_obs, c2_configuration_obs, blue_env.game.step_counter)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Installing RansomwareScript via C2 Terminal Commands\n",
"ransomware_install_command = {\"commands\":[[\"software_manager\", \"application\", \"install\", \"RansomwareScript\"]],\n",
" \"username\": \"admin\",\n",
" \"password\": \"admin\"}\n",
"c2_server.send_command(C2Command.TERMINAL, command_options=ransomware_install_command)\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Configuring the RansomwareScript\n",
"ransomware_config = {\"server_ip_address\": \"192.168.1.14\", \"payload\": \"ENCRYPT\"}\n",
"c2_server.send_command(C2Command.RANSOMWARE_CONFIGURE, command_options=ransomware_config)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Capturing the observation impacts of the previous code cell: Ransomware installation & configuration.\n",
"c2_ransomware_obs, _, _, _, _ = blue_env.step(0)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The code cell below demonstrates the differences between the default observation space and the configuration of the C2 Server and the Ransomware installation."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"display_obs_diffs(default_obs, c2_ransomware_obs, env.game.step_counter)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Waiting for the ransomware to finish installing and then launching the RansomwareScript.\n",
"blue_env.step(0)\n",
"c2_server.send_command(C2Command.RANSOMWARE_LAUNCH, command_options={})"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Capturing the observation impacts of the previous code cell: Launching the RansomwareScript.\n",
"c2_final_obs, _, _, _, _ = blue_env.step(0)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The code cell below demonstrates the differences between the default observation space and the configuration of the C2 Server, the ransomware script installation as well as the impact of RansomwareScript upon the database."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"display_obs_diffs(c2_ransomware_obs, c2_final_obs, blue_env.game.step_counter)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### **Command and Control** | Blue Agent Relevance | Action Space\n",
"\n",
"The next section of this notebook will go over some potential blue agent actions that could be use to thwart the previously demonstrated attack."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# This method is used to shorthand setting up the C2Server and the C2 Beacon.\n",
"def c2_setup(given_env: PrimaiteGymEnv):\n",
" client_1: Computer = given_env.game.simulation.network.get_node_by_hostname(\"client_1\")\n",
" web_server: Server = given_env.game.simulation.network.get_node_by_hostname(\"web_server\")\n",
"\n",
" client_1.software_manager.install(C2Server)\n",
" c2_server: C2Server = client_1.software_manager.software[\"C2Server\"]\n",
" c2_server.run()\n",
"\n",
" web_server.software_manager.install(C2Beacon)\n",
" c2_beacon: C2Beacon = web_server.software_manager.software[\"C2Beacon\"]\n",
" c2_beacon.configure(c2_server_ip_address=\"192.168.10.21\")\n",
" c2_beacon.establish()\n",
"\n",
" return given_env, c2_server, c2_beacon, client_1, web_server"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Removing the C2 Beacon.\n",
"\n",
"The simplest way a blue agent could prevent the C2 suite is by simply removing the C2 beacon from it's installation point. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"blue_env.reset()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Setting up the C2 Suite using the c2_setup method & capturing the OBS impacts\n",
"\n",
"blue_env, c2_server, c2_beacon, client_1, web_server = c2_setup(given_env=blue_env)\n",
"pre_blue_action_obs, _, _, _, _ = blue_env.step(0)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The code cell below uses the custom blue agent defined at the start of this section perform NODE_APPLICATION_REMOVE on the C2 beacon"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Using CAOS ACTION: NODE_APPLICATION_REMOVE & capturing the OBS\n",
"post_blue_action_obs, _, _, _, _ = blue_env.step(1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Which we can see after the effects of after stepping another timestep and looking at the web_servers software manager and the OBS differences."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"blue_env.step(0)\n",
"web_server.software_manager.show()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"display_obs_diffs(pre_blue_action_obs, post_blue_action_obs, blue_env.game.step_counter)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now we are unable to do so as the C2 Server is unable has lost it's connection to the C2 Beacon:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Attempting to install the C2 RansomwareScript\n",
"ransomware_install_command = {\"commands\":[[\"software_manager\", \"application\", \"install\", \"RansomwareScript\"]],\n",
" \"username\": \"admin\",\n",
" \"password\": \"admin\"}\n",
"\n",
"c2_server: C2Server = client_1.software_manager.software[\"C2Server\"]\n",
"c2_server.send_command(C2Command.TERMINAL, command_options=ransomware_install_command)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Shutting down the node infected with a C2 Beacon.\n",
"\n",
"Another way a blue agent can prevent the C2 suite is via shutting down the C2 beacon's host node. Whilst not as effective as the previous option, dependant on situation (such as multiple malicious applications) or other scenarios it may be more timestep efficient for a blue agent to shut down a node directly."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"blue_env.reset()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Setting up the C2 Suite using the c2_setup method & capturing the OBS impacts\n",
"\n",
"blue_env, c2_server, c2_beacon, client_1, web_server = c2_setup(given_env=blue_env)\n",
"pre_blue_action_obs, _, _, _, _ = blue_env.step(0)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The code cell below uses the custom blue agent defined at the start of this section perform NODE_SHUT_DOWN on the web server."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Using CAOS ACTION: NODE_SHUT_DOWN & capturing the OBS\n",
"post_blue_action_obs, _, _, _, _ = blue_env.step(2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Which we can see after the effects of after stepping another timestep and looking at the web_servers operating state & the OBS differences."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"web_server = blue_env.game.simulation.network.get_node_by_hostname(\"web_server\")\n",
"print(web_server.operating_state)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"display_obs_diffs(pre_blue_action_obs, post_blue_action_obs, blue_env.game.step_counter)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Attempting to install the C2 RansomwareScript\n",
"ransomware_install_command = {\"commands\":[[\"software_manager\", \"application\", \"install\", \"RansomwareScript\"]],\n",
" \"username\": \"admin\",\n",
" \"password\": \"admin\"}\n",
"\n",
"c2_server: C2Server = client_1.software_manager.software[\"C2Server\"]\n",
"c2_server.send_command(C2Command.TERMINAL, command_options=ransomware_install_command)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Blocking C2 Traffic via ACL.\n",
"\n",
"Another potential option a blue agent could take is by placing an ACL rule which blocks traffic between the C2 Server can C2 Beacon.\n",
"\n",
"It's worth noting the potential effectiveness of approach is also linked by the current green agent traffic on the network. The same applies for the previous example."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"blue_env.reset()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Setting up the C2 Suite using the c2_setup method & capturing the OBS impacts\n",
"\n",
"blue_env, c2_server, c2_beacon, client_1, web_server = c2_setup(given_env=blue_env)\n",
"pre_blue_action_obs, _, _, _, _ = blue_env.step(0)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The code cell below uses the custom blue agent defined at the start of this section to perform a ROUTER_ACL_ADDRULE on router 1."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Using CAOS ACTION: ROUTER_ACL_ADDRULE & capturing the OBS\n",
"post_blue_action_obs, _, _, _, _ = blue_env.step(3)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Which we can see after the effects of after stepping another timestep and looking at router 1's ACLs and the OBS differences."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"router_1: Router = blue_env.game.simulation.network.get_node_by_hostname(\"router_1\")\n",
"router_1.acl.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now we can see that the C2 applications are unable to maintain connection - thus being unable to execute correctly."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"blue_env.step(0)\n",
"\n",
"# Attempting to install and execute the ransomware script\n",
"c2_server.send_command(C2Command.TERMINAL, command_options=ransomware_install_command)\n",
"c2_server.send_command(C2Command.RANSOMWARE_LAUNCH, command_options={})"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"router_1.acl.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Because of the ACL rule the C2 beacon never received the ransomware installation and execute commands from the C2 server:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"web_server.software_manager.show()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"database_server: Server = blue_env.game.simulation.network.get_node_by_hostname(\"database_server\")\n",
"database_server.software_manager.file_system.show(full=True)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"display_obs_diffs(pre_blue_action_obs, post_blue_action_obs, blue_env.game.step_counter)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## **Command and Control** | C2 Beacon Actions\n",
"\n",
"Before any C2 Server commands is able to accept any commands, it must first establish connection with a C2 beacon.\n",
"\n",
"This can be done by installing, configuring and then executing a C2 Beacon. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## **Command and Control** | Configurability \n",
"\n",
"TODO: Fleshout"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"with open(data_manipulation_config_path()) as f:\n",
" cfg = yaml.safe_load(f)\n",
" # removing all agents & adding the custom agent.\n",
" cfg['agents'] = {}\n",
" cfg['agents'] = c2_agent_yaml\n",
" \n",
"\n",
"c2_config_env = PrimaiteGymEnv(env_config=cfg)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Installing the C2 Server"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"client_1: Computer = c2_config_env.game.simulation.network.get_node_by_hostname(\"client_1\")\n",
"client_1.software_manager.install(C2Server)\n",
"c2_server: C2Server = client_1.software_manager.software[\"C2Server\"]\n",
"c2_server.run()\n",
"client_1.software_manager.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Installing the C2 Beacon via NODE_APPLICATION_INSTALL"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"c2_config_env.step(1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Configuring the C2 Beacon using different parameters:\n",
"\n",
"``` yaml\n",
" action: CONFIGURE_C2_BEACON\n",
" options:\n",
" node_id: 0\n",
" config:\n",
" c2_server_ip_address: 192.168.10.21\n",
" keep_alive_frequency: 10\n",
" masquerade_protocol: TCP\n",
" masquerade_port: DNS\n",
"```"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"c2_config_env.step(7)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Establishing connection to the C2 Server.\n",
"c2_config_env.step(3)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"web_server: Server = c2_config_env.game.simulation.network.get_node_by_hostname(\"web_server\")\n",
"c2_beacon: C2Beacon = web_server.software_manager.software[\"C2Beacon\"]\n",
"c2_beacon.show()\n",
"c2_server.show()"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "venv",
"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,
"nbformat_minor": 2
}