1711 lines
65 KiB
Plaintext
1711 lines
65 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# TAP003 - Malicious Insider Kill Chain\n",
|
|
"\n",
|
|
"© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK\n",
|
|
"\n",
|
|
"**Threat Actor Profile (TAP):** 003 <br/>\n",
|
|
"**Kill Chain**: Insider"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"This notebook demonstrates the new TAP003 red agent which simulates a malicious insider which performs an internal cyber attack. In this scenario an malicious `some_tech` admin leverages their legitimate credentials and permissions to create purposeful backdoors, establish footholds and use other legitimate features in malicious ways.\n",
|
|
"<br/>\n",
|
|
"\n",
|
|
"In this version of PrimAITE, TAP003 opts to alter user accounts and implement malicious ACL rule by using the ``terminal`` service to SSH into target routers. These ACLs block green traffic which trigger a negative reward.\n",
|
|
"<br/>\n",
|
|
"\n",
|
|
"This TAP was designed to be both realistic but also dissimilar to the more traditional red agents such as [TAP001](./UC7-TAP001-Kill-Chain-E2E.ipynb) or use case 2's [data_manipulation_bot](./Data-Manipulation-Customising-Red-Agent.ipynb)."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"!primaite setup"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"metadata": {}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Importing the necessary primAITE libraries\n",
|
|
"from primaite.session.environment import PrimaiteGymEnv\n",
|
|
"from primaite.simulator.system.applications.database_client import DatabaseClient\n",
|
|
"from primaite.simulator.system.services.dns.dns_client import DNSClient\n",
|
|
"from primaite.simulator.network.hardware.nodes.host.computer import Computer\n",
|
|
"from primaite.simulator.system.applications.web_browser import WebBrowser\n",
|
|
"from primaite.simulator.network.hardware.nodes.network.router import Router\n",
|
|
"from primaite.game.agent.scripted_agents.TAP003 import TAP003, InsiderKillChain, InsiderKillChainOptions\n",
|
|
"from primaite.config.load import load, _EXAMPLE_CFG\n",
|
|
"from pprint import pprint\n",
|
|
"from deepdiff.diff import DeepDiff\n",
|
|
"from prettytable import PrettyTable\n",
|
|
"import yaml"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Utility functions.\n",
|
|
"\n",
|
|
"def print_agent_actions_except_do_nothing(agent_name):\n",
|
|
" \"\"\"Get the agent's action history, filter out `do-nothing` actions, print relevant data in a table.\"\"\"\n",
|
|
" table = PrettyTable()\n",
|
|
" table.field_names = [\"Step\", \"Action\", \"Node\", \"Application\", \"Target IP\", \"Response\"]\n",
|
|
" print(f\"Episode: {env.episode_counter}, Actions for '{agent_name}':\")\n",
|
|
" for item in env.game.agents[agent_name].history:\n",
|
|
" if item.action == \"do-nothing\":\n",
|
|
" continue\n",
|
|
"\n",
|
|
" node, application, target_ip = \"N/A\", \"N/A\", \"N/A\",\n",
|
|
"\n",
|
|
" if item.action.startswith(\"node-nmap\"):\n",
|
|
" node = item.parameters['source_node']\n",
|
|
" application = \"nmap\"\n",
|
|
" target_ip = str(item.parameters['target_ip_address'])\n",
|
|
" target_ip = (target_ip[:25]+'...') if len(target_ip)>25 else target_ip # truncate long string\n",
|
|
"\n",
|
|
" elif item.action == \"router-acl-add-rule\":\n",
|
|
" node = item.parameters.get(\"router_name\")\n",
|
|
" elif item.action == \"node-send-remote-command\":\n",
|
|
" node = item.parameters.get(\"node_name\")\n",
|
|
" target_ip = item.parameters.get(\"remote_ip\")\n",
|
|
" application = item.parameters.get(\"command\")\n",
|
|
" elif item.action == \"node-session-remote-login\":\n",
|
|
" node = item.parameters.get(\"node_name\")\n",
|
|
" target_ip = item.parameters.get(\"remote_ip\")\n",
|
|
" application = \"user-manager\"\n",
|
|
" elif item.action.startswith(\"c2-server\"):\n",
|
|
" application = \"c2-server\"\n",
|
|
" node = item.parameters.get('node_name')\n",
|
|
" elif item.action == \"configure-c2-beacon\":\n",
|
|
" application = \"c2-beacon\"\n",
|
|
" node = item.parameters.get('node_name')\n",
|
|
"\n",
|
|
" else:\n",
|
|
" if (item.parameters.get('node_name')) is not None:\n",
|
|
" node = item.parameters.get('node_name')\n",
|
|
" if (item.parameters.get('application_name')) is not None:\n",
|
|
" application = item.parameters.get('application_name')\n",
|
|
" if (application_name := item.parameters.get('application_name')) is not None:\n",
|
|
" application = application_name\n",
|
|
"\n",
|
|
" table.add_row([item.timestep, item.action, node, application, target_ip, item.response.status])\n",
|
|
"\n",
|
|
" print(table)\n",
|
|
" print(\"(Any do-nothing actions are omitted)\")\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"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']}\")\n",
|
|
"\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### **Notebook Sections:**\n",
|
|
"1. Notebook Intro\n",
|
|
"2. Notebook Setup\n",
|
|
"3. Prior To Attack\n",
|
|
"4. Kill Chain Stage Demonstration\n",
|
|
"5. Attack Configurations"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### **Notebook Intro** | **Backdoor & Vulnerability Creation Kill Chain Intro** \n",
|
|
"\n",
|
|
"TAP003's kill chain is comprised of a variety of blue actions which are leveraged in unusual ways. This includes introducing malicious ACL's which block green traffic. The rest of this notebook will go through each step in more detail whilst demonstrating the impacts that each step has on both observation and simulation behaviour.\n",
|
|
"\n",
|
|
"_Reconnaissance_\n",
|
|
"\n",
|
|
"|Index | Action Stage| OBS Impact | Narrative |action(s)|\n",
|
|
"|-----|-------------|-------------|-----------|---|\n",
|
|
"|1|Reconnaissance|*No Direct Impact*|TAP003 is passively investigating sensitive systems, data and access control mechanisms.|`do-nothing`|\n",
|
|
"\n",
|
|
"_Planning_\n",
|
|
"\n",
|
|
"|Index| Action Stage| OBS Impact | Narrative |action(s)|\n",
|
|
"|-----|-------------|------------|-----------|---|\n",
|
|
"|2|Planning| **No current impact**|TAP003 is devising a plan to exploit their elevated privileges.|`do-nothing`|\n",
|
|
"\n",
|
|
" _Access_\n",
|
|
"\n",
|
|
"|Index| Action Stage| OBS Impact | Narrative |action(s)|\n",
|
|
"|-----|-------------|------------|-----------|---|\n",
|
|
"|3|Access|**No current impact** |TAP003 uses their legitimate credentials to access the access control settings.|`do-nothing`|\n",
|
|
"\n",
|
|
" _Manipulation_\n",
|
|
" \n",
|
|
"|Index| Action Stage| OBS Impact | Narrative |action(s)|\n",
|
|
"|-----|-------------|------------|-----------|---|\n",
|
|
"|4|Manipulation| **Target Host(s)** HOST::SESSIONS:REMOTE |TAP003 exploits their insider knowledge/privilege to implement changes for sabotage.| - `node-session-remote-login` & `sessions-send-remote-command` (`node-account-change-password`)|\n",
|
|
"\n",
|
|
"_Exploit_\n",
|
|
"\n",
|
|
"|Index| Action Stage| OBS Impact | Narrative |action(s)|\n",
|
|
"|-----|-------------|------------|-----------|---|\n",
|
|
"|5|Exploit| **Target Host(s)** ROUTER:ACL:INTERNAL/EXTERNAL:*|TAP003 exploits their insider knowledge/privilege to implement changes for sabotage.| `node-session-remote-login` & `node-session-send-remote-command` (`router-acl-addrule`) |\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## **Notebook Setup** | **Network Configuration:**\n",
|
|
"\n",
|
|
"Any readers unfamiliar with UC7 can refer to the main [UC7-E2E-Demo notebook for further reference](./UC7-E2E-Demo.ipynb)."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"<p align=\"center\">\n",
|
|
" <a href=\"./_package_data/uc7/uc7_tap003/uc7_tap003_main.png\" target=\"_blank\">\n",
|
|
" <img src=\"./_package_data/uc7/uc7_tap003/uc7_tap003_main.png\" alt=\"Image\" style=\"width:1000px;\">\n",
|
|
" </a> \n",
|
|
" \n",
|
|
"</p>\n",
|
|
"\n",
|
|
"_(Click to enlarge)_"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"metadata": {}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"with open(_EXAMPLE_CFG/\"uc7_config_tap003.yaml\", mode=\"r\") as uc7_config:\n",
|
|
" cfg = yaml.safe_load(uc7_config)\n",
|
|
" cfg[\"agents\"][33][\"agent_settings\"][\"flatten_obs\"] = False\n",
|
|
" cfg['io_settings']['save_agent_logs'] = True\n",
|
|
" cfg['io_settings']['save_sys_logs'] = True # Saving syslogs\n",
|
|
"env = PrimaiteGymEnv(env_config=cfg)\n",
|
|
"env.game.simulation.network.show()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### **Notebook Setup** | Instantiating Relevant Simulation Objects\n",
|
|
"The cell below sets up the relevant simulation and agent objects for the kill chain demonstration.\n",
|
|
"\n",
|
|
"\n",
|
|
"The following cell resets the environment, instantiates TAP003 and it's selected starting/target hosts."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"metadata": {}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"env.reset() # resetting the environment\n",
|
|
"# The TAP003 Agent\n",
|
|
"tap003: TAP003 = env.game.agents['attacker']\n",
|
|
"tap003.logger.logger.setLevel(\"INFO\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## **Prior To Attack** | Initial States:"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"The first section of this notebook displays the initial simulation state of TAP003's starting and target nodes."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"#### **Initial State** | Starting Host:\n",
|
|
"TAP003's initial starting point.\n",
|
|
"\n",
|
|
"TAP003's starting host does not cause any MNE (Malicious Network Events) in it's current implementation."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"metadata": {}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# TAP003's Starting Client:\n",
|
|
"starting_host = env.game.simulation.network.get_node_by_hostname(tap003.starting_node)\n",
|
|
"print(f\"Starting host:\")\n",
|
|
"starting_host.show()\n",
|
|
"starting_host.software_manager.show()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"#### **Initial State** | Target Hosts\n",
|
|
"\n",
|
|
"TAP003's selected target hosts at current the only valid targets for TAP003 are Router/Firewall type nodes\n",
|
|
"\n",
|
|
"Code snippet below shows the default OBS of the target routers"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"metadata": {}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# TAP003's target routers\n",
|
|
"\n",
|
|
"st_intra_prv_rt_cr: Router = env.game.simulation.network.get_node_by_hostname(\"ST_INTRA-PRV-RT-CR\")\n",
|
|
"st_intra_prv_rt_dr_1: Router = env.game.simulation.network.get_node_by_hostname(\"ST_INTRA-PRV-RT-DR-1\")\n",
|
|
"rem_pub_rt_dr: Router = env.game.simulation.network.get_node_by_hostname(\"REM-PUB-RT-DR\")\n",
|
|
"\n",
|
|
"st_intra_prv_rt_cr.acl.show()\n",
|
|
"st_intra_prv_rt_dr_1.acl.show()\n",
|
|
"rem_pub_rt_dr.acl.show()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## **Kill Chain** | Kill Chain Stage Demonstration \n",
|
|
"\n",
|
|
"For the initial kill chain demonstration, TAP003 is configured with the following yaml snippet:\n",
|
|
"\n",
|
|
"```yaml\n",
|
|
" - ref: attacker\n",
|
|
" team: RED\n",
|
|
" type: tap-003\n",
|
|
" observation_space: {}\n",
|
|
" action_space: {}\n",
|
|
" agent_settings:\n",
|
|
" start_step: 1\n",
|
|
" frequency: 3\n",
|
|
" variance: 0\n",
|
|
" repeat_kill_chain: false\n",
|
|
" repeat_kill_chain_stages: true\n",
|
|
" default_starting_node: \"ST_PROJ-A-PRV-PC-1\"\n",
|
|
" starting_nodes:\n",
|
|
" # starting_nodes: [\"ST_PROJ-A-PRV-PC-1\", \"ST_PROJ-B-PRV-PC-2\", \"ST_PROJ-C-PRV-PC-3\"]\n",
|
|
" kill_chain:\n",
|
|
" PLANNING:\n",
|
|
" probability: 1\n",
|
|
" starting_network_knowledge:\n",
|
|
" credentials:\n",
|
|
" ST_PROJ-A-PRV-PC-1:\n",
|
|
" username: admin\n",
|
|
" password: admin\n",
|
|
" ST_PROJ-B-PRV-PC-2:\n",
|
|
" username: admin\n",
|
|
" password: admin\n",
|
|
" ST_PROJ-C-PRV-PC-3:\n",
|
|
" username: admin\n",
|
|
" password: admin\n",
|
|
" ST_INTRA-PRV-RT-DR-1:\n",
|
|
" ip_address: 192.168.230.1\n",
|
|
" username: admin\n",
|
|
" password: admin\n",
|
|
" ST_INTRA-PRV-RT-CR:\n",
|
|
" ip_address: 192.168.160.1\n",
|
|
" username: admin\n",
|
|
" password: admin\n",
|
|
" REM-PUB-RT-DR:\n",
|
|
" ip_address: 192.168.10.2\n",
|
|
" username: admin\n",
|
|
" password: admin\n",
|
|
" ACCESS:\n",
|
|
" probability: 1\n",
|
|
" MANIPULATION:\n",
|
|
" probability: 1\n",
|
|
" account_changes:\n",
|
|
" - host: ST_INTRA-PRV-RT-DR-1\n",
|
|
" ip_address: 192.168.230.1 # ST_INTRA-PRV-RT-DR-1\n",
|
|
" action: change_password\n",
|
|
" username: admin\n",
|
|
" new_password: \"red_pass\"\n",
|
|
" - host: ST_INTRA-PRV-RT-CR\n",
|
|
" ip_address: 192.168.160.1 # ST_INTRA-PRV-RT-CR\n",
|
|
" action: change_password\n",
|
|
" username: \"admin\"\n",
|
|
" new_password: \"red_pass\"\n",
|
|
" - host: REM-PUB-RT-DR\n",
|
|
" ip_address: 192.168.10.2 # REM-PUB-RT-DR\n",
|
|
" action: change_password\n",
|
|
" username: \"admin\"\n",
|
|
" new_password: \"red_pass\"\n",
|
|
" EXPLOIT:\n",
|
|
" probability: 1\n",
|
|
" malicious_acls:\n",
|
|
" - target_router: ST_INTRA-PRV-RT-DR-1\n",
|
|
" position: 1\n",
|
|
" permission: DENY\n",
|
|
" src_ip: ALL\n",
|
|
" src_wildcard: 0.0.255.255\n",
|
|
" dst_ip: ALL\n",
|
|
" dst_wildcard: 0.0.255.255\n",
|
|
" src_port: POSTGRES_SERVER\n",
|
|
" dst_port: POSTGRES_SERVER\n",
|
|
" protocol_name_name: TCP\n",
|
|
" - target_router: ST_INTRA-PRV-RT-CR\n",
|
|
" position: 1\n",
|
|
" permission: DENY\n",
|
|
" src_ip: ALL\n",
|
|
" src_wildcard: 0.0.255.255\n",
|
|
" dst_ip: ALL\n",
|
|
" dst_wildcard: 0.0.255.255\n",
|
|
" src_port: HTTP\n",
|
|
" dst_port: HTTP\n",
|
|
" protocol_name_name: TCP\n",
|
|
" - target_router: REM-PUB-RT-DR\n",
|
|
" position: 1\n",
|
|
" permission: DENY\n",
|
|
" src_ip: ALL\n",
|
|
" src_wildcard: 0.0.255.255\n",
|
|
" dst_ip: ALL\n",
|
|
" dst_wildcard: 0.0.255.255\n",
|
|
" src_port: DNS\n",
|
|
" dst_port: DNS\n",
|
|
" protocol_name_name: TCP\n",
|
|
"\n",
|
|
"```\n",
|
|
"_Further information & guidance around configuring TAP003 can be found within the last section of this notebook._"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### **Kill Chain** | NOT STARTED\n",
|
|
"This is the default state of the TAP003 Agent. This stage indicates that the TAP003 agent has not begun it's kill chain.\n",
|
|
"If TAP003 is in this stage then on the next execution step the kill chain will begin."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"tap003 = env.game.agents['attacker']\n",
|
|
"\n",
|
|
"\n",
|
|
"print(f\"Current Environment Step: {env.game.step_counter}\")\n",
|
|
"print(f\"Current Kill Chain Stage: {tap003.current_kill_chain_stage.name}\")\n",
|
|
"print(f\"Next Execution Step: {tap003.next_execution_timestep}\")\n",
|
|
"print(f\"Next Kill Chain Stage {tap003.next_kill_chain_stage.name}\")\n",
|
|
"while(tap003.current_kill_chain_stage == InsiderKillChain.NOT_STARTED):\n",
|
|
" default_obs, _, _, _, _ = env.step(0)\n",
|
|
"starting_host.software_manager.show()\n",
|
|
"\n",
|
|
"env.step(0);"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"tap003.logger.show()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### **Kill Chain** | RECONNAISSANCE\n",
|
|
"\n",
|
|
"|Index| Action Stage| OBS Impact | Narrative |\n",
|
|
"|-----|-------------|------------|-----------|\n",
|
|
"|1|RECONNAISSANCE|*No Direct Impact*|TAP003 is identifying Sensitive systems, data and access control mechanisms in legitimate ways.|\n",
|
|
"\n",
|
|
"Currently, this stage in the kill chain is implemented via the 'do-nothing' CAOS action."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"metadata": {}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"print(f\"Current Environment Step: {env.game.step_counter}\")\n",
|
|
"print(f\"Current Kill Chain Stage: {tap003.current_kill_chain_stage.name}\")\n",
|
|
"print(f\"Next Execution Step: {tap003.next_execution_timestep}\")\n",
|
|
"print(f\"Next Kill Chain Stage {tap003.next_kill_chain_stage.name}\")\n",
|
|
"\n",
|
|
"while(tap003.current_kill_chain_stage == InsiderKillChain.RECONNAISSANCE):\n",
|
|
" reconnaissance_obs_impact, _, _, _, _ = env.step(0)\n",
|
|
"\n",
|
|
"current_host = env.game.simulation.network.get_node_by_hostname(tap003.current_host)\n",
|
|
"current_host.software_manager.show()\n",
|
|
"display_obs_diffs(default_obs, reconnaissance_obs_impact, env.game.step_counter)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"tap003.logger.show()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### **Kill Chain** | PLANNING\n",
|
|
"\n",
|
|
"|Index| Action Stage| OBS Impact | Narrative |\n",
|
|
"|-----|-------------|------------|-----------|\n",
|
|
"|2|PLANNING| *No Direct Impact*| HOST:APPLICATION|TAP003 is devising a plan to exploit their elevated privileges.|\n",
|
|
"\n",
|
|
"Currently, the TAP003 agent does not perform any actions at this stage of the kill chain."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"metadata": {}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"pprint(\"---TAP003's Current State---\")\n",
|
|
"print(f\"Current Environment Step: {env.game.step_counter}\")\n",
|
|
"print(f\"Current Kill Chain Stage: {tap003.current_kill_chain_stage.name}\")\n",
|
|
"print(f\"Next Execution Step: {tap003.next_execution_timestep}\")\n",
|
|
"print(f\"Next Kill Chain Stage {tap003.next_kill_chain_stage.name}\")\n",
|
|
"pprint(\"---Starting Client State----\")\n",
|
|
"while(tap003.current_kill_chain_stage == InsiderKillChain.PLANNING):\n",
|
|
" planning_obs_impact, _, _, _, info = env.step(0);\n",
|
|
"current_host.software_manager.show()\n",
|
|
"display_obs_diffs(reconnaissance_obs_impact, planning_obs_impact, env.game.step_counter)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"tap003.logger.show()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### **Kill Chain** | ACCESS\n",
|
|
"\n",
|
|
"|Index| Action Stage| OBS Impact | Narrative |\n",
|
|
"|-----|-------------|------------|-----------|\n",
|
|
"|3|Access|_do-nothing CAOS Action_|TAP003 uses their legitimate credentials to access the access control settings.|\n",
|
|
"\n",
|
|
"Currently, at this point of the kill chain stage the TAP003 does not perform any simulations actions. Future versions of TAP003 aim to leverage more of the simulation to create and remove accounts at this stage."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"metadata": {}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"pprint(\"---TAP003's Current State---\")\n",
|
|
"print(f\"Current Environment Step: {env.game.step_counter}\")\n",
|
|
"print(f\"Current Kill Chain Stage: {tap003.current_kill_chain_stage.name}\")\n",
|
|
"print(f\"Next Execution Step: {tap003.next_execution_timestep}\")\n",
|
|
"print(f\"Next Kill Chain Stage {tap003.next_kill_chain_stage.name}\")\n",
|
|
"pprint(\"---Starting Client State----\")\n",
|
|
"while(tap003.current_kill_chain_stage == InsiderKillChain.ACCESS):\n",
|
|
" access_obs_impact, _, _, _, info = env.step(0)\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"\n",
|
|
"# Compare observation space before and after ACCESS stage.\n",
|
|
"display_obs_diffs(planning_obs_impact, access_obs_impact, env.game.step_counter)\n",
|
|
"\n",
|
|
"starting_host.software_manager.show()\n",
|
|
"print_agent_actions_except_do_nothing(tap003.config.ref)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"tap003.logger.show()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### **Kill Chain** | MANIPULATION\n",
|
|
"\n",
|
|
"|Index| Action Stage| OBS Impact | Narrative |\n",
|
|
"|-----|-------------|------------|-----------|\n",
|
|
"|4|Manipulation| **Target Host(s)** HOST::SESSIONS:REMOTE |TAP003 exploits their insider knowledge/privilege to implement changes for sabotage.|\n",
|
|
"\n",
|
|
"In the ``MANIPULATION`` kill chain stage the TAP003 agent creates new and alters pre-existing user accounts based on user given settings. \n",
|
|
"\n",
|
|
"_For more information please refer to the later TAP003 customisation section of the notebook._"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"access_obs_impact, _, _, _, _ = env.step(0)\n",
|
|
"pprint(f\"Agent action: {info['agent_actions']['attacker']}\")\n",
|
|
"\n",
|
|
"pprint(\"---TAP003's Current State---\")\n",
|
|
"print(f\"Current Environment Step: {env.game.step_counter}\")\n",
|
|
"print(f\"Current Kill Chain Stage: {tap003.current_kill_chain_stage.name}\")\n",
|
|
"print(f\"Next Execution Step: {tap003.next_execution_timestep}\")\n",
|
|
"print(f\"Next Kill Chain Stage {tap003.next_kill_chain_stage.name}\")\n",
|
|
"pprint(\"---Target Client State----\")\n",
|
|
"while(tap003.current_kill_chain_stage == InsiderKillChain.MANIPULATION):\n",
|
|
" manipulation_obs_impact, _, _, _, info = env.step(0)\n",
|
|
"\n",
|
|
"\n",
|
|
"# Example host\n",
|
|
"rem_pub_rt_dr.user_manager.show()\n",
|
|
"# rem_pub_rt_dr.user_session_manager.show()\n",
|
|
"\n",
|
|
"# Compare observation space before and after MANIPULATION stage.\n",
|
|
"display_obs_diffs(access_obs_impact, manipulation_obs_impact, env.game.step_counter)\n",
|
|
"print_agent_actions_except_do_nothing(tap003.config.ref)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"tap003.logger.show()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### **Kill Chain** | EXPLOITATION\n",
|
|
"\n",
|
|
"|Index| Action Stage| OBS Impact | Narrative |\n",
|
|
"|-----|-------------|------------|-----------|\n",
|
|
"|5|EXPLOITATION| **Target Host(s)** ROUTER_ACL_ADDRULE |TAP003 exploiting their insider knowledge/privilege to implement changes for sabotage|\n",
|
|
"\n",
|
|
"In the final attack stage the TAP003 agent insert a malicious ACL rule(s) which blocks specific traffic, therefore triggering negative rewards for the green agents.\n",
|
|
"\n",
|
|
"The table below shows the impacts:\n",
|
|
"\n",
|
|
"|Target Router | Impact |\n",
|
|
"|----------------------|--------|\n",
|
|
"|`ST_INTRA-PRV-RT-DR-1`| Blocks all `POSTGRES_SERVER` that arrives at the `ST_INTRA-PRV-RT-DR-1` router. This rule will prevent all ST_PROJ_* hosts from accessing the database (`ST_DATA-PRV-SRV-DB`).|\n",
|
|
"|`ST_INTRA-PRV-RT-CR`| Blocks all `HTTP` traffic that arrives at the`ST_INTRA-PRV-RT-CR` router. This rule will prevent all SOME_TECH hosts from accessing the webserver (`ST_DMZ-PUB-SRV-WEB`)|\n",
|
|
"|`REM-PUB-RT-DR`| Blocks all `DNS` traffic that arrives at the `REM-PUB-RT-DR` router. This rule prevents any remote site works from accessing the DNS Server (`ISP-PUB-SRV-DNS`).|\n",
|
|
"\n",
|
|
"\n",
|
|
"<p align=\"center\">\n",
|
|
" <a href=\"./_package_data/uc7/uc7_tap003/uc7_tap003_main.png\" target=\"_blank\">\n",
|
|
" <img src=\"./_package_data/uc7/uc7_tap003/uc7_tap003_main.png\" alt=\"Image\" style=\"width:1000px;\">\n",
|
|
" </a> \n",
|
|
" \n",
|
|
"</p>\n",
|
|
"\n",
|
|
"_(Click to enlarge)_"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"metadata": {}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"manipulation_obs_impact, _, _, _, _ = env.step(0)\n",
|
|
"pprint(f\"Agent action: {info['agent_actions']['attacker']}\")\n",
|
|
"\n",
|
|
"pprint(\"---TAP003's Current State---\")\n",
|
|
"print(f\"Current Environment Step: {env.game.step_counter}\")\n",
|
|
"print(f\"Current Kill Chain Stage: {tap003.current_kill_chain_stage.name}\")\n",
|
|
"print(f\"Next Execution Step: {tap003.next_execution_timestep}\")\n",
|
|
"print(f\"Next Kill Chain Stage {tap003.next_kill_chain_stage.name}\")\n",
|
|
"pprint(\"---Target Client State----\")\n",
|
|
"while(tap003.current_kill_chain_stage == InsiderKillChain.EXPLOIT):\n",
|
|
" exploit_obs_impact, _, _, _, info = env.step(0)\n",
|
|
" \n",
|
|
"st_intra_prv_rt_cr.acl.show()\n",
|
|
"st_intra_prv_rt_dr_1.acl.show()\n",
|
|
"rem_pub_rt_dr.acl.show()\n",
|
|
"\n",
|
|
"# Stepping once more to allow the malicious acl to appear in the simulation.\n",
|
|
"exploit_obs_impact, _, _, _, _ = env.step(0)\n",
|
|
"\n",
|
|
"# Compare observation space before and after MANIPULATION stage.\n",
|
|
"display_obs_diffs(manipulation_obs_impact, exploit_obs_impact, env.game.step_counter)\n",
|
|
"print_agent_actions_except_do_nothing(tap003.config.ref)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"tap003.logger.show()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"#### Demonstration of the ACL Rule blocking traffic\n",
|
|
"\n",
|
|
"As an example of the malicious ACL Rule affecting traffic across the network, attempting to query the database server (ST_DATA-PRV-SRV-DB) from any of the `ST_PROJECT_*` networks should fail because it is must route through the `ST_INTRA-PRV-RT-DR-1` router which TAP003 has configured to block all `POSTGRES_SERVER` traffic."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"affected_node = env.game.simulation.network.get_node_by_hostname(\"ST_PROJ-A-PRV-PC-1\")\n",
|
|
"database_server = env.game.simulation.network.get_node_by_hostname(\"ST_DATA-PRV-SRV-DB\")\n",
|
|
"\n",
|
|
"st_intra_prv_rt_dr_1 = env.game.simulation.network.get_node_by_hostname(\"ST_INTRA-PRV-RT-DR-1\")\n",
|
|
"\n",
|
|
"database_client: DatabaseClient = affected_node.software_manager.software.get(\"database-client\")\n",
|
|
"st_intra_prv_rt_dr_1.acl.show()\n",
|
|
"\n",
|
|
"# should be False\n",
|
|
"print(database_client.query(sql=\"SELECT\"))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"However, ACL rules will not stop ICMP traffic, allowing us to still ping the target nodes as shown below."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# should be true\n",
|
|
"print(affected_node.ping(database_server.network_interface[1].ip_address))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Additionally, by default, TAP003 is configured to add two more ACLs on the UC7 network as shown in the table previously."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# This ACL blocks all web_server traffic from within the main `SOME_TECH` office. Thus leading to every SOME_TECH host unable to access the web-server\n",
|
|
"st_intra_prv_rt_cr = env.game.simulation.network.get_node_by_hostname(\"ST_INTRA-PRV-RT-CR\")\n",
|
|
"st_intra_prv_rt_cr.acl.show()\n",
|
|
"\n",
|
|
"st_head_office_private_pc_1: Computer = env.game.simulation.network.get_node_by_hostname(\"ST_HO-PRV-PC-1\")\n",
|
|
"st_head_office_private_pc_1_web_browser: WebBrowser = st_head_office_private_pc_1.software_manager.software[\"web-browser\"]\n",
|
|
"st_head_office_private_pc_1_web_browser.get_webpage(url=\"http://some_tech.com\")\n",
|
|
"st_head_office_private_pc_1_web_browser.sys_log.show()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# This ACL blocks all DNS traffic from exiting the SOME_TECH remote site.\n",
|
|
"rem_pub_pc_1: Computer = env.game.simulation.network.get_node_by_hostname(hostname=\"REM-PUB-PC-1\")\n",
|
|
"rem_pub_rt_dr = env.game.simulation.network.get_node_by_hostname(\"REM-PUB-RT-DR\")\n",
|
|
"dns_client: DNSClient = rem_pub_pc_1.software_manager.software[\"dns-client\"]\n",
|
|
"dns_client.dns_cache.clear()\n",
|
|
"dns_client.check_domain_exists(target_domain=\"some_tech.com\")\n",
|
|
"rem_pub_rt_dr.acl.show()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## **Kill Chain Configurations** | Overview:"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"The following sections cover the TAP003's settings & configurations. \n",
|
|
"Each section contains code cells which directly demonstrate each option and it's effect on TAP003."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### **Attack Configurations** | Threat Actor Profile (TAP) wide Agent Settings\n",
|
|
"\n",
|
|
"<summary> Threat Actor Profile Agent Settings </summary>\n",
|
|
"\n",
|
|
"<details>\n",
|
|
"\n",
|
|
"|Option Field|Meaning|Expected Type|Required/Optional|\n",
|
|
"|------------|-------|-------------|-----------------|\n",
|
|
"|start_step|The initial kill chain starting step.|Int|_Required_|\n",
|
|
"|frequency|The frequency of each kill chains starting steps.|Int|_Required_|\n",
|
|
"|variance| The timestep variance between frequency|Int|_Required_|\n",
|
|
"|repeat_kill_chain|Indicates whether the attack is repeated throughout the episode.|Bool|_Required_|\n",
|
|
"|repeat_kill_chain_stages|Indicates if the kill_chain stage should reset upon failure or retry.|Bool|_Required_|\n",
|
|
"|default_target_node|The Target Host|Str|_Required_|\n",
|
|
"|starting_nodes|A list of Potential Targets|List|_Optional_|\n",
|
|
"|kill_chain|_See the next notebook section_|Dict|_Required_||\n",
|
|
"\n",
|
|
"</details>"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"_Example kill chain setting configuration_\n",
|
|
"```yaml\n",
|
|
" start_step: 1\n",
|
|
" frequency: 3\n",
|
|
" variance: 0\n",
|
|
" repeat_kill_chain: false\n",
|
|
" repeat_kill_chain_stages: true\n",
|
|
" default_starting_node: \"ST_PROJ-A-PRV-PC-1\"\n",
|
|
" starting_nodes:\n",
|
|
" # starting_nodes: [\"ST_PROJ-A-PRV-PC-1\", \"ST_PROJ-B-PRV-PC-2\", \"ST_PROJ-C-PRV-PC-3\"]\n",
|
|
"```"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### **Attack Configurations** | Kill Chain Settings Overview\n",
|
|
"Currently, each kill chain stage has a probability of success option.\n",
|
|
"Additionally the manipulation kill stage offers an additional configuration of the malicious ACL.\n",
|
|
"\n",
|
|
"<summary> TAP003's Kill Chain Settings </summary>\n",
|
|
"\n",
|
|
"<details> \n",
|
|
"\n",
|
|
"Kill Chain Stage 1 - _PLANNING_\n",
|
|
"\n",
|
|
"|Option Field|Meaning|Expected Type|Required/Optional|\n",
|
|
"|------------|-------|-------------|-----------------|\n",
|
|
"|probability|Probability Of Success - The chance of successfully carrying out this stage in the kill_chain.|float|_Required_|\n",
|
|
"|starting_network_knowledge| User Account details | dict |_required_|\n",
|
|
"\n",
|
|
"Kill Chain Stage 2 - _ACCESS_\n",
|
|
"\n",
|
|
"|Option Field|Meaning|Expected Type|Required/Optional|\n",
|
|
"|------------|-------|-------------|-----------------|\n",
|
|
"|probability|Probability Of Success - The chance of successfully carrying out this stage in the kill_chain.|float|_Required_|\n",
|
|
"\n",
|
|
"Kill Chain Stage 3 - _MANIPULATION_\n",
|
|
"\n",
|
|
"|Option Field|Meaning|Expected Type|Required/Optional|\n",
|
|
"|------------|-------|-------------|-----------------|\n",
|
|
"|probability|Probability Of Success - The chance of successfully carrying out this stage in the kill_chain.|float|_Required_|\n",
|
|
"|account_changes| User Accounts hijacked - Must be the same targets as `malicious_acl` used in next kill chain stage | dict | _Required_|\n",
|
|
"\n",
|
|
"Kill Chain Stage 4 - _EXPLOIT_\n",
|
|
"\n",
|
|
"|Option Field|Meaning|Expected Type|Required/Optional|\n",
|
|
"|------------|-------|-------------|-----------------|\n",
|
|
"|malicious_acl|The configurable ACL that the TAP003 agent adds to the target node.|dict|_Required_|\n",
|
|
"\n",
|
|
"</details>"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"_An example of a kill chain setting configuration_ \n",
|
|
"```yaml\n",
|
|
" kill_chain:\n",
|
|
" PLANNING:\n",
|
|
" probability: 1\n",
|
|
" starting_network_knowledge:\n",
|
|
" credentials:\n",
|
|
" ST_PROJ-A-PRV-PC-1:\n",
|
|
" username: admin\n",
|
|
" password: admin\n",
|
|
" ST_PROJ-B-PRV-PC-2:\n",
|
|
" username: admin\n",
|
|
" password: admin\n",
|
|
" ST_PROJ-C-PRV-PC-3:\n",
|
|
" username: admin\n",
|
|
" password: admin\n",
|
|
" ST_INTRA-PRV-RT-DR-1:\n",
|
|
" ip_address: 192.168.230.1\n",
|
|
" username: admin\n",
|
|
" password: admin\n",
|
|
" ST_INTRA-PRV-RT-CR:\n",
|
|
" ip_address: 192.168.160.1\n",
|
|
" username: admin\n",
|
|
" password: admin\n",
|
|
" REM-PUB-RT-DR:\n",
|
|
" ip_address: 192.168.10.2\n",
|
|
" username: admin\n",
|
|
" password: admin\n",
|
|
" ACCESS:\n",
|
|
" probability: 1\n",
|
|
" MANIPULATION:\n",
|
|
" probability: 1\n",
|
|
" account_changes:\n",
|
|
" - host: ST_INTRA-PRV-RT-DR-1\n",
|
|
" ip_address: 192.168.230.1 # ST_INTRA-PRV-RT-DR-1\n",
|
|
" action: change_password\n",
|
|
" username: admin\n",
|
|
" new_password: \"red_pass\"\n",
|
|
" - host: ST_INTRA-PRV-RT-CR\n",
|
|
" ip_address: 192.168.160.1 # ST_INTRA-PRV-RT-CR\n",
|
|
" action: change_password\n",
|
|
" username: \"admin\"\n",
|
|
" new_password: \"red_pass\"\n",
|
|
" - host: REM-PUB-RT-DR\n",
|
|
" ip_address: 192.168.10.2 # REM-PUB-RT-DR\n",
|
|
" action: change_password\n",
|
|
" username: \"admin\"\n",
|
|
" new_password: \"red_pass\"\n",
|
|
" EXPLOIT:\n",
|
|
" probability: 1\n",
|
|
" malicious_acls:\n",
|
|
" - target_router: ST_INTRA-PRV-RT-DR-1\n",
|
|
" ip_address: 192.168.230.1 \n",
|
|
" position: 1\n",
|
|
" permission: DENY\n",
|
|
" src_ip: ALL\n",
|
|
" src_wildcard_mask: 0.0.255.255\n",
|
|
" dst_ip: ALL\n",
|
|
" dst_wildcard_mask: 0.0.255.255\n",
|
|
" src_port: POSTGRES_SERVER\n",
|
|
" dst_port: POSTGRES_SERVER\n",
|
|
" protocol_name: TCP\n",
|
|
"\n",
|
|
"```"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### **Attack Configurations** | Configuration Examples \n",
|
|
"The following notebook section demonstrates a few potential examples of different TAP003 configurations and their expected behaviour within an episode."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"metadata": {}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"tap003 = env.game.agents['attacker']\n",
|
|
"for key,value in tap003.config.agent_settings:\n",
|
|
" if key == 'kill_chain':\n",
|
|
" pass\n",
|
|
" else:\n",
|
|
" print(f\"{key} : {value}\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"#### **Attack Configurations** | Start Step, Frequency & Variance\n",
|
|
"\n",
|
|
"In this section, the code cells below demonstrate the following options:\n",
|
|
"\n",
|
|
"|Option Field|Meaning|Expected Type|Required/Optional|\n",
|
|
"|------------|-------|-------------|-----------------|\n",
|
|
"|start_step|The initial kill chain starting step.|Int|_Required_|\n",
|
|
"|frequency|The frequency of each kill chains starting steps.|Str|_Required_|\n",
|
|
"|variance|The timestep variance between frequency.|Str|_Required_|\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"The code cell below alters the start_step, frequency and variance to 20, 10 and 5 respectively.\n",
|
|
"Additionally, the probability of the kill chain stages are set to guarantee success. "
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"metadata": {}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"with open(_EXAMPLE_CFG/\"uc7_config_tap003.yaml\", mode=\"r\") as uc7_config:\n",
|
|
" cfg = yaml.safe_load(uc7_config)\n",
|
|
" cfg[\"agents\"][33][\"agent_settings\"][\"flatten_obs\"] = False\n",
|
|
" cfg['io_settings']['save_sys_logs'] = True # Saving syslogs\n",
|
|
" cfg['agents'][32]['agent_settings']['start_step'] = 20\n",
|
|
" cfg['agents'][32]['agent_settings']['frequency'] = 10\n",
|
|
" cfg['agents'][32]['agent_settings']['variance'] = 5\n",
|
|
" cfg['agents'][32]['agent_settings']['kill_chain']['MANIPULATION']['probability'] = 1\n",
|
|
" cfg['agents'][32]['agent_settings']['kill_chain']['ACCESS']['probability'] = 1\n",
|
|
" cfg['agents'][32]['agent_settings']['kill_chain']['PLANNING']['probability'] = 1\n",
|
|
"env = PrimaiteGymEnv(env_config = cfg)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"The cell below demonstrates how the frequency & variance options affect TAP003's next execution step."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"metadata": {}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"tap003 = env.game.agents['attacker']\n",
|
|
"print(\"---TAP003's Current State---\")\n",
|
|
"print(f\"Current Environment Step: {env.game.step_counter}\")\n",
|
|
"print(f\"Current Kill Chain Stage: {tap003.current_kill_chain_stage.name}\")\n",
|
|
"print(f\"Next Execution Step: {tap003.next_execution_timestep}\")\n",
|
|
"print(f\"Next Kill Chain Stage {tap003.next_kill_chain_stage.name}\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"#### **Attack Configurations** | repeat_kill_chain & repeat_kill_chain_stages\n",
|
|
"\n",
|
|
"This section demonstrate how the different repeat options may affect a 100 step length episode.\n",
|
|
"\n",
|
|
"|Option Field|Meaning|Expected Type|Required/Optional|\n",
|
|
"|------------|-------|-------------|-----------------|\n",
|
|
"|repeat_kill_chain|Indicates whether the attack is repeated throughout the episode.|Str|_Required_|\n",
|
|
"|repeat_kill_chain_stages|Indicates if the kill_chain stage should reset upon failure or retry.|Str|_Required_|\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"metadata": {}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"with open(_EXAMPLE_CFG/\"uc7_config_tap003.yaml\", mode=\"r\") as f:\n",
|
|
" cfg = yaml.safe_load(f)\n",
|
|
" cfg['io_settings']['save_sys_logs'] = True # Saving syslogs\n",
|
|
" cfg['agents'][32]['agent_settings']['repeat_kill_chain'] = False\n",
|
|
" cfg['agents'][32]['agent_settings']['repeat_kill_chain_stages'] = False\n",
|
|
"env = PrimaiteGymEnv(env_config = cfg)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"metadata": {}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"with open(_EXAMPLE_CFG/\"uc7_config_tap003.yaml\", mode=\"r\") as f:\n",
|
|
" cfg = yaml.safe_load(f)\n",
|
|
" cfg['agents'][32]['agent_settings']['repeat_kill_chain'] = True\n",
|
|
" cfg['agents'][32]['agent_settings']['repeat_kill_chain_stages'] = True\n",
|
|
"env = PrimaiteGymEnv(env_config = cfg)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"metadata": {}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"while(env.game.step_counter != 100):\n",
|
|
" env.step(0)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"#### **Attack Configurations** | Starting Node\n",
|
|
"\n",
|
|
"The code cells below demonstrate how to configure TAP003's different options for selecting starting hosts.\n",
|
|
"\n",
|
|
"|Option Field|Meaning|Expected Type|Required/Optional|\n",
|
|
"|------------|-------|-------------|-----------------|\n",
|
|
"|default_starting_node|The default starting host.|Str|_Required_|\n",
|
|
"|starting_nodes|A list of potential targets|List|_Optional_|\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"metadata": {}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"with open(_EXAMPLE_CFG/\"uc7_config_tap003.yaml\", mode=\"r\") as f:\n",
|
|
" cfg = yaml.safe_load(f)\n",
|
|
" cfg[\"agents\"][32][\"agent_settings\"][\"default_starting_node\"] = \"ST_PROJ-A-PRV-PC-1\"\n",
|
|
"env = PrimaiteGymEnv(env_config = cfg)\n",
|
|
"tap003 = env.game.agents[\"attacker\"]\n",
|
|
"print(f\"TA003's Selected Starting Host: {tap003.starting_node}\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"The code cell below demonstrates how starting node lists overrule the default start node options:"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"metadata": {}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"with open(_EXAMPLE_CFG/\"uc7_config_tap003.yaml\", mode=\"r\") as f:\n",
|
|
" cfg = yaml.safe_load(f)\n",
|
|
" cfg[\"agents\"][32][\"agent_settings\"][\"default_starting_node\"] = \"ST_PROJ-A-PRV-PC-1\"\n",
|
|
" cfg[\"agents\"][32][\"agent_settings\"][\"starting_nodes\"] = [\"ST_PROJ-A-PRV-PC-1\",\"ST_PROJ-B-PRV-PC-2\"]"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"metadata": {}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"env = PrimaiteGymEnv(env_config = cfg)\n",
|
|
"tap003 = env.game.agents[\"attacker\"]\n",
|
|
"print(f\"TA003's Selected Starting Host: {tap003.starting_node}\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"#### **Attack Configurations** | kill_chain_settings | probability\n",
|
|
"\n",
|
|
"The code cells below configure each kill chain's probability of success. \n",
|
|
"The cells also demonstrate how TAP003 handles failure within an episode.\n",
|
|
"\n",
|
|
"|Option Field|Meaning|Expected Type|Required/Optional|\n",
|
|
"|------------|-------|-------------|-----------------|\n",
|
|
"|probability | The chance of successfully carrying out this stage in the kill chain.|float|_Required_|\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"The code cell below directly sets each probability of success to 0.25. <Br/>\n",
|
|
"Additionally the repeat kill chain and kill chain stage configuration options are set to false."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"metadata": {}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"with open(_EXAMPLE_CFG/\"uc7_config_tap003.yaml\", mode=\"r\") as f:\n",
|
|
" cfg = yaml.safe_load(f)\n",
|
|
" cfg['io_settings']['save_sys_logs'] = True # Saving syslogs\n",
|
|
" cfg['agents'][32]['agent_settings']['repeat_kill_chain'] = False\n",
|
|
" cfg['agents'][32]['agent_settings']['repeat_kill_chain_stages'] = False\n",
|
|
" cfg['agents'][32]['agent_settings']['kill_chain']['EXPLOIT']['probability'] = 0.25\n",
|
|
" cfg['agents'][32]['agent_settings']['kill_chain']['ACCESS']['probability'] = 0.25\n",
|
|
" cfg['agents'][32]['agent_settings']['kill_chain']['PLANNING']['probability'] = 0.25\n",
|
|
"env = PrimaiteGymEnv(env_config = cfg)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"metadata": {}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"while(env.game.step_counter != 100):\n",
|
|
" env.step(0)\n",
|
|
"tap003 = env.game.agents['attacker']\n",
|
|
"pprint(\"---TAP003's Current State---\")\n",
|
|
"print(f\"Current Environment Step: {env.game.step_counter}\")\n",
|
|
"print(f\"Current Kill Chain Stage: {tap003.current_kill_chain_stage.name}\")\n",
|
|
"print(f\"Next Execution Step: {tap003.next_execution_timestep}\")\n",
|
|
"print(f\"Next Kill Chain Stage {tap003.next_kill_chain_stage.name}\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"The code cell below performs the same episode but with the repeat_kill_chain and repeat_kill_chain_stages to true."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"metadata": {}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"with open(_EXAMPLE_CFG/\"uc7_config_tap003.yaml\", mode=\"r\") as f:\n",
|
|
" cfg = yaml.safe_load(f)\n",
|
|
" cfg['agents'][32]['agent_settings']['repeat_kill_chain'] = True\n",
|
|
" cfg['agents'][32]['agent_settings']['repeat_kill_chain_stages'] = True\n",
|
|
" cfg['agents'][32]['agent_settings']['kill_chain']['MANIPULATION']['probability'] = 0.25\n",
|
|
" cfg['agents'][32]['agent_settings']['kill_chain']['ACCESS']['probability'] = 0.25\n",
|
|
" cfg['agents'][32]['agent_settings']['kill_chain']['PLANNING']['probability'] = 0.25\n",
|
|
"env = PrimaiteGymEnv(env_config = cfg)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"metadata": {}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"while(env.game.step_counter != 100):\n",
|
|
" env.step(0)\n",
|
|
"tap003 = env.game.agents['attacker']\n",
|
|
"pprint(\"---TAP003's Current State---\")\n",
|
|
"print(f\"Current Environment Step: {env.game.step_counter}\")\n",
|
|
"print(f\"Current Kill Chain Stage: {tap003.current_kill_chain_stage.name}\")\n",
|
|
"print(f\"Next Execution Step: {tap003.next_execution_timestep}\")\n",
|
|
"print(f\"Next Kill Chain Stage {tap003.next_kill_chain_stage.name}\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"#### **Attack Configurations** | kill_chain_settings | ACCESS - Starting Network Knowledge\n",
|
|
"\n",
|
|
"|Option Field |Meaning|Expected Type|Required/Optional|\n",
|
|
"|-------------|-------|-------------|-----------------|\n",
|
|
"|probability |Action Probability - The chance of successfully carrying out this stage in the kill_chain.|str|_Required_|\n",
|
|
"|starting_network_knowledge|TAP003's starting knowledge. Used to login into the target accounts in the ``MANIPULATION`` stage.|dict|_Required_|"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"``starting_network_knowledge``\n",
|
|
"\n",
|
|
"***\n",
|
|
"\n",
|
|
"The ``starting_network_knowledge`` options uses the following schema:\n",
|
|
"\n",
|
|
"|Option Field |Meaning|Expected Type|Required/Optional|\n",
|
|
"|-------------|-------|-------------|-----------------|\n",
|
|
"|credentials|The credential knowledge does TAP003 starts the episode with.|dict|_Required_|\n",
|
|
"\n",
|
|
"```yaml\n",
|
|
" kill_chain:\n",
|
|
" PLANNING:\n",
|
|
" probability: 1\n",
|
|
" starting_network_knowledge:\n",
|
|
" credentials:\n",
|
|
"```"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"``credentials``\n",
|
|
"\n",
|
|
"***\n",
|
|
"\n",
|
|
"The ``credentials`` options uses the following schema:\n",
|
|
"\n",
|
|
"|Option Field |Meaning|Expected Type|Required/Optional|\n",
|
|
"|-------------|-------|-------------|-----------------|\n",
|
|
"|ip_address |The IP Address of the target host.|str|_Required_|\n",
|
|
"|username |A username of a valid user account. Defaults to ``Admin``.|str|_Optional_|\n",
|
|
"|password |The corresponding valid password of the given username. Defaults to ``Admin``.|str|_Optional_|\n",
|
|
"\n",
|
|
"These credentials will are used in the ``MANIPULATION`` kill chain stage to login into the target accounts. Therefore the ``credentials`` options needs contain the same hosts that the the ``ACCOUNT_CHANGES`` option\n",
|
|
"\n",
|
|
"```yaml\n",
|
|
"\n",
|
|
" kill_chain:\n",
|
|
" PLANNING:\n",
|
|
" probability: 1\n",
|
|
" starting_network_knowledge:\n",
|
|
" credentials:\n",
|
|
" ST_PROJ-A-PRV-PC-1:\n",
|
|
" username: admin\n",
|
|
" password: admin\n",
|
|
" ST_PROJ-B-PRV-PC-2:\n",
|
|
" username: admin\n",
|
|
" password: admin\n",
|
|
" ST_PROJ-C-PRV-PC-3:\n",
|
|
" username: admin\n",
|
|
" password: admin\n",
|
|
" ST_INTRA-PRV-RT-DR-1:\n",
|
|
" ip_address: 192.168.230.1\n",
|
|
" username: admin\n",
|
|
" password: admin\n",
|
|
" ST_INTRA-PRV-RT-CR:\n",
|
|
" ip_address: 192.168.160.1\n",
|
|
" username: admin\n",
|
|
" password: admin\n",
|
|
" REM-PUB-RT-DR:\n",
|
|
" ip_address: 192.168.10.2\n",
|
|
" username: admin\n",
|
|
" password: admin\n",
|
|
"\n",
|
|
"```"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"env.reset()\n",
|
|
"tap003 = env.game.agents['attacker']\n",
|
|
"# This while loop will run TAP003 until it hits TAP003 reaches ``ACCESS`` (Therefore passing PLANNING)\n",
|
|
"while(tap003.current_kill_chain_stage != InsiderKillChain.ACCESS):\n",
|
|
" env.step(0)\n",
|
|
"for account in tap003.network_knowledge['credentials']:\n",
|
|
" print(f\"----{account}---\")\n",
|
|
" for key in tap003.network_knowledge['credentials'][account]:\n",
|
|
" pprint(f\"{key}: {tap003.network_knowledge['credentials'][account][key]}\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"#### **Attack Configurations** | kill_chain_settings | Manipulation - Account Changes\n",
|
|
"\n",
|
|
"|Option Field |Meaning|Expected Type|Required/Optional|\n",
|
|
"|------------|-------|-------------|-----------------|\n",
|
|
"|probability|Action Probability - The chance of successfully carrying out this stage in the kill_chain.|str|_Required_|\n",
|
|
"|account_changes|List of dictionaries containing the target hostnames, ip and account configuration changes.|list[dict]|_Required_|\n",
|
|
"\n",
|
|
"```yaml\n",
|
|
" kill_chain:\n",
|
|
" MANIPULATION:\n",
|
|
" probability: 1\n",
|
|
" account_changes:\n",
|
|
" - host: ST_INTRA-PRV-RT-DR-1\n",
|
|
" ip_address: 192.168.230.1 # ST_INTRA-PRV-RT-DR-1\n",
|
|
" action: change_password\n",
|
|
" username: admin\n",
|
|
" new_password: \"red_pass\"\n",
|
|
" - host: ST_INTRA-PRV-RT-CR\n",
|
|
" ip_address: 192.168.160.1 # ST_INTRA-PRV-RT-CR\n",
|
|
" action: change_password\n",
|
|
" username: \"admin\"\n",
|
|
" new_password: \"red_pass\"\n",
|
|
" - host: REM-PUB-RT-DR\n",
|
|
" ip_address: 192.168.10.2 # REM-PUB-RT-DR\n",
|
|
" action: change_password\n",
|
|
" username: \"admin\"\n",
|
|
" new_password: \"red_pass\"\n",
|
|
"\n",
|
|
"```\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"``account_changes``\n",
|
|
"\n",
|
|
"***\n",
|
|
"\n",
|
|
"The ``account_changes`` options uses the following schema:\n",
|
|
"\n",
|
|
"|Option Field |Meaning|Expected Type|Required/Optional|\n",
|
|
"|-------------|-------|-------------|-----------------|\n",
|
|
"|host|The hostname of the target host.|str|_Required_|\n",
|
|
"|ip_address|The IP Address of the target host.|str|_Required_|\n",
|
|
"|action|The user account manager action. Currently only ``change_password`` is available.|str|_Required_|\n",
|
|
"|username|The username of the account that TAP003 will target.|str|_Required_|\n",
|
|
"|new_password|The new password that TAP003 will set.|str|_Required_|\n",
|
|
"\n",
|
|
"_For further information around the simulation implementation of user sessions please consult the ``user_session_manager`` primAITE API documentation page within PrimAITE's user guide documentation._"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"#### **Attack Configurations** | kill_chain_settings | Manipulation - Sandbox \n",
|
|
"\n",
|
|
"The code cells below can be used as a sandbox to trial out different configuration options and their impact on the simulation. Additionally, if users wish to alter an account other than admin on this sandbox they can alter the ``new_users`` dictionary in the code cell below."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# New ST_PROJ-B-PRV-PC-2 user account\n",
|
|
"user_username = \"example_user_1\"\n",
|
|
"user_password = \"example_pass_1\"\n",
|
|
"user_admin = \"False\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"new_users = {\"username\": user_username, \"password\": user_password, \"is_admin\": user_admin }"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Changing the password\n",
|
|
"tap003_new_password = \"tap003_password\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"account_changes = [{\"host\":\"ST_PROJ-A-PRV-PC-2\", \"ip_address\": \"192.168.230.2\", \"username\": user_username, \"old_password\": user_password, \"new_password\": tap003_new_password}]"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Now we update the UC7 config and implement the new user accounts and run through an episode."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"with open(_EXAMPLE_CFG/\"uc7_config_tap003.yaml\", mode=\"r\") as f:\n",
|
|
" cfg = yaml.safe_load(f)\n",
|
|
" cfg['agents'][32]['agent_settings']['repeat_kill_chain'] = False\n",
|
|
" cfg['simulation']['network']['nodes'][31].update({'users':[]})\n",
|
|
" cfg['simulation']['network']['nodes'][31]['users'].append(new_users)\n",
|
|
" cfg['agents'][32]['agent_settings']['start_step'] = 1\n",
|
|
" cfg['agents'][32]['agent_settings']['frequency'] = 3\n",
|
|
" cfg['agents'][32]['agent_settings']['variance'] = 0\n",
|
|
" starting_creds = {\"username\": \"admin\",\"password\":\"admin\", \"ip_address\":\"192.168.230.2\"} # Adding \"ST_PROJ-A-PRV-PC-2\" to TAP003's starting_network_knowledge\n",
|
|
" cfg['agents'][32]['agent_settings']['kill_chain']['PLANNING']['starting_network_knowledge']['credentials'].update({\"ST_PROJ-A-PRV-PC-2\": starting_creds})\n",
|
|
" cfg['agents'][32]['agent_settings']['kill_chain']['MANIPULATION']['account_changes'] = account_changes\n",
|
|
"env = PrimaiteGymEnv(env_config = cfg)\n",
|
|
"env.reset()\n",
|
|
"while(env.game.step_counter != 90): # 20 Red Actions (frequency of 3)\n",
|
|
" env.step(0)\n",
|
|
"tap003 = env.game.agents['attacker']\n",
|
|
"target_host = env.game.simulation.network.get_node_by_hostname(\"ST_PROJ-A-PRV-PC-2\")\n",
|
|
"target_host.user_manager.show()\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"#### **Attack Configurations** | kill_chain_settings | Exploit - Malicious ACL\n",
|
|
"\n",
|
|
"|Option Field |Meaning|Expected Type|Required/Optional|\n",
|
|
"|------------|-------|-------------|-----------------|\n",
|
|
"|probability|Action Probability - The chance of successfully carrying out this stage in the kill_chain.|str|_Required_|\n",
|
|
"|malicious_acls|The configurable ACL that the TAP003 agent adds to the target node.|dict|_Required_|\n",
|
|
"\n",
|
|
"The malicious ACL is configured identically to the other ACLs except from the target router/firewall. \n",
|
|
"This option is set to the TAP003's configured target host automatically.\n",
|
|
"\n",
|
|
"TAP003 intends to leverage these ACL's for malicious purposes. The default configuration is to deny all traffic from and towards the 0.0.0.255 subnet. \n",
|
|
"The configurability of the malicious ACL will allow for future releases of TAP type agents itself to perform more complex attacks. Currently, the TAP003 aims to block green agent traffic."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"``malicious_acl``\n",
|
|
"\n",
|
|
"***\n",
|
|
"\n",
|
|
"The ``malicious_acl`` options uses the following schema:\n",
|
|
"\n",
|
|
"|Option Field |Meaning|Expected Type|Required/Optional|\n",
|
|
"|-------------|-------|-------------|-----------------|\n",
|
|
"|target_router|The hostname of target router.|str|_Required_|\n",
|
|
"|ip_address|The ip_address of target router.|str|_Required_|\n",
|
|
"|position|The position that the malicious ACL is placed.|str|_Required_|\n",
|
|
"|permission|The implicit action. Should the ACL ``DENY`` or ``PERMIT``.|str|_Required_|\n",
|
|
"|src_ip|The source IP address to be targeted by the ``ACL``.|str|_Required_|\n",
|
|
"|src_wildcard_mask|The wildcard mask for the source ip address.|str|_Required_|\n",
|
|
"|dst_ip|The destination IP address to be targeted by the ``ACL``.|str|_Required_|\n",
|
|
"|dst_wildcard_mask|The wildcard mask for the destination ip address.|str|_Required_|\n",
|
|
"|src_port|The source port to be targeted by the ``ACL``.|str|_Required_|\n",
|
|
"|dst_port|The destination port to be targeted by the ``ACL``.|str|_Required_|\n",
|
|
"|protocol_name|The transport layer protocol_name to be targeted.|str|_Required_|\n",
|
|
"\n",
|
|
"_For further information please consult the simulation ACL documentation within PrimAITE's Sphinx documentation._"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"The code cell below demonstrates the default ACL's added by TAP003:"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"metadata": {}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"with open(_EXAMPLE_CFG/\"uc7_config_tap003.yaml\", mode=\"r\") as f:\n",
|
|
" cfg = yaml.safe_load(f)\n",
|
|
" cfg['agents'][32]['agent_settings']['start_step'] = 1\n",
|
|
" cfg['agents'][32]['agent_settings']['frequency'] = 3 # Install action takes multiple timesteps.\n",
|
|
" cfg['agents'][32]['agent_settings']['variance'] = 0\n",
|
|
" cfg['agents'][32]['agent_settings']['kill_chain']['EXPLOIT']['probability'] = 1\n",
|
|
" cfg['agents'][32]['agent_settings']['kill_chain']['MANIPULATION']['probability'] = 1\n",
|
|
" cfg['agents'][32]['agent_settings']['kill_chain']['ACCESS']['probability'] = 1\n",
|
|
" cfg['agents'][32]['agent_settings']['kill_chain']['PLANNING']['probability'] = 1\n",
|
|
"env = PrimaiteGymEnv(env_config = cfg)\n",
|
|
"while(env.game.step_counter != 70):\n",
|
|
" env.step(0)\n",
|
|
"tap003 = env.game.agents['attacker']\n",
|
|
"for key,value in tap003.config.agent_settings:\n",
|
|
" if key != 'kill_chain':\n",
|
|
" pass\n",
|
|
" else:\n",
|
|
" for kill_chain_setting_key in value:\n",
|
|
" if kill_chain_setting_key == 'EXPLOIT':\n",
|
|
" pprint(value[kill_chain_setting_key]['malicious_acls'][0])\n",
|
|
" pprint(value[kill_chain_setting_key]['malicious_acls'][1])\n",
|
|
" pprint(value[kill_chain_setting_key]['malicious_acls'][2])\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"st_intra_prv_rt_dr_1 = env.game.simulation.network.get_node_by_hostname(\"ST_INTRA-PRV-RT-DR-1\")\n",
|
|
"st_intra_prv_rt_dr_1.acl.show()\n",
|
|
"\n",
|
|
"rem_pub_rt_dr = env.game.simulation.network.get_node_by_hostname(\"REM-PUB-RT-DR\")\n",
|
|
"rem_pub_rt_dr.acl.show()\n",
|
|
"\n",
|
|
"st_intra_prv_rt_cr = env.game.simulation.network.get_node_by_hostname(\"ST_INTRA-PRV-RT-CR\")\n",
|
|
"st_intra_prv_rt_cr.acl.show()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Unlike the blue agent, TAP003 does not need to use its action space options for indexing different options, meaning that ACLs are a lot easier to configure.\n",
|
|
"\n",
|
|
"The sandbox below can be used to try out different configuration options and their impact on the simulation."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"#### **Attack Configurations** | kill_chain_settings | Exploit - Sandbox "
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"metadata": {}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# please ensure that the source/dest ip_addresses are within the blue agent's observation space ip_list option.\n",
|
|
"with open(_EXAMPLE_CFG/\"uc7_config_tap003.yaml\", mode=\"r\") as f:\n",
|
|
" cfg = yaml.safe_load(f)\n",
|
|
" cfg['agents'][32]['agent_settings']['repeat_kill_chain'] = False\n",
|
|
" cfg['agents'][32]['agent_settings']['start_step'] = 1\n",
|
|
" cfg['agents'][32]['agent_settings']['frequency'] = 3\n",
|
|
" cfg['agents'][32]['agent_settings']['variance'] = 0\n",
|
|
" cfg['agents'][32]['agent_settings']['kill_chain']['EXPLOIT']['malicious_acls'][0]['position'] = 1\n",
|
|
" cfg['agents'][32]['agent_settings']['kill_chain']['EXPLOIT']['malicious_acls'][0]['permission'] = \"DENY\"\n",
|
|
" cfg['agents'][32]['agent_settings']['kill_chain']['EXPLOIT']['malicious_acls'][0]['src_ip'] = \"ALL\"\n",
|
|
" cfg['agents'][32]['agent_settings']['kill_chain']['EXPLOIT']['malicious_acls'][0]['src_wildcard'] = '0.0.255.255'\n",
|
|
" cfg['agents'][32]['agent_settings']['kill_chain']['EXPLOIT']['malicious_acls'][0]['dst_ip'] = 'ALL'\n",
|
|
" cfg['agents'][32]['agent_settings']['kill_chain']['EXPLOIT']['malicious_acls'][0]['dst_wildcard'] = \"0.0.255.255\"\n",
|
|
" # Please refer to the ``PORT`` class in the primAITE API for more information around the different supported ports\n",
|
|
" cfg['agents'][32]['agent_settings']['kill_chain']['EXPLOIT']['malicious_acls'][0]['src_port'] = 'POSTGRES_SERVER'\n",
|
|
" cfg['agents'][32]['agent_settings']['kill_chain']['EXPLOIT']['malicious_acls'][0]['dst_port'] = \"POSTGRES_SERVER\"\n",
|
|
" cfg['agents'][32]['agent_settings']['kill_chain']['EXPLOIT']['malicious_acls'][0]['protocol_name'] = 'ALL'\n",
|
|
"env = PrimaiteGymEnv(env_config = cfg)\n",
|
|
"while(env.game.step_counter != 50):\n",
|
|
" env.step(0)\n",
|
|
"tap003 = env.game.agents['attacker']\n",
|
|
"target_host = env.game.simulation.network.get_node_by_hostname(\"ST_INTRA-PRV-RT-DR-1\")\n",
|
|
"target_host.acl.show()"
|
|
]
|
|
}
|
|
],
|
|
"metadata": {
|
|
"kernelspec": {
|
|
"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,
|
|
"nbformat_minor": 2
|
|
}
|