High School Technology Lab

Disk Forensics • Python Scripting • Hash Databases

Class Overview

This isn’t just “how to use a computer.” This lab dives into disk images, hash verification, Python automation, and controlled execution. Students learn how real investigators and engineers work with data, verify integrity, and build tools that don’t just “run”—they prove.

Digital Forensics Module

In this unit, students explore:

The goal: treat files like evidence, not just “stuff on a drive.”

Python Script: MD5-Verified Launcher Lab Demo

Students walk through a Python script that:

Example script used in class:

import hashlib
import sqlite3
import subprocess
import os
import sys
from datetime import datetime

HASH_DB = r"C:\Lab\hash.db"
RUNCOUNT_DB = r"C:\Lab\runcount.db"
KILL_SCRIPT = r"C:\Lab\kill.py"

def md5_of_file(path):
    h = hashlib.md5()
    with open(path, "rb") as f:
        for chunk in iter(lambda: f.read(4096), b""):
            h.update(chunk)
    return h.hexdigest()

def check_hash_in_db(md5_value):
    conn = sqlite3.connect(HASH_DB)
    cur = conn.cursor()
    cur.execute("SELECT COUNT(*) FROM hashes WHERE md5 = ?", (md5_value,))
    result = cur.fetchone()[0]
    conn.close()
    return result > 0

def increment_run_count(file_path):
    conn = sqlite3.connect(RUNCOUNT_DB)
    cur = conn.cursor()
    cur.execute("""
        CREATE TABLE IF NOT EXISTS runs (
            file TEXT PRIMARY KEY,
            count INTEGER,
            last_run TEXT
        )
    """)
    cur.execute("SELECT count FROM runs WHERE file = ?", (file_path,))
    row = cur.fetchone()
    ts = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    if row:
        new_count = row[0] + 1
        cur.execute("UPDATE runs SET count = ?, last_run = ? WHERE file = ?",
                    (new_count, ts, file_path))
    else:
        cur.execute("INSERT INTO runs (file, count, last_run) VALUES (?, ?, ?)",
                    (file_path, 1, ts))
    conn.commit()
    conn.close()

def launch_kill_script():
    print("[SECURITY] Hash mismatch — launching kill.py")
    subprocess.Popen([sys.executable, KILL_SCRIPT])

def launch_program(path):
    print(f"[EXECUTE] Launching: {path}")
    subprocess.Popen([path])

def main():
    if len(sys.argv) != 2:
        print("Usage: launcher.py <program_to_launch>")
        return
    target = sys.argv[1]
    if not os.path.exists(target):
        print(f"[ERROR] File not found: {target}")
        return
    print(f"[INFO] Hashing file: {target}")
    md5_value = md5_of_file(target)
    print(f"[INFO] MD5: {md5_value}")
    print("[INFO] Checking hash database...")
    if check_hash_in_db(md5_value):
        print("[OK] Hash match — execution allowed.")
        increment_run_count(target)
        launch_program(target)
    else:
        print("[FAIL] Hash mismatch — execution denied.")
        launch_kill_script()

if __name__ == "__main__":
    main()
        

Students discuss why this kind of launcher is safer than “double‑click and hope.”

Lab Artifacts & Exercises