234 lines
5.2 KiB
Plaintext
234 lines
5.2 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "a9ae0aa5",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Module 2 — Lab 1: Python Fundamentals for Security Analysis\n",
|
|
"\n",
|
|
"**Topics:** variables, data types, strings, type casting, operators\n",
|
|
"\n",
|
|
"\n",
|
|
"> **Solution version:** This notebook contains the complete solution. Run the cells in order and compare the results with your Lab notebook.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "6b669205",
|
|
"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": "5338112e",
|
|
"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": "0094841a",
|
|
"metadata": {},
|
|
"source": [
|
|
"## 1. Strings in security logs\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "b5ed12a4",
|
|
"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": "c484946c",
|
|
"metadata": {
|
|
"tags": [
|
|
"exercise"
|
|
]
|
|
},
|
|
"source": [
|
|
"## 2. Normalize a username and extract the protocol\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "c62e36d5",
|
|
"metadata": {
|
|
"tags": [
|
|
"solution"
|
|
]
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"raw_username = \" AdMin \"\n",
|
|
"normalized_username = raw_username.strip().lower()\n",
|
|
"\n",
|
|
"url = \"https://example.com/login\"\n",
|
|
"protocol = url[0:5]\n",
|
|
"\n",
|
|
"print(normalized_username)\n",
|
|
"print(protocol)\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "9f02318b",
|
|
"metadata": {
|
|
"tags": [
|
|
"exercise"
|
|
]
|
|
},
|
|
"source": [
|
|
"## 3. Type casting and operators\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "61827b28",
|
|
"metadata": {
|
|
"tags": [
|
|
"solution"
|
|
]
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"port_text = \"8080\"\n",
|
|
"port_number = int(port_text)\n",
|
|
"next_port = port_number + 1\n",
|
|
"\n",
|
|
"login_attempts = 7\n",
|
|
"user_ip = \"198.51.100.14\"\n",
|
|
"is_suspicious = login_attempts > 5 and user_ip != \"127.0.0.1\"\n",
|
|
"\n",
|
|
"print(f\"Next port: {next_port}\")\n",
|
|
"print(f\"Suspicious: {is_suspicious}\")\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "0613c68c",
|
|
"metadata": {
|
|
"tags": [
|
|
"exercise"
|
|
]
|
|
},
|
|
"source": [
|
|
"## 4. Calculate a basic risk score\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "fa8d9c4d",
|
|
"metadata": {
|
|
"tags": [
|
|
"solution"
|
|
]
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"failed_logins = 7\n",
|
|
"is_admin = False\n",
|
|
"is_off_hours = True\n",
|
|
"\n",
|
|
"risk_score = failed_logins * 10 + int(is_admin) * 25 + int(is_off_hours) * 15\n",
|
|
"requires_review = risk_score >= 60\n",
|
|
"\n",
|
|
"print(f\"Risk score: {risk_score}\")\n",
|
|
"print(f\"Requires review: {requires_review}\")\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "285b59c6",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Self-check\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "3a59fbe2",
|
|
"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": "92257020",
|
|
"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
|
|
}
|