mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-06-26 19:54:37 +03:00
203 lines
8.5 KiB
Python
203 lines
8.5 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Physical Security Assessment Tracker
|
|
|
|
Tracks physical intrusion testing attempts, documents findings,
|
|
and generates assessment reports with remediation recommendations.
|
|
"""
|
|
|
|
import json
|
|
import os
|
|
from datetime import datetime
|
|
from collections import defaultdict
|
|
from dataclasses import dataclass, field, asdict
|
|
|
|
|
|
@dataclass
|
|
class PhysicalAccessAttempt:
|
|
"""A single physical access test attempt."""
|
|
attempt_id: str
|
|
timestamp: str
|
|
location: str
|
|
entry_point: str # main_entrance, side_door, loading_dock, etc.
|
|
technique: str # tailgating, badge_clone, lock_pick, social_engineering
|
|
target_area: str # lobby, server_room, executive_floor, data_center
|
|
successful: bool
|
|
detected: bool
|
|
challenged: bool # was tester confronted/questioned
|
|
security_notified: bool
|
|
time_inside_minutes: int = 0
|
|
device_deployed: bool = False
|
|
device_type: str = ""
|
|
evidence_collected: str = ""
|
|
notes: str = ""
|
|
severity: str = "" # critical, high, medium, low
|
|
|
|
|
|
class PhysicalAssessmentTracker:
|
|
"""Track physical security assessment results."""
|
|
|
|
def __init__(self, assessment_id: str, facility_name: str):
|
|
self.assessment_id = assessment_id
|
|
self.facility_name = facility_name
|
|
self.attempts: list[PhysicalAccessAttempt] = []
|
|
|
|
def log_attempt(self, attempt: PhysicalAccessAttempt) -> None:
|
|
"""Log an access attempt."""
|
|
# Auto-assign severity
|
|
if not attempt.severity:
|
|
if attempt.target_area in ("server_room", "data_center") and attempt.successful:
|
|
attempt.severity = "critical"
|
|
elif attempt.successful and not attempt.detected:
|
|
attempt.severity = "high"
|
|
elif attempt.successful and attempt.detected:
|
|
attempt.severity = "medium"
|
|
else:
|
|
attempt.severity = "low"
|
|
self.attempts.append(attempt)
|
|
|
|
def calculate_metrics(self) -> dict:
|
|
"""Calculate assessment metrics."""
|
|
total = len(self.attempts)
|
|
if total == 0:
|
|
return {}
|
|
|
|
successful = [a for a in self.attempts if a.successful]
|
|
detected = [a for a in self.attempts if a.detected]
|
|
challenged = [a for a in self.attempts if a.challenged]
|
|
devices = [a for a in self.attempts if a.device_deployed]
|
|
|
|
# By technique
|
|
technique_stats = defaultdict(lambda: {"total": 0, "success": 0})
|
|
for a in self.attempts:
|
|
technique_stats[a.technique]["total"] += 1
|
|
if a.successful:
|
|
technique_stats[a.technique]["success"] += 1
|
|
|
|
# By area
|
|
area_stats = defaultdict(lambda: {"total": 0, "success": 0})
|
|
for a in self.attempts:
|
|
area_stats[a.target_area]["total"] += 1
|
|
if a.successful:
|
|
area_stats[a.target_area]["success"] += 1
|
|
|
|
return {
|
|
"total_attempts": total,
|
|
"successful_entries": len(successful),
|
|
"success_rate": len(successful) / total * 100,
|
|
"detection_rate": len(detected) / total * 100,
|
|
"challenge_rate": len(challenged) / total * 100,
|
|
"devices_deployed": len(devices),
|
|
"technique_breakdown": dict(technique_stats),
|
|
"area_breakdown": dict(area_stats),
|
|
"avg_time_inside": (
|
|
sum(a.time_inside_minutes for a in successful) / len(successful)
|
|
if successful else 0
|
|
),
|
|
}
|
|
|
|
def generate_report(self) -> str:
|
|
"""Generate assessment report."""
|
|
metrics = self.calculate_metrics()
|
|
if not metrics:
|
|
return "No attempts logged."
|
|
|
|
lines = []
|
|
lines.append("=" * 70)
|
|
lines.append("PHYSICAL SECURITY ASSESSMENT REPORT")
|
|
lines.append(f"Assessment ID: {self.assessment_id}")
|
|
lines.append(f"Facility: {self.facility_name}")
|
|
lines.append(f"Date: {datetime.now().strftime('%Y-%m-%d')}")
|
|
lines.append("=" * 70)
|
|
|
|
lines.append(f"\nSUMMARY:")
|
|
lines.append(f" Total Attempts: {metrics['total_attempts']}")
|
|
lines.append(f" Successful Entries: {metrics['successful_entries']}")
|
|
lines.append(f" Success Rate: {metrics['success_rate']:.1f}%")
|
|
lines.append(f" Detection Rate: {metrics['detection_rate']:.1f}%")
|
|
lines.append(f" Challenge Rate: {metrics['challenge_rate']:.1f}%")
|
|
lines.append(f" Devices Deployed: {metrics['devices_deployed']}")
|
|
lines.append(f" Avg Time Inside: {metrics['avg_time_inside']:.0f} minutes")
|
|
|
|
risk = (
|
|
"CRITICAL" if metrics['success_rate'] > 60
|
|
else "HIGH" if metrics['success_rate'] > 40
|
|
else "MEDIUM" if metrics['success_rate'] > 20
|
|
else "LOW"
|
|
)
|
|
lines.append(f"\n OVERALL RISK: {risk}")
|
|
|
|
lines.append(f"\nTECHNIQUE EFFECTIVENESS:")
|
|
lines.append("-" * 70)
|
|
for tech, stats in metrics["technique_breakdown"].items():
|
|
rate = stats["success"] / stats["total"] * 100 if stats["total"] else 0
|
|
lines.append(f" {tech:<25} {rate:>5.1f}% ({stats['success']}/{stats['total']})")
|
|
|
|
lines.append(f"\nAREA ACCESS:")
|
|
lines.append("-" * 70)
|
|
for area, stats in metrics["area_breakdown"].items():
|
|
rate = stats["success"] / stats["total"] * 100 if stats["total"] else 0
|
|
lines.append(f" {area:<25} {rate:>5.1f}% ({stats['success']}/{stats['total']})")
|
|
|
|
lines.append(f"\nDETAILED FINDINGS:")
|
|
lines.append("-" * 70)
|
|
for a in sorted(self.attempts, key=lambda x: {"critical": 0, "high": 1, "medium": 2, "low": 3}.get(x.severity, 4)):
|
|
status = "SUCCESS" if a.successful else "FAILED"
|
|
lines.append(f"\n [{a.severity.upper()}] {a.location} - {a.entry_point}")
|
|
lines.append(f" Technique: {a.technique} | Result: {status}")
|
|
lines.append(f" Detected: {'Yes' if a.detected else 'No'} | "
|
|
f"Challenged: {'Yes' if a.challenged else 'No'}")
|
|
if a.device_deployed:
|
|
lines.append(f" Device Deployed: {a.device_type}")
|
|
if a.notes:
|
|
lines.append(f" Notes: {a.notes}")
|
|
|
|
lines.append(f"\nREMEDIATIONS:")
|
|
lines.append("-" * 70)
|
|
if metrics["success_rate"] > 50:
|
|
lines.append(" [CRITICAL] Physical access controls require immediate review")
|
|
if any(a.technique == "tailgating" and a.successful for a in self.attempts):
|
|
lines.append(" [HIGH] Install mantraps or anti-tailgating turnstiles")
|
|
lines.append(" [HIGH] Implement security awareness training on tailgating")
|
|
if any(a.technique == "badge_clone" and a.successful for a in self.attempts):
|
|
lines.append(" [HIGH] Upgrade to encrypted RFID (SEOS, DESFire EV2)")
|
|
if metrics["challenge_rate"] < 50:
|
|
lines.append(" [HIGH] Improve guard challenge procedures")
|
|
if any(a.device_deployed for a in self.attempts):
|
|
lines.append(" [CRITICAL] Implement physical port security controls")
|
|
|
|
return "\n".join(lines)
|
|
|
|
|
|
def main():
|
|
"""Demonstrate physical assessment tracking."""
|
|
tracker = PhysicalAssessmentTracker("PHYS-2025-001", "Example Corp HQ")
|
|
|
|
attempts = [
|
|
PhysicalAccessAttempt("P001", "2025-02-10T08:45:00", "Main Building",
|
|
"main_entrance", "tailgating", "lobby", True, False, False, False, 45,
|
|
notes="Followed group during morning rush"),
|
|
PhysicalAccessAttempt("P002", "2025-02-10T10:00:00", "Main Building",
|
|
"side_door", "badge_clone", "office_floor", True, False, False, False, 30,
|
|
notes="Cloned badge from elevator reading"),
|
|
PhysicalAccessAttempt("P003", "2025-02-10T14:00:00", "Data Center Wing",
|
|
"secured_door", "badge_clone", "server_room", True, True, True, True, 5,
|
|
device_deployed=True, device_type="LAN Turtle",
|
|
notes="Guard challenged but accepted fake contractor story"),
|
|
PhysicalAccessAttempt("P004", "2025-02-11T07:30:00", "Loading Dock",
|
|
"loading_dock", "social_engineering", "warehouse", True, False, False, False, 20,
|
|
notes="Posed as delivery driver with empty boxes"),
|
|
PhysicalAccessAttempt("P005", "2025-02-11T12:00:00", "Executive Floor",
|
|
"elevator", "tailgating", "executive_office", False, True, True, True, 0,
|
|
notes="Security escort required, access denied"),
|
|
]
|
|
|
|
for attempt in attempts:
|
|
tracker.log_attempt(attempt)
|
|
|
|
print(tracker.generate_report())
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|