mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-06-13 14:44:58 +03:00
294 lines
11 KiB
Python
294 lines
11 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Ransomware Honeypot Deployment and Monitoring Tool
|
|
|
|
Deploys canary files across file shares and monitors for modifications
|
|
that indicate ransomware activity. Supports:
|
|
- Canary file generation with realistic content
|
|
- File system monitoring with immediate alerting
|
|
- Integration with SIEM via syslog
|
|
- Automated containment via API calls
|
|
"""
|
|
|
|
import hashlib
|
|
import json
|
|
import logging
|
|
import os
|
|
import sys
|
|
import time
|
|
from dataclasses import dataclass, field, asdict
|
|
from datetime import datetime
|
|
from pathlib import Path
|
|
from typing import Optional
|
|
|
|
logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s")
|
|
logger = logging.getLogger("ransomware_honeypot")
|
|
|
|
|
|
@dataclass
|
|
class CanaryFile:
|
|
path: str
|
|
original_hash: str
|
|
file_type: str
|
|
deploy_time: str
|
|
share_name: str
|
|
status: str = "active"
|
|
last_check: Optional[str] = None
|
|
alert_triggered: bool = False
|
|
|
|
|
|
@dataclass
|
|
class CanaryAlert:
|
|
timestamp: str
|
|
canary_path: str
|
|
change_type: str # modified, deleted, renamed, extension_changed
|
|
source_info: str
|
|
severity: str = "CRITICAL"
|
|
automated_response: str = ""
|
|
|
|
|
|
CANARY_TEMPLATES = {
|
|
"finance": [
|
|
("!_Budget_FY2026_FINAL.xlsx", "FY2026 Budget Summary\nTotal Revenue: $142.3M\nTotal Expenses: $98.7M\nNet Income: $43.6M"),
|
|
("000_Quarterly_Earnings.docx", "Q4 2025 Earnings Report\nRevenue: $38.2M\nGross Margin: 67%\nEBITDA: $12.1M"),
|
|
("_Executive_Compensation.pdf", "Executive Compensation Committee Report\nCEO Total Comp: $2.1M\nCFO Total Comp: $1.4M"),
|
|
],
|
|
"hr": [
|
|
("!_Employee_SSN_List.xlsx", "Employee ID | Name | SSN\n10001 | Smith, John | XXX-XX-1234\n10002 | Johnson, Mary | XXX-XX-5678"),
|
|
("000_Salary_Database_2026.csv", "Employee,Department,Base Salary,Bonus\nSmith J,Engineering,$145000,$29000"),
|
|
("_Termination_List_Q1.docx", "Planned Workforce Reduction Q1 2026\nDepartment: Operations\nHeadcount Impact: 45 positions"),
|
|
],
|
|
"engineering": [
|
|
("!_Product_Roadmap_Confidential.docx", "Product Roadmap 2026-2028\nProject Phoenix: AI-powered analytics\nProject Titan: Next-gen platform"),
|
|
("000_Source_Code_Access_Keys.txt", "Repository Access Tokens\nGitHub Enterprise: ghp_XXXXXXXXXXXX\nAWS CodeCommit: AKIAIOSFODNN7EXAMPLE"),
|
|
("_Patent_Application_Draft.pdf", "US Patent Application\nTitle: Method for Distributed Computing\nInventor: Dr. Jane Smith"),
|
|
],
|
|
"executive": [
|
|
("!_Board_Meeting_Minutes.docx", "Board of Directors Meeting Minutes\nDate: January 15, 2026\nAttendees: Full board present"),
|
|
("000_MA_Target_Analysis.xlsx", "M&A Target Analysis\nTarget: AcmeTech Inc\nValuation: $450M\nSynergies: $80M annual"),
|
|
("_Strategic_Plan_2026.pdf", "Strategic Plan 2026-2030\nVision: Market leader in three verticals\nCapEx Budget: $200M"),
|
|
],
|
|
}
|
|
|
|
|
|
class CanaryDeployer:
|
|
"""Deploys and manages canary files for ransomware detection."""
|
|
|
|
def __init__(self, state_file: str = "canary_state.json"):
|
|
self.state_file = state_file
|
|
self.canaries: list[CanaryFile] = []
|
|
self._load_state()
|
|
|
|
def _load_state(self):
|
|
if os.path.exists(self.state_file):
|
|
with open(self.state_file, "r") as f:
|
|
data = json.load(f)
|
|
self.canaries = [CanaryFile(**c) for c in data.get("canaries", [])]
|
|
|
|
def _save_state(self):
|
|
with open(self.state_file, "w") as f:
|
|
json.dump({"canaries": [asdict(c) for c in self.canaries],
|
|
"last_updated": datetime.now().isoformat()}, f, indent=2)
|
|
|
|
def _compute_hash(self, filepath: str) -> str:
|
|
if not os.path.exists(filepath):
|
|
return ""
|
|
h = hashlib.sha256()
|
|
with open(filepath, "rb") as f:
|
|
for chunk in iter(lambda: f.read(8192), b""):
|
|
h.update(chunk)
|
|
return h.hexdigest()
|
|
|
|
def deploy_canaries(self, base_path: str, share_type: str = "finance") -> list:
|
|
"""Deploy canary files to a target directory."""
|
|
templates = CANARY_TEMPLATES.get(share_type, CANARY_TEMPLATES["finance"])
|
|
deployed = []
|
|
|
|
base = Path(base_path)
|
|
if not base.exists():
|
|
logger.error(f"Target path does not exist: {base_path}")
|
|
return deployed
|
|
|
|
for filename, content in templates:
|
|
filepath = base / filename
|
|
try:
|
|
filepath.write_text(content, encoding="utf-8")
|
|
file_hash = self._compute_hash(str(filepath))
|
|
|
|
canary = CanaryFile(
|
|
path=str(filepath),
|
|
original_hash=file_hash,
|
|
file_type=filepath.suffix,
|
|
deploy_time=datetime.now().isoformat(),
|
|
share_name=share_type,
|
|
)
|
|
self.canaries.append(canary)
|
|
deployed.append(canary)
|
|
logger.info(f"Deployed canary: {filepath}")
|
|
except OSError as e:
|
|
logger.error(f"Failed to deploy canary {filepath}: {e}")
|
|
|
|
self._save_state()
|
|
return deployed
|
|
|
|
def check_canaries(self) -> list:
|
|
"""Check all deployed canaries for modifications."""
|
|
alerts = []
|
|
|
|
for canary in self.canaries:
|
|
if canary.status != "active":
|
|
continue
|
|
|
|
canary.last_check = datetime.now().isoformat()
|
|
|
|
if not os.path.exists(canary.path):
|
|
# File deleted - strong ransomware indicator
|
|
alert = CanaryAlert(
|
|
timestamp=datetime.now().isoformat(),
|
|
canary_path=canary.path,
|
|
change_type="deleted",
|
|
source_info="File no longer exists",
|
|
severity="CRITICAL",
|
|
)
|
|
alerts.append(alert)
|
|
canary.alert_triggered = True
|
|
canary.status = "triggered"
|
|
logger.critical(f"CANARY DELETED: {canary.path}")
|
|
continue
|
|
|
|
current_hash = self._compute_hash(canary.path)
|
|
if current_hash != canary.original_hash:
|
|
# File modified - likely encryption
|
|
alert = CanaryAlert(
|
|
timestamp=datetime.now().isoformat(),
|
|
canary_path=canary.path,
|
|
change_type="modified",
|
|
source_info=f"Hash changed: {canary.original_hash[:16]}... -> {current_hash[:16]}...",
|
|
severity="CRITICAL",
|
|
)
|
|
alerts.append(alert)
|
|
canary.alert_triggered = True
|
|
canary.status = "triggered"
|
|
logger.critical(f"CANARY MODIFIED: {canary.path}")
|
|
|
|
# Check for ransomware extension appended
|
|
parent = Path(canary.path).parent
|
|
base_name = Path(canary.path).name
|
|
for f in parent.iterdir():
|
|
if f.name.startswith(base_name) and f.name != base_name:
|
|
# Possible encrypted version (e.g., file.docx.lockbit)
|
|
alert = CanaryAlert(
|
|
timestamp=datetime.now().isoformat(),
|
|
canary_path=canary.path,
|
|
change_type="extension_changed",
|
|
source_info=f"Possible encrypted copy: {f.name}",
|
|
severity="CRITICAL",
|
|
)
|
|
alerts.append(alert)
|
|
canary.alert_triggered = True
|
|
logger.critical(f"CANARY EXTENSION CHANGE: {f.name}")
|
|
|
|
self._save_state()
|
|
return alerts
|
|
|
|
def generate_report(self) -> str:
|
|
"""Generate deployment status report."""
|
|
lines = []
|
|
lines.append("=" * 60)
|
|
lines.append("RANSOMWARE CANARY DEPLOYMENT REPORT")
|
|
lines.append("=" * 60)
|
|
lines.append(f"Report Time: {datetime.now().isoformat()}")
|
|
lines.append(f"Total Canaries: {len(self.canaries)}")
|
|
|
|
active = sum(1 for c in self.canaries if c.status == "active")
|
|
triggered = sum(1 for c in self.canaries if c.status == "triggered")
|
|
lines.append(f"Active: {active}")
|
|
lines.append(f"Triggered: {triggered}")
|
|
|
|
by_share = {}
|
|
for c in self.canaries:
|
|
by_share.setdefault(c.share_name, []).append(c)
|
|
|
|
lines.append("\nDeployment by Share:")
|
|
for share, canaries in by_share.items():
|
|
lines.append(f"\n {share.upper()}:")
|
|
for c in canaries:
|
|
status_icon = "OK" if c.status == "active" else "ALERT"
|
|
lines.append(f" [{status_icon}] {c.path}")
|
|
|
|
lines.append("\n" + "=" * 60)
|
|
return "\n".join(lines)
|
|
|
|
def continuous_monitor(self, interval_seconds: int = 10):
|
|
"""Run continuous monitoring loop."""
|
|
logger.info(f"Starting continuous canary monitoring (interval: {interval_seconds}s)")
|
|
logger.info(f"Monitoring {len(self.canaries)} canary files")
|
|
|
|
try:
|
|
while True:
|
|
alerts = self.check_canaries()
|
|
if alerts:
|
|
logger.critical(f"!!! {len(alerts)} CANARY ALERTS DETECTED !!!")
|
|
for alert in alerts:
|
|
logger.critical(f" {alert.change_type}: {alert.canary_path}")
|
|
# In production: trigger SIEM alert, NAC quarantine, EDR isolation
|
|
time.sleep(interval_seconds)
|
|
except KeyboardInterrupt:
|
|
logger.info("Monitoring stopped by user")
|
|
|
|
|
|
def main():
|
|
deployer = CanaryDeployer(
|
|
state_file=str(Path(__file__).parent / "canary_state.json")
|
|
)
|
|
|
|
if len(sys.argv) > 1:
|
|
command = sys.argv[1]
|
|
|
|
if command == "deploy" and len(sys.argv) >= 4:
|
|
target_path = sys.argv[2]
|
|
share_type = sys.argv[3]
|
|
deployed = deployer.deploy_canaries(target_path, share_type)
|
|
print(f"Deployed {len(deployed)} canary files to {target_path}")
|
|
|
|
elif command == "check":
|
|
alerts = deployer.check_canaries()
|
|
if alerts:
|
|
print(f"\n!!! {len(alerts)} ALERTS !!!")
|
|
for alert in alerts:
|
|
print(f" [{alert.severity}] {alert.change_type}: {alert.canary_path}")
|
|
else:
|
|
print("All canaries intact - no alerts")
|
|
|
|
elif command == "monitor":
|
|
interval = int(sys.argv[2]) if len(sys.argv) > 2 else 10
|
|
deployer.continuous_monitor(interval)
|
|
|
|
elif command == "report":
|
|
print(deployer.generate_report())
|
|
|
|
else:
|
|
print("Usage:")
|
|
print(" python process.py deploy <path> <type> - Deploy canaries (finance/hr/engineering/executive)")
|
|
print(" python process.py check - Check all canaries for modifications")
|
|
print(" python process.py monitor [interval] - Continuous monitoring")
|
|
print(" python process.py report - Generate deployment report")
|
|
else:
|
|
# Demo mode
|
|
print("Ransomware Honeypot - Demo Mode")
|
|
print("=" * 40)
|
|
demo_dir = Path(__file__).parent / "demo_share"
|
|
demo_dir.mkdir(exist_ok=True)
|
|
|
|
deployed = deployer.deploy_canaries(str(demo_dir), "finance")
|
|
print(f"\nDeployed {len(deployed)} canary files")
|
|
|
|
alerts = deployer.check_canaries()
|
|
print(f"Initial check: {len(alerts)} alerts (expected: 0)")
|
|
|
|
print("\n" + deployer.generate_report())
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|