Files
labs/Lab-2/Lab-2-Practical/01_Python_Basics_Lab.ipynb

5.5 KiB

Module 2 — Lab 1: Python Fundamentals for Security Analysis

Topics: variables, data types, strings, type casting, operators

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.

Learning objectives

After completing this lab, you will be able to:

  • store security information in variables and select suitable data types;
  • normalize log strings using string methods;
  • cast values read from logs to the required data types;
  • combine comparison and logical operators to flag suspicious activity.
In [ ]:
print("Hello, Cyber World!")

ip_address = "198.51.100.14"
port_number = 443
failed_logins = 7
response_time = 0.125
is_admin = False

print(f"IP: {ip_address} | Port: {port_number}")
print(type(ip_address), type(port_number), type(response_time), type(is_admin))

1. Strings in security logs

In [ ]:
log_message = "  FAILED login for Admin from 198.51.100.14  "
url = "https://example.com/login"

print(log_message.strip())
print(log_message.lower())
print(log_message.replace("FAILED", "DENIED"))
print(url[0:5])

2. Normalize a username and extract the protocol

In [ ]:
raw_username = "  AdMin "

# TODO 1: remove surrounding whitespace and convert the username to lowercase
normalized_username = None

url = "https://example.com/login"
# TODO 2: use slicing to extract the string "https"
protocol = None

print(normalized_username)
print(protocol)

3. Type casting and operators

In [ ]:
port_text = "8080"
# TODO 3: cast port_text to int
port_number = None
# TODO 4: calculate the next port number
next_port = None

login_attempts = 7
user_ip = "198.51.100.14"
# TODO 5: flag as suspicious when attempts > 5 AND the IP is not localhost
is_suspicious = None

print(f"Next port: {next_port}")
print(f"Suspicious: {is_suspicious}")

4. Calculate a basic risk score

In [ ]:
failed_logins = 7
is_admin = False
is_off_hours = True

# Rule: each failure adds 10 points, admin adds 25, and off-hours adds 15
# TODO 6: calculate risk_score and require review at 60 points or higher
risk_score = None
requires_review = None

print(f"Risk score: {risk_score}")
print(f"Requires review: {requires_review}")

Self-check

In [ ]:
assert normalized_username == "admin"
assert protocol == "https"
assert next_port == 8081
assert is_suspicious is True
assert risk_score == 85
assert requires_review is True
print("✓ Lab 1 completed")

Reflection questions

  1. Why does port_text + 1 fail while int(port_text) + 1 works?
  2. What changes if you replace and with or in the is_suspicious condition?