mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-06-10 21:24:56 +03:00
367 lines
14 KiB
Python
367 lines
14 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Anti-Phishing Training Program Analytics
|
|
|
|
Tracks training completion, simulation results, and program effectiveness
|
|
over time. Generates reports comparing departments, identifying repeat
|
|
offenders, and measuring ROI.
|
|
|
|
Usage:
|
|
python process.py dashboard --data program_data.json
|
|
python process.py trend --data program_data.json --months 12
|
|
python process.py repeat-offenders --data program_data.json
|
|
python process.py department-report --data program_data.json
|
|
"""
|
|
|
|
import argparse
|
|
import json
|
|
import sys
|
|
from datetime import datetime, timezone
|
|
from collections import defaultdict
|
|
from dataclasses import dataclass, field, asdict
|
|
|
|
|
|
@dataclass
|
|
class UserRecord:
|
|
"""Training and simulation record for a single user."""
|
|
email: str = ""
|
|
name: str = ""
|
|
department: str = ""
|
|
role: str = ""
|
|
simulations_sent: int = 0
|
|
simulations_clicked: int = 0
|
|
simulations_submitted: int = 0
|
|
simulations_reported: int = 0
|
|
trainings_assigned: int = 0
|
|
trainings_completed: int = 0
|
|
last_simulation_date: str = ""
|
|
last_training_date: str = ""
|
|
risk_level: str = "low"
|
|
|
|
|
|
@dataclass
|
|
class DepartmentMetrics:
|
|
"""Aggregated metrics for a department."""
|
|
name: str = ""
|
|
total_users: int = 0
|
|
avg_click_rate: float = 0.0
|
|
avg_submit_rate: float = 0.0
|
|
avg_report_rate: float = 0.0
|
|
training_completion: float = 0.0
|
|
repeat_offenders: int = 0
|
|
trend: str = "stable"
|
|
|
|
|
|
@dataclass
|
|
class ProgramDashboard:
|
|
"""Overall program dashboard metrics."""
|
|
total_users: int = 0
|
|
total_simulations_sent: int = 0
|
|
overall_click_rate: float = 0.0
|
|
overall_submit_rate: float = 0.0
|
|
overall_report_rate: float = 0.0
|
|
training_completion_rate: float = 0.0
|
|
repeat_offender_count: int = 0
|
|
repeat_offender_rate: float = 0.0
|
|
maturity_level: int = 1
|
|
departments: list = field(default_factory=list)
|
|
top_risks: list = field(default_factory=list)
|
|
monthly_trends: list = field(default_factory=list)
|
|
|
|
|
|
def calculate_risk_level(user: UserRecord) -> str:
|
|
"""Calculate risk level for a user based on simulation history."""
|
|
if user.simulations_sent == 0:
|
|
return "unknown"
|
|
|
|
click_rate = user.simulations_clicked / user.simulations_sent
|
|
submit_rate = user.simulations_submitted / user.simulations_sent
|
|
|
|
if submit_rate > 0.3 or user.simulations_submitted >= 3:
|
|
return "critical"
|
|
elif click_rate > 0.4 or user.simulations_clicked >= 3:
|
|
return "high"
|
|
elif click_rate > 0.2:
|
|
return "medium"
|
|
elif user.simulations_reported > 0:
|
|
return "low"
|
|
else:
|
|
return "low"
|
|
|
|
|
|
def assess_maturity(dashboard: ProgramDashboard) -> int:
|
|
"""Assess SANS Security Awareness Maturity level (1-5)."""
|
|
if dashboard.total_simulations_sent == 0:
|
|
return 1 # Non-existent
|
|
|
|
if dashboard.training_completion_rate < 50:
|
|
return 2 # Compliance-focused
|
|
|
|
if dashboard.overall_click_rate > 15:
|
|
return 2
|
|
|
|
if dashboard.overall_click_rate > 5:
|
|
return 3 # Promoting Awareness
|
|
|
|
if dashboard.overall_report_rate > 50 and dashboard.overall_click_rate < 5:
|
|
return 5 # Metrics Framework
|
|
|
|
return 4 # Long-term Sustainment
|
|
|
|
|
|
def process_program_data(data: dict) -> ProgramDashboard:
|
|
"""Process raw program data into dashboard metrics."""
|
|
dashboard = ProgramDashboard()
|
|
|
|
users_data = data.get("users", [])
|
|
simulations = data.get("simulations", [])
|
|
trainings = data.get("trainings", [])
|
|
|
|
# Build user records
|
|
user_records = {}
|
|
for u in users_data:
|
|
record = UserRecord(
|
|
email=u.get("email", ""),
|
|
name=u.get("name", ""),
|
|
department=u.get("department", "Unknown"),
|
|
role=u.get("role", ""),
|
|
)
|
|
user_records[record.email] = record
|
|
|
|
# Process simulation results
|
|
for sim in simulations:
|
|
for result in sim.get("results", []):
|
|
email = result.get("email", "")
|
|
if email in user_records:
|
|
user = user_records[email]
|
|
user.simulations_sent += 1
|
|
if result.get("clicked"):
|
|
user.simulations_clicked += 1
|
|
if result.get("submitted"):
|
|
user.simulations_submitted += 1
|
|
if result.get("reported"):
|
|
user.simulations_reported += 1
|
|
user.last_simulation_date = sim.get("date", "")
|
|
|
|
# Process training completions
|
|
for training in trainings:
|
|
for completion in training.get("completions", []):
|
|
email = completion.get("email", "")
|
|
if email in user_records:
|
|
user = user_records[email]
|
|
user.trainings_assigned += 1
|
|
if completion.get("completed"):
|
|
user.trainings_completed += 1
|
|
user.last_training_date = training.get("date", "")
|
|
|
|
# Calculate risk levels
|
|
for user in user_records.values():
|
|
user.risk_level = calculate_risk_level(user)
|
|
|
|
# Aggregate overall metrics
|
|
all_users = list(user_records.values())
|
|
dashboard.total_users = len(all_users)
|
|
|
|
total_sent = sum(u.simulations_sent for u in all_users)
|
|
total_clicked = sum(u.simulations_clicked for u in all_users)
|
|
total_submitted = sum(u.simulations_submitted for u in all_users)
|
|
total_reported = sum(u.simulations_reported for u in all_users)
|
|
total_assigned = sum(u.trainings_assigned for u in all_users)
|
|
total_completed = sum(u.trainings_completed for u in all_users)
|
|
|
|
dashboard.total_simulations_sent = total_sent
|
|
dashboard.overall_click_rate = round(total_clicked / max(total_sent, 1) * 100, 1)
|
|
dashboard.overall_submit_rate = round(total_submitted / max(total_sent, 1) * 100, 1)
|
|
dashboard.overall_report_rate = round(total_reported / max(total_sent, 1) * 100, 1)
|
|
dashboard.training_completion_rate = round(total_completed / max(total_assigned, 1) * 100, 1)
|
|
|
|
# Repeat offenders (clicked 2+ times)
|
|
repeat_offenders = [u for u in all_users if u.simulations_clicked >= 2]
|
|
dashboard.repeat_offender_count = len(repeat_offenders)
|
|
dashboard.repeat_offender_rate = round(
|
|
len(repeat_offenders) / max(len(all_users), 1) * 100, 1
|
|
)
|
|
|
|
# Department breakdown
|
|
dept_users = defaultdict(list)
|
|
for user in all_users:
|
|
dept_users[user.department].append(user)
|
|
|
|
for dept_name, users in sorted(dept_users.items()):
|
|
dept = DepartmentMetrics(name=dept_name, total_users=len(users))
|
|
|
|
d_sent = sum(u.simulations_sent for u in users)
|
|
d_clicked = sum(u.simulations_clicked for u in users)
|
|
d_submitted = sum(u.simulations_submitted for u in users)
|
|
d_reported = sum(u.simulations_reported for u in users)
|
|
d_assigned = sum(u.trainings_assigned for u in users)
|
|
d_completed = sum(u.trainings_completed for u in users)
|
|
|
|
dept.avg_click_rate = round(d_clicked / max(d_sent, 1) * 100, 1)
|
|
dept.avg_submit_rate = round(d_submitted / max(d_sent, 1) * 100, 1)
|
|
dept.avg_report_rate = round(d_reported / max(d_sent, 1) * 100, 1)
|
|
dept.training_completion = round(d_completed / max(d_assigned, 1) * 100, 1)
|
|
dept.repeat_offenders = sum(1 for u in users if u.simulations_clicked >= 2)
|
|
|
|
dashboard.departments.append(dept)
|
|
|
|
# Top risk users
|
|
risk_users = sorted(all_users, key=lambda u: u.simulations_submitted, reverse=True)
|
|
dashboard.top_risks = [
|
|
{"email": u.email, "name": u.name, "department": u.department,
|
|
"click_count": u.simulations_clicked, "submit_count": u.simulations_submitted,
|
|
"risk_level": u.risk_level}
|
|
for u in risk_users[:20] if u.simulations_clicked > 0
|
|
]
|
|
|
|
# Monthly trends from simulation data
|
|
monthly = defaultdict(lambda: {"sent": 0, "clicked": 0, "submitted": 0, "reported": 0})
|
|
for sim in simulations:
|
|
month = sim.get("date", "")[:7] # YYYY-MM
|
|
for result in sim.get("results", []):
|
|
monthly[month]["sent"] += 1
|
|
if result.get("clicked"):
|
|
monthly[month]["clicked"] += 1
|
|
if result.get("submitted"):
|
|
monthly[month]["submitted"] += 1
|
|
if result.get("reported"):
|
|
monthly[month]["reported"] += 1
|
|
|
|
for month in sorted(monthly.keys()):
|
|
m = monthly[month]
|
|
dashboard.monthly_trends.append({
|
|
"month": month,
|
|
"sent": m["sent"],
|
|
"click_rate": round(m["clicked"] / max(m["sent"], 1) * 100, 1),
|
|
"submit_rate": round(m["submitted"] / max(m["sent"], 1) * 100, 1),
|
|
"report_rate": round(m["reported"] / max(m["sent"], 1) * 100, 1),
|
|
})
|
|
|
|
dashboard.maturity_level = assess_maturity(dashboard)
|
|
|
|
return dashboard
|
|
|
|
|
|
def format_dashboard(dashboard: ProgramDashboard) -> str:
|
|
"""Format dashboard as text report."""
|
|
lines = []
|
|
lines.append("=" * 65)
|
|
lines.append(" ANTI-PHISHING TRAINING PROGRAM DASHBOARD")
|
|
lines.append("=" * 65)
|
|
lines.append(f" Generated: {datetime.now(timezone.utc).strftime('%Y-%m-%d %H:%M UTC')}")
|
|
lines.append(f" Maturity Level: {dashboard.maturity_level}/5 (SANS Model)")
|
|
lines.append("")
|
|
|
|
lines.append("[PROGRAM OVERVIEW]")
|
|
lines.append(f" Total Users: {dashboard.total_users}")
|
|
lines.append(f" Total Simulations Sent: {dashboard.total_simulations_sent}")
|
|
lines.append(f" Overall Click Rate: {dashboard.overall_click_rate}%")
|
|
lines.append(f" Overall Submit Rate: {dashboard.overall_submit_rate}%")
|
|
lines.append(f" Overall Report Rate: {dashboard.overall_report_rate}%")
|
|
lines.append(f" Training Completion: {dashboard.training_completion_rate}%")
|
|
lines.append(f" Repeat Offenders: {dashboard.repeat_offender_count} "
|
|
f"({dashboard.repeat_offender_rate}%)")
|
|
lines.append("")
|
|
|
|
lines.append("[DEPARTMENT BREAKDOWN]")
|
|
lines.append(f" {'Department':<20} {'Users':>6} {'Click%':>7} {'Submit%':>8} "
|
|
f"{'Report%':>8} {'Training%':>10} {'Repeat':>7}")
|
|
lines.append(" " + "-" * 66)
|
|
for dept in sorted(dashboard.departments, key=lambda d: d.avg_click_rate, reverse=True):
|
|
lines.append(f" {dept.name:<20} {dept.total_users:>6} {dept.avg_click_rate:>6.1f}% "
|
|
f"{dept.avg_submit_rate:>7.1f}% {dept.avg_report_rate:>7.1f}% "
|
|
f"{dept.training_completion:>9.1f}% {dept.repeat_offenders:>7}")
|
|
lines.append("")
|
|
|
|
if dashboard.top_risks:
|
|
lines.append("[TOP RISK USERS]")
|
|
for i, user in enumerate(dashboard.top_risks[:10], 1):
|
|
lines.append(f" {i}. {user['name']} ({user['department']}) - "
|
|
f"Clicked: {user['click_count']}, Submitted: {user['submit_count']} "
|
|
f"[{user['risk_level'].upper()}]")
|
|
lines.append("")
|
|
|
|
if dashboard.monthly_trends:
|
|
lines.append("[MONTHLY TRENDS]")
|
|
lines.append(f" {'Month':<10} {'Sent':>6} {'Click%':>7} {'Submit%':>8} {'Report%':>8}")
|
|
lines.append(" " + "-" * 39)
|
|
for trend in dashboard.monthly_trends[-12:]:
|
|
lines.append(f" {trend['month']:<10} {trend['sent']:>6} "
|
|
f"{trend['click_rate']:>6.1f}% {trend['submit_rate']:>7.1f}% "
|
|
f"{trend['report_rate']:>7.1f}%")
|
|
|
|
lines.append("")
|
|
lines.append("=" * 65)
|
|
return "\n".join(lines)
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description="Anti-Phishing Training Program Analytics")
|
|
subparsers = parser.add_subparsers(dest="command")
|
|
|
|
dash_parser = subparsers.add_parser("dashboard", help="Generate program dashboard")
|
|
dash_parser.add_argument("--data", required=True, help="Program data JSON file")
|
|
dash_parser.add_argument("--output", "-o", help="Output file")
|
|
|
|
dept_parser = subparsers.add_parser("department-report", help="Department breakdown")
|
|
dept_parser.add_argument("--data", required=True)
|
|
|
|
repeat_parser = subparsers.add_parser("repeat-offenders", help="List repeat offenders")
|
|
repeat_parser.add_argument("--data", required=True)
|
|
repeat_parser.add_argument("--threshold", type=int, default=2, help="Minimum click count")
|
|
|
|
trend_parser = subparsers.add_parser("trend", help="Show monthly trends")
|
|
trend_parser.add_argument("--data", required=True)
|
|
trend_parser.add_argument("--months", type=int, default=12)
|
|
|
|
parser.add_argument("--json", action="store_true", help="Output as JSON")
|
|
|
|
args = parser.parse_args()
|
|
|
|
if not args.command:
|
|
parser.print_help()
|
|
sys.exit(1)
|
|
|
|
with open(args.data, "r") as f:
|
|
data = json.load(f)
|
|
|
|
dashboard = process_program_data(data)
|
|
|
|
if args.command == "dashboard":
|
|
if args.json:
|
|
output = json.dumps(asdict(dashboard), indent=2, default=str)
|
|
else:
|
|
output = format_dashboard(dashboard)
|
|
|
|
if args.output:
|
|
with open(args.output, "w") as f:
|
|
f.write(output)
|
|
print(f"Dashboard written to {args.output}")
|
|
else:
|
|
print(output)
|
|
|
|
elif args.command == "department-report":
|
|
for dept in sorted(dashboard.departments, key=lambda d: d.avg_click_rate, reverse=True):
|
|
if args.json:
|
|
print(json.dumps(asdict(dept), indent=2))
|
|
else:
|
|
print(f"{dept.name}: {dept.total_users} users, "
|
|
f"click={dept.avg_click_rate}%, report={dept.avg_report_rate}%, "
|
|
f"training={dept.training_completion}%")
|
|
|
|
elif args.command == "repeat-offenders":
|
|
for user in dashboard.top_risks:
|
|
if user["click_count"] >= args.threshold:
|
|
print(f" {user['name']} ({user['department']}): "
|
|
f"clicked {user['click_count']}x, submitted {user['submit_count']}x "
|
|
f"[{user['risk_level']}]")
|
|
|
|
elif args.command == "trend":
|
|
for trend in dashboard.monthly_trends[-args.months:]:
|
|
print(f" {trend['month']}: click={trend['click_rate']}%, "
|
|
f"submit={trend['submit_rate']}%, report={trend['report_rate']}%")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|