{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Simulating Privilege Escalation and Data Loss Using SSH and ACLs Manipulation\n",
    "\n",
    "© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK\n",
    "\n",
    "## Overview\n",
    "\n",
    "This Jupyter notebook demonstrates a cyber scenario focusing on internal privilege escalation and data loss through the manipulation of SSH access and Access Control Lists (ACLs). The scenario is designed to model and visualise how a disgruntled junior engineer might exploit internal network vulnerabilities and social engineering of account credentials to escalate privileges and cause significant data loss and disruption to services.\n",
    "\n",
    "## Scenario Description\n",
    "\n",
    "This simulation utilises the PrimAITE demo network, focussing specifically on five nodes:\n",
    "\n",
    "<a href=\"_package_data/primaite_demo_network.png\" target=\"_blank\">\n",
    "    <img src=\"_package_data/primaite_demo_network.png\" alt=\"Description of Image\" style=\"width:100%; max-width:450px;\">\n",
    "</a>\n",
    "\n",
    "\n",
    "- **SomeTech Developer PC (`some_tech_jnr_dev_pc`)**: The workstation used by the junior engineer.\n",
    "- **SomeTech Core Router (`some_tech_rt`)**: A critical network device that controls access between nodes.\n",
    "- **SomeTech PostgreSQL Database Server (`some_tech_db_srv`)**: Hosts the company’s critical database.\n",
    "- **SomeTech Storage Server (`some_tech_storage_srv`)**: Stores important files and database backups.\n",
    "- **SomeTech Web Server (`some_tech_web_srv`)**: Serves the company’s website.\n",
    "\n",
    "By default, the junior developer PC is restricted from connecting to the storage server via FTP or SSH due to ACL rules that permit only senior members of the engineering team to access these services.\n",
    "\n",
    "The goal of the scenario is to simulate how the junior engineer, after gaining unauthorised access to the core router, manipulates ACL rules to escalate privileges and delete critical data.\n",
    "\n",
    "### Key Actions Simulated\n",
    "\n",
    "1. **Privilege Escalation**: The junior engineer uses social engineering to obtain login credentials for the core router, SSHs into the router, and modifies the ACL rules to allow SSH access from their PC to the storage server.\n",
    "2. **Remote Access**: The junior engineer then uses the newly gained SSH access to connect to the storage server from their PC. This step is crucial for executing further actions, such as deleting files.\n",
    "3. **File Deletion**: With SSH access to the storage server, the engineer deletes the backup file from the storage server and subsequently removes critical data from the PostgreSQL database, bringing down the sometech.ai website.\n",
    "4.  **Website Impact Verification:** After the deletion of the database backup, the scenario checks the sometech.ai website's status to confirm it has been brought down due to the data loss.\n",
    "5.  **Database Restore Failure:** An attempt is made to restore the deleted backup, demonstrating that the restoration fails and highlighting the severity of the data loss.\n",
    "\n",
    "### Notes:\n",
    "- The demo will utilise CAOS (Common Action and Observation Space) actions wherever they are available. For actions where a CAOS action does not yet exist, the action will be performed manually on the node/service.\n",
    "- This notebook will be updated to incorporate new CAOS actions as they become supported."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## The Scenario"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "import yaml\n",
    "\n",
    "from primaite import PRIMAITE_PATHS\n",
    "from primaite.game.game import PrimaiteGame\n",
    "from primaite.simulator.network.hardware.nodes.host.computer import Computer\n",
    "from primaite.simulator.network.hardware.nodes.network.router import Router\n",
    "from primaite.simulator.network.hardware.nodes.host.server import Server\n",
    "from primaite.simulator.system.applications.database_client import DatabaseClient\n",
    "from primaite.simulator.system.applications.web_browser import WebBrowser\n",
    "from primaite.simulator.system.services.database.database_service import DatabaseService"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Load the network configuration"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "path = PRIMAITE_PATHS.user_config_path / \"example_config\" / \"multi_lan_internet_network_example.yaml\"\n",
    "\n",
    "with open(path, \"r\") as file:\n",
    "    cfg = yaml.safe_load(file)\n",
    "\n",
    "    game = PrimaiteGame.from_config(cfg)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Capture some of the nodes from the network to observe actions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "some_tech_jnr_dev_pc: Computer = game.simulation.network.get_node_by_hostname(\"some_tech_jnr_dev_pc\")\n",
    "some_tech_jnr_dev_db_client: DatabaseClient = some_tech_jnr_dev_pc.software_manager.software[\"DatabaseClient\"]\n",
    "some_tech_jnr_dev_web_browser: WebBrowser = some_tech_jnr_dev_pc.software_manager.software[\"WebBrowser\"]\n",
    "some_tech_rt: Router = game.simulation.network.get_node_by_hostname(\"some_tech_rt\")\n",
    "some_tech_db_srv: Server = game.simulation.network.get_node_by_hostname(\"some_tech_db_srv\")\n",
    "some_tech_db_service: DatabaseService = some_tech_db_srv.software_manager.software[\"DatabaseService\"]\n",
    "some_tech_storage_srv: Server = game.simulation.network.get_node_by_hostname(\"some_tech_storage_srv\")\n",
    "some_tech_web_srv: Server = game.simulation.network.get_node_by_hostname(\"some_tech_web_srv\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Perform a Database Backup and Inspect the Storage Server\n",
    "\n",
    "At this stage, a backup of the PostgreSQL database is created and the storage server’s file system is inspected. This step ensures that a backup file is present and correctly stored in the storage server before any further actions are taken. The inspection of the file system allows verification of the backup’s existence and health, establishing a baseline that will later be used to confirm the success of the subsequent deletion actions."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "some_tech_storage_srv.file_system.show(full=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "some_tech_db_service.backup_database()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "some_tech_storage_srv.file_system.show(full=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Extract the folder name containing the database backup file"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "db_backup_folder = [folder.name for folder in some_tech_storage_srv.file_system.folders.values() if folder.name != \"root\"][0]\n",
    "db_backup_folder"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "tags": []
   },
   "source": [
    "## Check That the Junior Engineer Cannot SSH into the Storage Server\n",
    "\n",
    "This step verifies that the junior engineer is currently restricted from SSH access to the storage server. By attempting to establish an SSH connection from the junior engineer’s workstation to the storage server, this action confirms that the current ACL rules on the core router correctly prevents unauthorised access. It sets up the necessary conditions to later validate the effectiveness of the privilege escalation by demonstrating the initial access restrictions.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "caos_action = [\n",
    "    \"network\", \"node\", \"some_tech_jnr_dev_pc\", \n",
    "    \"service\", \"Terminal\", \"ssh_to_remote\", \"admin\", \"admin\", str(some_tech_storage_srv.network_interface[1].ip_address)\n",
    "]\n",
    "game.simulation.apply_request(caos_action)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Confirm That the Website Is Up by Executing the Web Browser on the Junior Engineer's Machine\n",
    "\n",
    "In this step, we verify that the sometech.ai website is operational before any malicious activities begin. By executing the web browser application on the junior engineer’s machine, we ensure that the website is accessible and functioning correctly. This establishes a baseline for the website’s status, allowing us to later assess the impact of the subsequent actions, such as database deletion, on the website's availability.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "caos_action = [\"network\", \"node\", \"some_tech_jnr_dev_pc\", \"application\", \"WebBrowser\", \"execute\"]\n",
    "game.simulation.apply_request(caos_action)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "tags": []
   },
   "source": [
    "## Exploit Core Router to Add ACL for SSH Access\n",
    "\n",
    "At this point, the junior engineer exploits a vulnerability in the core router by obtaining the login credentials through social engineering. With SSH access to the core router, the engineer modifies the ACL rules to permit SSH connections from their machine to the storage server. This action is crucial as it will enable the engineer to remotely access the storage server and execute further malicious activities.\n",
    "\n",
    "Interestingly, if we inspect the `active_remote_sessions` on the SomeTech core routers `UserSessionManager`, we'll see an active session appear. This active session would pop up in the observation space."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "game.get_sim_state()[\"network\"][\"nodes\"][\"some_tech_rt\"][\"services\"][\"UserSessionManager\"][\"active_remote_sessions\"]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "caos_action = [\n",
    "    \"network\", \"node\", \"some_tech_jnr_dev_pc\", \n",
    "    \"service\", \"Terminal\", \"ssh_to_remote\", \"admin\", \"admin\", str(some_tech_rt.network_interface[4].ip_address)\n",
    "]\n",
    "game.simulation.apply_request(caos_action)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "game.get_sim_state()[\"network\"][\"nodes\"][\"some_tech_rt\"][\"services\"][\"UserSessionManager\"][\"active_remote_sessions\"]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Inspect the ACL Table Before Adding the New Rule\n",
    "\n",
    "Before making any changes, we first examine the current Access Control List (ACL) table on the core router. This inspection provides a snapshot of the existing rules that govern network traffic, including permissions and restrictions related to SSH access. Understanding this baseline is crucial for verifying the effect of new rules, ensuring that changes can be accurately assessed for their impact on network security and access controls.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "some_tech_rt.acl.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "caos_action = [\n",
    "    \"network\", \"node\", \"some_tech_jnr_dev_pc\", \n",
    "    \"service\", \"Terminal\", \"send_remote_command\", str(some_tech_rt.network_interface[4].ip_address),\n",
    "    {\n",
    "        \"command\": [\n",
    "            \"acl\", \"add_rule\", \"PERMIT\", \"TCP\",\n",
    "            str(some_tech_jnr_dev_pc.network_interface[1].ip_address), \"0.0.0.0\", \"SSH\",\n",
    "            str(some_tech_storage_srv.network_interface[1].ip_address), \"0.0.0.0\", \"SSH\",\n",
    "            1\n",
    "        ]\n",
    "    }\n",
    "]\n",
    "\n",
    "game.simulation.apply_request(caos_action)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Verify That the New ACL Rule Has Been Added\n",
    "\n",
    "After updating the ACL rules on the core router, we need to confirm that the new rule has been successfully applied. This verification involves inspecting the ACL table again to ensure that the new rule allowing SSH access from the junior engineer’s PC to the storage server is present. This step is critical to ensure that the modification was executed correctly and that the junior engineer now has the intended access."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "some_tech_rt.acl.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Terminate Remote Session on Core Router\n",
    "\n",
    "After successfully adding the ACL rule to allow SSH access to the storage server, the junior engineer terminates the remote session on the core router. The termination of the session is a strategic move to avoid leaving an active remote login open while maintaining the newly granted access privileges for future use."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "caos_action = [\n",
    "    \"network\", \"node\", \"some_tech_jnr_dev_pc\", \n",
    "    \"service\", \"Terminal\", \"remote_logoff\", str(some_tech_rt.network_interface[4].ip_address)\n",
    "]\n",
    "game.simulation.apply_request(caos_action)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Confirm the termination of the remote session"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "game.get_sim_state()[\"network\"][\"nodes\"][\"some_tech_rt\"][\"services\"][\"UserSessionManager\"][\"active_remote_sessions\"]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## SSH into Storage Server and Delete Database Backup\n",
    "\n",
    "With the newly added ACL rule, the junior engineer can now SSH into the storage server from their machine. The engineer proceeds to delete the critical database backup file stored on the server. This action is pivotal in the attack, as it directly impacts the availability of essential data and sets the stage for subsequent data loss and disruption of services.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "caos_action = [\n",
    "    \"network\", \"node\", \"some_tech_jnr_dev_pc\", \n",
    "    \"service\", \"Terminal\", \"ssh_to_remote\", \"admin\", \"admin\", str(some_tech_storage_srv.network_interface[1].ip_address)\n",
    "]\n",
    "game.simulation.apply_request(caos_action)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "caos_action = [\n",
    "    \"network\", \"node\", \"some_tech_jnr_dev_pc\", \n",
    "    \"service\", \"Terminal\", \"send_remote_command\", str(some_tech_storage_srv.network_interface[1].ip_address),\n",
    "    {\n",
    "        \"command\": [\n",
    "            \"file_system\", \"delete\", \"file\", db_backup_folder, \"database.db\"\n",
    "        ]\n",
    "    }\n",
    "]\n",
    "\n",
    "game.simulation.apply_request(caos_action)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Verify that the database backup file has been deleted"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "some_tech_storage_srv.file_system.show(full=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Delete Critical Data from the PostgreSQL Database\n",
    "\n",
    "In this part of the scenario, the junior engineer manually interacts with the PostgreSQL database to delete critical data. The deletion of critical data from the database has significant implications, leading to the loss of essential information and affecting the availability of the sometech.ai website.\n",
    "\n",
    "* Since the CAOS framework does not support ad-hoc or dynamic SQL queries for database services, this action must be performed manually."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### Again, confirm that the sometech.ai website is up by executing the web browser on the junior engineer's machine"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "caos_action = [\"network\", \"node\", \"some_tech_jnr_dev_pc\", \"application\", \"WebBrowser\", \"execute\"]\n",
    "game.simulation.apply_request(caos_action)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### Set the server IP address and open a new DB connection"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "some_tech_jnr_dev_db_client.server_ip_address = some_tech_db_srv.network_interface[1].ip_address\n",
    "some_tech_jnr_dev_db_connection = some_tech_jnr_dev_db_client.get_new_connection()\n",
    "some_tech_jnr_dev_db_connection"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "tags": []
   },
   "source": [
    "##### Send the DELETE query"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "some_tech_jnr_dev_db_connection.query(\"DELETE\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### Confirm that the actions have brought the sometech.ai website down"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "caos_action = [\"network\", \"node\", \"some_tech_jnr_dev_pc\", \"application\", \"WebBrowser\", \"execute\"]\n",
    "game.simulation.apply_request(caos_action)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Attempt to Restore Database Backup\n",
    "\n",
    "In this final section, an attempt is made to restore the database backup that was deleted earlier. The action is performed using the `some_tech_db_service.restore_backup()` method. This will demonstrate the impact of the data loss and confirm that the backup restoration fails, highlighting the severity of the disruption caused."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "some_tech_db_service.restore_backup()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## End of Scenario Summary\n",
    "\n",
    "In this simulation, we modelled a cyber attack scenario where a disgruntled junior engineer exploits internal network vulnerabilities to escalate privileges, causing significant data loss and disruption of services. The following key actions were performed:\n",
    "\n",
    "1.  **Privilege Escalation:** The junior engineer used social engineering to obtain the login credentials for the core router. They remotely accessed the router via SSH and modified the ACL rules to grant SSH access from their machine to the storage server.\n",
    "\n",
    "2.  **Remote Access:** With the modified ACLs in place, the engineer was able to SSH into the storage server from their machine. This access enabled them to interact with the storage server and perform further actions.\n",
    "\n",
    "3.  **File & Data Deletion:** The engineer used SSH remote access to delete a critical database backup file from the storage server. Subsequently, they executed a SQL command to delete critical data from the PostgreSQL database, which resulted in the disruption of the sometech.ai website.\n",
    "\n",
    "4.  **Website Status Verification:** After the deletion of the database backup, the website's status was checked to confirm that it had been brought down due to the data loss.\n",
    "\n",
    "5.  **Database Restore Failure:** An attempt to restore the deleted backup was made to demonstrate that the restoration process failed, highlighting the severity of the data loss.\n",
    "\n",
    "**Verification and Outcomes:**\n",
    "\n",
    "-   **Initial State Verification:** The backup file was confirmed to be present on the storage server before any actions were taken. The junior engineer's inability to SSH into the storage server initially confirmed that ACL restrictions were in effect.\n",
    "\n",
    "-   **Privilege Escalation Confirmation:** The successful modification of the ACL rules was verified by checking the router's ACL table.\n",
    "\n",
    "-   **Remote Access Verification:** After the ACL modification, the engineer successfully SSH'd into the storage server from their PC. The file system inspection confirmed that the backup file was accessible and could be deleted.\n",
    "\n",
    "-   **File Deletion Confirmation:** The deletion of the backup file was confirmed by inspecting the storage server's file system after the operation. The backup file was marked as deleted, validating that the deletion command was executed.\n",
    "\n",
    "-   **Database and Website Impact:** The deletion of the database backup was followed by a DELETE query executed on the PostgreSQL database. The website's functionality was subsequently checked using a web browser, confirming that the sometech.ai website was down due to the data loss.\n",
    "\n",
    "-   **Restore Attempt Verification:** An attempt to restore the deleted database backup was made, and it was confirmed that the restoration failed, highlighting the impact of the data deletion."
   ]
  }
 ],
 "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": 4
}
