242 lines
5.5 KiB
Plaintext
242 lines
5.5 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "eca32fd8",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Module 2 — Lab 1: Python Fundamentals for Security Analysis\n",
|
|
"\n",
|
|
"**Topics:** variables, data types, strings, type casting, operators\n",
|
|
"\n",
|
|
"\n",
|
|
"> **Instructions:** Run the cells in order. Complete every `TODO`, then run the **Self-check** cell. Do not open the Solution notebook before attempting the tasks yourself.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "da8ed50e",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Learning objectives\n",
|
|
"\n",
|
|
"After completing this lab, you will be able to:\n",
|
|
"\n",
|
|
"- store security information in variables and select suitable data types;\n",
|
|
"- normalize log strings using string methods;\n",
|
|
"- cast values read from logs to the required data types;\n",
|
|
"- combine comparison and logical operators to flag suspicious activity.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "0a4d2b7d",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"print(\"Hello, Cyber World!\")\n",
|
|
"\n",
|
|
"ip_address = \"198.51.100.14\"\n",
|
|
"port_number = 443\n",
|
|
"failed_logins = 7\n",
|
|
"response_time = 0.125\n",
|
|
"is_admin = False\n",
|
|
"\n",
|
|
"print(f\"IP: {ip_address} | Port: {port_number}\")\n",
|
|
"print(type(ip_address), type(port_number), type(response_time), type(is_admin))\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "d700974b",
|
|
"metadata": {},
|
|
"source": [
|
|
"## 1. Strings in security logs\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "776c60e6",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"log_message = \" FAILED login for Admin from 198.51.100.14 \"\n",
|
|
"url = \"https://example.com/login\"\n",
|
|
"\n",
|
|
"print(log_message.strip())\n",
|
|
"print(log_message.lower())\n",
|
|
"print(log_message.replace(\"FAILED\", \"DENIED\"))\n",
|
|
"print(url[0:5])\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "a31e697c",
|
|
"metadata": {
|
|
"tags": [
|
|
"exercise"
|
|
]
|
|
},
|
|
"source": [
|
|
"## 2. Normalize a username and extract the protocol\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "02195f3c",
|
|
"metadata": {
|
|
"tags": [
|
|
"exercise"
|
|
]
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"raw_username = \" AdMin \"\n",
|
|
"\n",
|
|
"# TODO 1: remove surrounding whitespace and convert the username to lowercase\n",
|
|
"normalized_username = None\n",
|
|
"\n",
|
|
"url = \"https://example.com/login\"\n",
|
|
"# TODO 2: use slicing to extract the string \"https\"\n",
|
|
"protocol = None\n",
|
|
"\n",
|
|
"print(normalized_username)\n",
|
|
"print(protocol)\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "c22bc685",
|
|
"metadata": {
|
|
"tags": [
|
|
"exercise"
|
|
]
|
|
},
|
|
"source": [
|
|
"## 3. Type casting and operators\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "ee235adb",
|
|
"metadata": {
|
|
"tags": [
|
|
"exercise"
|
|
]
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"port_text = \"8080\"\n",
|
|
"# TODO 3: cast port_text to int\n",
|
|
"port_number = None\n",
|
|
"# TODO 4: calculate the next port number\n",
|
|
"next_port = None\n",
|
|
"\n",
|
|
"login_attempts = 7\n",
|
|
"user_ip = \"198.51.100.14\"\n",
|
|
"# TODO 5: flag as suspicious when attempts > 5 AND the IP is not localhost\n",
|
|
"is_suspicious = None\n",
|
|
"\n",
|
|
"print(f\"Next port: {next_port}\")\n",
|
|
"print(f\"Suspicious: {is_suspicious}\")\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "8bfdaf0b",
|
|
"metadata": {
|
|
"tags": [
|
|
"exercise"
|
|
]
|
|
},
|
|
"source": [
|
|
"## 4. Calculate a basic risk score\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "1dde9681",
|
|
"metadata": {
|
|
"tags": [
|
|
"exercise"
|
|
]
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"failed_logins = 7\n",
|
|
"is_admin = False\n",
|
|
"is_off_hours = True\n",
|
|
"\n",
|
|
"# Rule: each failure adds 10 points, admin adds 25, and off-hours adds 15\n",
|
|
"# TODO 6: calculate risk_score and require review at 60 points or higher\n",
|
|
"risk_score = None\n",
|
|
"requires_review = None\n",
|
|
"\n",
|
|
"print(f\"Risk score: {risk_score}\")\n",
|
|
"print(f\"Requires review: {requires_review}\")\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "bdfa1e23",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Self-check\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "8e9fa7c6",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"assert normalized_username == \"admin\"\n",
|
|
"assert protocol == \"https\"\n",
|
|
"assert next_port == 8081\n",
|
|
"assert is_suspicious is True\n",
|
|
"assert risk_score == 85\n",
|
|
"assert requires_review is True\n",
|
|
"print(\"✓ Lab 1 completed\")\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "c63bef39",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Reflection questions\n",
|
|
"\n",
|
|
"1. Why does `port_text + 1` fail while `int(port_text) + 1` works?\n",
|
|
"2. What changes if you replace `and` with `or` in the `is_suspicious` condition?\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
|
|
}
|