# Practical No. 09 – Penetration Testing
# 1. Local Port Scan, Banner Grabbing and Version Check
# Run only against your own local lab machine.
import socket
from datetime import datetime

vulnerabilities = {
    "Apache/2.2.8": "Outdated Apache version",
    "OpenSSH_4.7": "Outdated OpenSSH version",
    "Microsoft-IIS/6.0": "Deprecated IIS version",
}

def scan_ports(target, ports):
    opened = []
    for port in ports:
        try:
            with socket.create_connection((target, port), timeout=0.5):
                opened.append(port)
                print(f"Port {port} is open")
        except OSError:
            pass
    return opened

def grab_banner(target, port):
    try:
        with socket.create_connection((target, port), timeout=1) as sock:
            sock.settimeout(1)
            return sock.recv(1024).decode(errors="replace").strip()
    except OSError:
        return ""

def check_vulnerabilities(banner):
    for version, warning in vulnerabilities.items():
        if version in banner:
            return warning
    return "No known version match"

if __name__ == "__main__":
    target = "127.0.0.1"
    ports = [21, 22, 23, 25, 80, 110, 143, 443, 3389]
    start = datetime.now()
    for port in scan_ports(target, ports):
        banner = grab_banner(target, port)
        print(f"\nPort {port} banner: {banner or 'Not available'}")
        if banner:
            print(check_vulnerabilities(banner))
    print("\nScan time:", datetime.now() - start)

# 2. Safe SQL-security demonstration
# The input is treated as data by the parameterized query, not as SQL code.
import sqlite3

with sqlite3.connect(":memory:") as db:
    db.execute("CREATE TABLE users (username TEXT, password TEXT)")
    db.execute("INSERT INTO users VALUES (?, ?)", ("admin", "demo"))
    username = input("Test username: ")
    row = db.execute(
        "SELECT username FROM users WHERE username=? AND password=?",
        (username, "demo"),
    ).fetchone()
    print("Login successful" if row else "Invalid credentials")

# Password guessing, SQL-injection probes, and directory enumeration are
# intentionally not included; use instructor-provided isolated lab exercises.

# What this code does: scans selected ports on localhost, checks service
# banners against a small version list, and demonstrates a safe parameterized
# SQL query using an in-memory database.
