{ "cells": [ { "cell_type": "markdown", "id": "2e0973be-fd6d-4467-b006-f30e455eae87", "metadata": {}, "source": [ "# Download & load the dataset" ] }, { "cell_type": "code", "execution_count": 1, "id": "17023a3e-0ed8-4b1b-a7c0-b63268c8ca33", "metadata": {}, "outputs": [], "source": [ "import requests, zipfile, io\n", "\n", "# URL for the NSL-KDD dataset\n", "url = \"https://academy.hackthebox.com/storage/modules/292/KDD_dataset.zip\"\n", "\n", "# Download the zip file and extract its contents\n", "response = requests.get(url)\n", "z = zipfile.ZipFile(io.BytesIO(response.content))\n", "z.extractall('.') # Extracts to the current directory\n" ] }, { "cell_type": "code", "execution_count": 2, "id": "ae73c6f7-aa06-4383-bfcb-bf33af11a36e", "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import pandas as pd\n", "from sklearn.ensemble import RandomForestClassifier\n", "from sklearn.model_selection import train_test_split\n", "from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, confusion_matrix, classification_report\n", "import seaborn as sns\n", "import matplotlib.pyplot as plt" ] }, { "cell_type": "code", "execution_count": 3, "id": "4a38157b-ab82-4739-b1b8-30646064f943", "metadata": {}, "outputs": [], "source": [ "# Set the file path to the dataset\n", "file_path = r'KDD+.txt'\n", "\n", "# Define the column names corresponding to the NSL-KDD dataset\n", "columns = [\n", " 'duration', 'protocol_type', 'service', 'flag', 'src_bytes', 'dst_bytes', \n", " 'land', 'wrong_fragment', 'urgent', 'hot', 'num_failed_logins', 'logged_in', \n", " 'num_compromised', 'root_shell', 'su_attempted', 'num_root', 'num_file_creations', \n", " 'num_shells', 'num_access_files', 'num_outbound_cmds', 'is_host_login', 'is_guest_login', \n", " 'count', 'srv_count', 'serror_rate', 'srv_serror_rate', 'rerror_rate', 'srv_rerror_rate', \n", " 'same_srv_rate', 'diff_srv_rate', 'srv_diff_host_rate', 'dst_host_count', 'dst_host_srv_count', \n", " 'dst_host_same_srv_rate', 'dst_host_diff_srv_rate', 'dst_host_same_src_port_rate', \n", " 'dst_host_srv_diff_host_rate', 'dst_host_serror_rate', 'dst_host_srv_serror_rate', \n", " 'dst_host_rerror_rate', 'dst_host_srv_rerror_rate', 'attack', 'level'\n", "]" ] }, { "cell_type": "code", "execution_count": 4, "id": "d4d7b05e-894d-4f54-886a-f3469f473675", "metadata": {}, "outputs": [], "source": [ "df = pd.read_csv(file_path, names=columns)" ] }, { "cell_type": "code", "execution_count": 5, "id": "fe6882f3-1e5c-4195-88a4-4d58d2ac0d37", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " duration protocol_type service flag src_bytes dst_bytes land \\\n", "0 0 tcp ftp_data SF 491 0 0 \n", "1 0 udp other SF 146 0 0 \n", "2 0 tcp private S0 0 0 0 \n", "3 0 tcp http SF 232 8153 0 \n", "4 0 tcp http SF 199 420 0 \n", "\n", " wrong_fragment urgent hot ... dst_host_same_srv_rate \\\n", "0 0 0 0 ... 0.17 \n", "1 0 0 0 ... 0.00 \n", "2 0 0 0 ... 0.10 \n", "3 0 0 0 ... 1.00 \n", "4 0 0 0 ... 1.00 \n", "\n", " dst_host_diff_srv_rate dst_host_same_src_port_rate \\\n", "0 0.03 0.17 \n", "1 0.60 0.88 \n", "2 0.05 0.00 \n", "3 0.00 0.03 \n", "4 0.00 0.00 \n", "\n", " dst_host_srv_diff_host_rate dst_host_serror_rate \\\n", "0 0.00 0.00 \n", "1 0.00 0.00 \n", "2 0.00 1.00 \n", "3 0.04 0.03 \n", "4 0.00 0.00 \n", "\n", " dst_host_srv_serror_rate dst_host_rerror_rate dst_host_srv_rerror_rate \\\n", "0 0.00 0.05 0.00 \n", "1 0.00 0.00 0.00 \n", "2 1.00 0.00 0.00 \n", "3 0.01 0.00 0.01 \n", "4 0.00 0.00 0.00 \n", "\n", " attack level \n", "0 normal 20 \n", "1 normal 15 \n", "2 neptune 19 \n", "3 normal 21 \n", "4 normal 21 \n", "\n", "[5 rows x 43 columns]\n" ] } ], "source": [ "print(df.head())" ] }, { "cell_type": "markdown", "id": "44b7cf45-5cfe-4a7d-9e15-b59cc369028e", "metadata": {}, "source": [ "# Preprocessing and Splitting the Dataset" ] }, { "cell_type": "code", "execution_count": 6, "id": "084802d8-ff3e-4d34-89f7-3d2e238c413a", "metadata": {}, "outputs": [], "source": [ "# Binary classification target\n", "# Maps normal traffic to 0 and any type of attack to 1\n", "df['attack_flag'] = df['attack'].apply(lambda a: 0 if a == 'normal' else 1)" ] }, { "cell_type": "markdown", "id": "c275f531-ac9f-4661-a07c-cc07efc354f4", "metadata": {}, "source": [ "# Multi-class classification target" ] }, { "cell_type": "code", "execution_count": 7, "id": "1b18dd99-adb4-44ca-8b86-4807428eea87", "metadata": {}, "outputs": [], "source": [ "# Multi-class classification target categories\n", "dos_attacks = ['apache2', 'back', 'land', 'neptune', 'mailbomb', 'pod', \n", " 'processtable', 'smurf', 'teardrop', 'udpstorm', 'worm']\n", "probe_attacks = ['ipsweep', 'mscan', 'nmap', 'portsweep', 'saint', 'satan']\n", "privilege_attacks = ['buffer_overflow', 'loadmdoule', 'perl', 'ps', \n", " 'rootkit', 'sqlattack', 'xterm']\n", "access_attacks = ['ftp_write', 'guess_passwd', 'http_tunnel', 'imap', \n", " 'multihop', 'named', 'phf', 'sendmail', 'snmpgetattack', \n", " 'snmpguess', 'spy', 'warezclient', 'warezmaster', \n", " 'xclock', 'xsnoop']\n", "\n", "def map_attack(attack):\n", " if attack in dos_attacks:\n", " return 1\n", " elif attack in probe_attacks:\n", " return 2\n", " elif attack in privilege_attacks:\n", " return 3\n", " elif attack in access_attacks:\n", " return 4\n", " else:\n", " return 0\n", "\n", "# Assign multi-class category to each row\n", "df['attack_map'] = df['attack'].apply(map_attack)\n" ] }, { "cell_type": "markdown", "id": "be5f32df-4218-416c-832f-e190f97a8e47", "metadata": {}, "source": [ "# Encoding Categorical Variables" ] }, { "cell_type": "code", "execution_count": null, "id": "777d9ee2-40bb-400e-9264-47e67b7834c0", "metadata": {}, "outputs": [], "source": [ "# Numeric features that capture various statistical properties of the traffic\n", "numeric_features = [\n", " 'duration', 'src_bytes', 'dst_bytes', 'wrong_fragment', 'urgent', 'hot', \n", " 'num_failed_logins', 'num_compromised', 'root_shell', 'su_attempted', \n", " 'num_root', 'num_file_creations', 'num_shells', 'num_access_files', \n", " 'num_outbound_cmds', 'count', 'srv_count', 'serror_rate', \n", " 'srv_serror_rate', 'rerror_rate', 'srv_rerror_rate', 'same_srv_rate', \n", " 'diff_srv_rate', 'srv_diff_host_rate', 'dst_host_count', 'dst_host_srv_count', \n", " 'dst_host_same_srv_rate', 'dst_host_diff_srv_rate', \n", " 'dst_host_same_src_port_rate', 'dst_host_srv_diff_host_rate', \n", " 'dst_host_serror_rate', 'dst_host_srv_serror_rate', 'dst_host_rerror_rate', \n", " 'dst_host_srv_rerror_rate'\n", "]\n" ] } ], "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.11.6" } }, "nbformat": 4, "nbformat_minor": 5 }