npx skills add mukul975/Anthropic-Cybersecurity-SkillsMITRE ATT&CK
Overview
XM Cyber is a continuous exposure management platform that uses attack graph analysis to identify how adversaries can chain together exposures -- vulnerabilities, misconfigurations, identity risks, and credential weaknesses -- to reach critical business assets. According to XM Cyber's 2024 research analyzing over 40 million exposures across 11.5 million entities, organizations typically have around 15,000 exploitable exposures, but traditional CVEs account for less than 1% of total exposures. The platform identifies that only 2% of exposures reside on "choke points" of converging attack paths, enabling security teams to focus on fixes that eliminate the most risk with the least effort.
When to Use
- When deploying or configuring implementing attack path analysis with xm cyber capabilities in your environment
- When establishing security controls aligned to compliance requirements
- When building or improving security architecture for this domain
- When conducting security assessments that require this implementation
Prerequisites
- XM Cyber platform license and tenant access
- Network connectivity to monitored environments (on-premises, cloud, hybrid)
- Administrative access for agent deployment or agentless integration
- Cloud provider API access (AWS, Azure, GCP) for cloud attack path analysis
- Active Directory read access for identity-based attack path modeling
- CMDB or asset inventory defining critical business assets
Core Concepts
Attack Graph Analysis
Unlike point-in-time vulnerability scanning, XM Cyber continuously models all possible attack paths across the entire environment:
| Traditional Scanning | XM Cyber Attack Path Analysis |
|---|---|
| Lists individual vulnerabilities | Maps chained attack paths |
| Scores by CVSS severity | Scores by reachability to critical assets |
| Point-in-time assessment | Continuous real-time modeling |
| No context of lateral movement | Models full lateral movement chains |
| Treats each vuln independently | Shows how vulns chain together |
Key Metrics from XM Cyber Research (2024)
| Finding | Statistic |
|---|---|
| Average exposures per organization | ~15,000 |
| CVE-based exposures | < 1% of total |
| Misconfiguration-based exposures | ~80% of total |
| Exposures on critical choke points | 2% |
| Orgs where attackers can pivot on-prem to cloud | 70% |
| Cloud critical assets compromisable in 2 hops | 93% |
| Critical asset exposures in cloud platforms | 56% |
Choke Point Concept
A choke point is a single entity (host, identity, credential, misconfiguration) that sits at the intersection of multiple attack paths leading to critical assets. Fixing a choke point eliminates many attack paths simultaneously, providing maximum risk reduction per remediation effort.
Attack Path 1: Web Server -> SQL Injection -> DB Admin Creds
\
Attack Path 2: VPN -> Stolen Creds -> File Server -> Domain Controller
/ (Critical Asset)
Attack Path 3: Workstation -> Mimikatz -> Cached Creds
^
CHOKE POINT
(Cached Domain Admin credential)Exposure Categories
| Category | % of Exposures | Examples |
|---|---|---|
| Identity & Credentials | 40% | Cached credentials, over-privileged accounts, Kerberoastable SPNs |
| Misconfigurations | 38% | Open shares, weak permissions, missing hardening |
| Network Exposures | 12% | Open ports, flat networks, missing segmentation |
| Software Vulnerabilities | 8% | Unpatched CVEs, outdated software |
| Cloud Exposures | 2% | IAM misconfig, public storage, overly permissive roles |
Workflow
Step 1: Define Critical Assets (Business Context)
Critical Asset Definition:
Tier 1 - Crown Jewels:
- Domain Controllers (Active Directory)
- Database servers with PII/financial data
- ERP systems (SAP, Oracle)
- Certificate Authority servers
- Backup infrastructure (Veeam, Commvault)
Tier 2 - High Value:
- Email servers (Exchange)
- File servers with IP/trade secrets
- CI/CD pipeline servers
- Jump servers / PAM vaults
Tier 3 - Supporting Infrastructure:
- DNS/DHCP servers
- Monitoring systems
- Logging infrastructureStep 2: Deploy XM Cyber Sensors
Deployment Architecture:
On-Premises:
- Install XM Cyber sensor on management server
- Configure AD integration (read-only service account)
- Enable network discovery protocols
- Set scanning scope (IP ranges, AD OUs)
Cloud (AWS):
- Deploy XM Cyber CloudConnect via CloudFormation
- Configure IAM role with read-only permissions
- Enable cross-account scanning for multi-account orgs
Cloud (Azure):
- Deploy via Azure Marketplace
- Configure Entra ID (Azure AD) integration
- Grant Reader role on subscriptions
Hybrid:
- Configure cross-environment path analysis
- Map on-premises to cloud trust relationships
- Enable identity correlation across environmentsStep 3: Configure Attack Scenarios
Scenario 1: External Attacker to Domain Admin
Starting Point: Internet-facing assets
Target: Domain Admin privileges
Attack Techniques: Exploit public CVEs, credential theft,
lateral movement, privilege escalation
Scenario 2: Insider Threat to Financial Data
Starting Point: Any corporate workstation
Target: Financial database servers
Attack Techniques: Credential harvesting, share enumeration,
privilege escalation, data access
Scenario 3: Cloud Account Takeover
Starting Point: Compromised cloud IAM user
Target: Production cloud infrastructure
Attack Techniques: IAM privilege escalation, cross-account
pivot, storage access, compute compromise
Scenario 4: Ransomware Propagation
Starting Point: Phished workstation
Target: Maximum host compromise (lateral spread)
Attack Techniques: Credential reuse, SMB exploitation,
PsExec/WMI lateral movementStep 4: Analyze Attack Path Results
# Interpreting XM Cyber attack path analysis results
def analyze_choke_points(attack_graph_results):
"""Analyze attack graph results for priority remediation."""
choke_points = []
for entity in attack_graph_results.get("entities", []):
if entity.get("is_choke_point"):
choke_points.append({
"entity_name": entity["name"],
"entity_type": entity["type"],
"attack_paths_blocked": entity["paths_through"],
"critical_assets_protected": entity["protects_assets"],
"remediation_complexity": entity["fix_complexity"],
"exposure_type": entity["exposure_category"],
})
# Sort by impact (paths blocked * assets protected)
choke_points.sort(
key=lambda x: x["attack_paths_blocked"] * len(x["critical_assets_protected"]),
reverse=True
)
print(f"Total choke points identified: {len(choke_points)}")
print(f"\nTop 10 choke points for maximum risk reduction:")
for i, cp in enumerate(choke_points[:10], 1):
print(f" {i}. {cp['entity_name']} ({cp['entity_type']})")
print(f" Paths blocked: {cp['attack_paths_blocked']}")
print(f" Assets protected: {len(cp['critical_assets_protected'])}")
print(f" Exposure type: {cp['exposure_type']}")
print(f" Fix complexity: {cp['remediation_complexity']}")
return choke_pointsStep 5: Prioritize Remediation by Impact
Remediation Priority Matrix:
Priority 1 (Immediate - 48h):
- Choke points on paths to Tier 1 assets
- Identity exposures (cached Domain Admin creds)
- Internet-facing vulnerabilities with attack paths
Priority 2 (Urgent - 7 days):
- Choke points on paths to Tier 2 assets
- Cloud IAM misconfigurations with privilege escalation
- Network segmentation gaps enabling lateral movement
Priority 3 (Important - 30 days):
- Remaining choke points
- Misconfigurations reducing defense depth
- Non-critical software vulnerabilities on attack paths
Priority 4 (Standard - 90 days):
- Exposures NOT on any attack path to critical assets
- Informational findings
- Hardening recommendationsBest Practices
- Define critical assets before deploying the platform; attack paths without target context are meaningless
- Focus remediation on choke points first; fixing 2% of exposures can eliminate the majority of risk
- Use attack path context to justify remediation urgency to IT teams (show the chain, not just the vuln)
- Re-run attack path analysis after each remediation to verify paths are truly eliminated
- Include cloud environments in analysis; 56% of critical asset exposures exist in cloud platforms
- Monitor for new attack paths created by infrastructure changes (new servers, permission changes)
- Integrate findings with ticketing systems for automated remediation tracking
Common Pitfalls
- Focusing solely on CVEs when 80% of exposures come from misconfigurations
- Not defining critical assets, leading to unfocused attack path analysis
- Treating all exposures equally instead of focusing on choke points
- Ignoring identity-based attack paths (cached credentials, Kerberoastable accounts)
- Not correlating on-premises and cloud attack paths in hybrid environments
- Running analysis once instead of continuously
References and resources
Everything below is rendered for inspection. Script files are read-only and never run.
References 3
api-reference.md1.7 KB
API Reference: XM Cyber Attack Path Analysis Agent
Dependencies
| Library | Version | Purpose |
|---|---|---|
| requests | >=2.28 | HTTP client for XM Cyber REST API |
CLI Usage
python scripts/agent.py \
--url https://xmcyber.example.com \
--api-key YOUR_API_KEY \
--output-dir /reports/ \
--output attack_path_report.jsonFunctions
XMCyberClient(base_url, api_key)
Client class with Bearer token auth for the XM Cyber API.
get_scenarios() -> list
GET /api/v1/scenarios - Lists all attack simulation scenarios.
get_attack_paths(scenario_id) -> list
GET /api/v1/scenarios/{id}/attack-paths - Returns attack paths for a scenario.
get_choke_points(scenario_id) -> list
GET /api/v1/scenarios/{id}/choke-points - Returns points where attack paths converge.
get_critical_assets() -> list
GET /api/v1/critical-assets - Lists defined critical business assets.
get_entities_at_risk(scenario_id) -> list
GET /api/v1/scenarios/{id}/entities-at-risk - Entities reachable via attack paths.
get_remediation_actions(scenario_id) -> list
GET /api/v1/scenarios/{id}/remediations - Prioritized fix recommendations.
analyze_choke_points(choke_points) -> dict
Ranks choke points by paths_through count, returns top 10.
compute_risk_score(attack_paths, critical_assets) -> dict
Calculates critical asset exposure percentage from reachable targets.
Output Schema
{
"scenarios": [{
"name": "Full Environment",
"attack_paths": 1234,
"choke_point_analysis": {"total_choke_points": 45, "top_choke_points": []},
"risk_score": {"critical_asset_exposure_pct": 67.5}
}]
}standards.md1.3 KB
Standards and References - XM Cyber Attack Path Analysis
XM Cyber Resources
- XM Cyber Platform: https://xmcyber.com/
- 2024 State of Exposure Management Report: https://info.xmcyber.com/2024-state-of-exposure-management
- CTEM (Continuous Threat Exposure Management): https://xmcyber.com/ctem/
- XM Cyber EASM Integration: https://xmcyber.com/press-release/xm-cyber-unifies-external-discovery-with-internal-validation/
Industry Frameworks
- Gartner CTEM: Continuous Threat Exposure Management framework (2022)
- MITRE ATT&CK: Lateral movement and privilege escalation techniques
- NIST CSF 2.0: Identify, Protect, Detect functions
- CIS Controls v8.1 Control 7: Continuous Vulnerability Management
Research Findings (2024)
| Metric | Finding |
|---|---|
| Avg exposures per org | ~15,000 |
| CVE-based exposures | < 1% of total |
| Misconfiguration exposures | ~80% |
| Identity/credential exposures | ~40% |
| Critical choke points | 2% of all exposures |
| On-prem to cloud pivot | 70% of organizations |
| Cloud assets compromised in 2 hops | 93% |
Related Technologies
- BloodHound/SharpHound: Active Directory attack path analysis
- PurpleKnight: AD security assessment
- CrowdStrike Falcon Exposure Management
- Tenable Identity Exposure
- Microsoft Defender for Identity
workflows.md2.9 KB
Workflows - XM Cyber Attack Path Analysis
Workflow 1: Continuous Exposure Management Lifecycle
┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐
│ Define Critical │────>│ Deploy Sensors │────>│ Run Attack Graph │
│ Assets (Crown │ │ (On-prem + Cloud)│ │ Analysis │
│ Jewels) │ │ │ │ │
└──────────────────┘ └──────────────────┘ └──────────────────┘
│
┌────────────────────────────────────────────────┘
v
┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐
│ Identify Choke │────>│ Prioritize │────>│ Remediate & │
│ Points │ │ Remediation │ │ Validate │
└──────────────────┘ └──────────────────┘ └──────────────────┘
│
v
┌──────────────────┐
│ Continuous │ (Loop back to Attack Graph Analysis)
│ Monitoring │
└──────────────────┘Workflow 2: Choke Point Remediation
For each identified choke point:
1. Document the entity (host, credential, misconfiguration)
2. Map all attack paths passing through this choke point
3. List all critical assets protected if choke point is fixed
4. Determine remediation action (patch, reconfig, credential rotation)
5. Estimate fix complexity (easy/moderate/complex)
6. Calculate risk reduction score (paths * assets / complexity)
7. Assign to remediation team with priority and SLA
8. After fix: re-run analysis to confirm path elimination
9. Document residual risk if paths still existWorkflow 3: Attack Path to Remediation Ticket
XM Cyber Finding:
"Cached Domain Admin credential on WORKSTATION-042
enables 47 attack paths to Domain Controller DC-01"
│
v
Remediation Ticket:
Priority: P1-Emergency
Title: "Remove cached DA cred on WORKSTATION-042"
Action: Clear credential cache, implement LAPS,
restrict DA logon to Tier 0 only
Impact: Eliminates 47 attack paths to DC-01
SLA: 48 hoursScripts 2
agent.py5.6 KB
#!/usr/bin/env python3
"""Attack path analysis agent using XM Cyber REST API for exposure management."""
import argparse
import json
import logging
import os
import sys
from datetime import datetime
from typing import List
try:
import requests
except ImportError:
sys.exit("requests required: pip install requests")
logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s")
logger = logging.getLogger(__name__)
class XMCyberClient:
"""Client for XM Cyber Continuous Exposure Management API."""
def __init__(self, base_url: str, api_key: str):
self.base_url = base_url.rstrip("/")
self.session = requests.Session()
self.session.headers.update({
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json",
})
def get_scenarios(self) -> List[dict]:
"""List all attack scenarios."""
resp = self.session.get(f"{self.base_url}/api/v1/scenarios", timeout=30)
resp.raise_for_status()
return resp.json().get("data", [])
def get_attack_paths(self, scenario_id: str) -> List[dict]:
"""Get attack paths for a specific scenario."""
resp = self.session.get(
f"{self.base_url}/api/v1/scenarios/{scenario_id}/attack-paths", timeout=30)
resp.raise_for_status()
return resp.json().get("data", [])
def get_choke_points(self, scenario_id: str) -> List[dict]:
"""Get choke points where multiple attack paths converge."""
resp = self.session.get(
f"{self.base_url}/api/v1/scenarios/{scenario_id}/choke-points", timeout=30)
resp.raise_for_status()
return resp.json().get("data", [])
def get_critical_assets(self) -> List[dict]:
"""List critical assets defined in the platform."""
resp = self.session.get(f"{self.base_url}/api/v1/critical-assets", timeout=30)
resp.raise_for_status()
return resp.json().get("data", [])
def get_entities_at_risk(self, scenario_id: str) -> List[dict]:
"""Get entities at risk of compromise in a scenario."""
resp = self.session.get(
f"{self.base_url}/api/v1/scenarios/{scenario_id}/entities-at-risk", timeout=30)
resp.raise_for_status()
return resp.json().get("data", [])
def get_remediation_actions(self, scenario_id: str) -> List[dict]:
"""Get recommended remediation actions prioritized by impact."""
resp = self.session.get(
f"{self.base_url}/api/v1/scenarios/{scenario_id}/remediations", timeout=30)
resp.raise_for_status()
return resp.json().get("data", [])
def analyze_choke_points(choke_points: List[dict]) -> dict:
"""Analyze choke points to identify highest-impact remediation targets."""
sorted_cp = sorted(choke_points, key=lambda c: c.get("paths_through", 0), reverse=True)
return {
"total_choke_points": len(choke_points),
"top_choke_points": [
{"entity": cp.get("entity_name", ""), "type": cp.get("entity_type", ""),
"paths_through": cp.get("paths_through", 0),
"techniques": cp.get("techniques", [])}
for cp in sorted_cp[:10]
],
}
def compute_risk_score(attack_paths: List[dict], critical_assets: List[dict]) -> dict:
"""Compute risk score based on attack path complexity and critical asset exposure."""
reachable = set()
for path in attack_paths:
target = path.get("target_asset", "")
if target:
reachable.add(target)
critical_names = {a.get("name", "") for a in critical_assets}
compromised = reachable & critical_names
pct = (len(compromised) / len(critical_names) * 100) if critical_names else 0
return {
"total_paths": len(attack_paths),
"unique_targets": len(reachable),
"critical_assets_reachable": len(compromised),
"critical_asset_exposure_pct": round(pct, 1),
}
def generate_report(client: XMCyberClient) -> dict:
"""Generate comprehensive attack path analysis report."""
report = {"analysis_date": datetime.utcnow().isoformat(), "scenarios": []}
scenarios = client.get_scenarios()
critical_assets = client.get_critical_assets()
report["critical_assets_count"] = len(critical_assets)
for scenario in scenarios[:5]:
sid = scenario.get("id", "")
paths = client.get_attack_paths(sid)
choke = client.get_choke_points(sid)
remediations = client.get_remediation_actions(sid)
report["scenarios"].append({
"id": sid, "name": scenario.get("name", ""),
"attack_paths": len(paths),
"choke_point_analysis": analyze_choke_points(choke),
"risk_score": compute_risk_score(paths, critical_assets),
"top_remediations": remediations[:5],
})
return report
def main():
parser = argparse.ArgumentParser(description="XM Cyber Attack Path Analysis Agent")
parser.add_argument("--url", required=True, help="XM Cyber platform URL")
parser.add_argument("--api-key", required=True, help="API key")
parser.add_argument("--output-dir", default=".", help="Output directory")
parser.add_argument("--output", default="attack_path_report.json")
args = parser.parse_args()
os.makedirs(args.output_dir, exist_ok=True)
client = XMCyberClient(args.url, args.api_key)
report = generate_report(client)
out_path = os.path.join(args.output_dir, args.output)
with open(out_path, "w") as f:
json.dump(report, f, indent=2)
logger.info("Report saved to %s", out_path)
print(json.dumps(report, indent=2))
if __name__ == "__main__":
main()
process.py8.6 KB
#!/usr/bin/env python3
"""
Attack Path Analysis and Choke Point Prioritization Tool
Processes attack path data from exposure management platforms
to identify and prioritize choke points for remediation.
Requirements:
pip install pandas networkx matplotlib
Usage:
python process.py analyze --input attack_paths.json --output choke_points.csv
python process.py visualize --input attack_paths.json --output graph.png
python process.py report --input attack_paths.json
"""
import argparse
import json
import sys
from collections import defaultdict
import networkx as nx
import pandas as pd
class AttackPathAnalyzer:
"""Analyze attack paths and identify choke points."""
def __init__(self):
self.graph = nx.DiGraph()
self.critical_assets = set()
self.choke_points = []
def load_attack_paths(self, data):
"""Load attack path data into a directed graph."""
for path in data.get("attack_paths", []):
nodes = path.get("nodes", [])
for i in range(len(nodes) - 1):
src = nodes[i]
dst = nodes[i + 1]
self.graph.add_node(src["id"], **src)
self.graph.add_node(dst["id"], **dst)
self.graph.add_edge(
src["id"], dst["id"],
technique=path.get("technique", "unknown"),
path_id=path.get("path_id", "")
)
for asset in data.get("critical_assets", []):
self.critical_assets.add(asset["id"])
if asset["id"] in self.graph:
self.graph.nodes[asset["id"]]["is_critical"] = True
self.graph.nodes[asset["id"]]["tier"] = asset.get("tier", 3)
print(f"[+] Loaded {self.graph.number_of_nodes()} nodes, "
f"{self.graph.number_of_edges()} edges")
print(f" Critical assets: {len(self.critical_assets)}")
def find_choke_points(self):
"""Identify choke points using betweenness centrality
weighted by paths to critical assets."""
betweenness = nx.betweenness_centrality(self.graph)
node_path_counts = defaultdict(lambda: {"paths": 0, "assets": set()})
for critical_asset in self.critical_assets:
if critical_asset not in self.graph:
continue
for source in self.graph.nodes():
if source == critical_asset:
continue
if source in self.critical_assets:
continue
try:
for path in nx.all_simple_paths(
self.graph, source, critical_asset, cutoff=8
):
for node in path[1:-1]:
node_path_counts[node]["paths"] += 1
node_path_counts[node]["assets"].add(critical_asset)
except nx.NetworkXNoPath:
continue
self.choke_points = []
for node_id, counts in node_path_counts.items():
if counts["paths"] < 2:
continue
node_data = self.graph.nodes.get(node_id, {})
self.choke_points.append({
"entity_id": node_id,
"entity_name": node_data.get("name", node_id),
"entity_type": node_data.get("type", "unknown"),
"exposure_category": node_data.get("exposure_category", "unknown"),
"paths_through": counts["paths"],
"critical_assets_at_risk": len(counts["assets"]),
"assets_list": list(counts["assets"]),
"betweenness_centrality": round(betweenness.get(node_id, 0), 4),
"risk_score": round(
counts["paths"] * len(counts["assets"]) *
(1 + betweenness.get(node_id, 0)),
2
),
"remediation": node_data.get("remediation", "Review and fix"),
"fix_complexity": node_data.get("fix_complexity", "medium"),
})
self.choke_points.sort(key=lambda x: x["risk_score"], reverse=True)
print(f"[+] Identified {len(self.choke_points)} choke points")
return self.choke_points
def generate_remediation_plan(self):
"""Generate prioritized remediation plan from choke points."""
if not self.choke_points:
self.find_choke_points()
plan = []
for i, cp in enumerate(self.choke_points, 1):
if cp["risk_score"] >= 100 or cp["critical_assets_at_risk"] >= 3:
priority = "P1-Emergency"
sla = "48 hours"
elif cp["risk_score"] >= 50 or cp["critical_assets_at_risk"] >= 2:
priority = "P2-Critical"
sla = "7 days"
elif cp["risk_score"] >= 20:
priority = "P3-High"
sla = "14 days"
else:
priority = "P4-Medium"
sla = "30 days"
plan.append({
"rank": i,
"entity": cp["entity_name"],
"type": cp["entity_type"],
"category": cp["exposure_category"],
"paths_eliminated": cp["paths_through"],
"assets_protected": cp["critical_assets_at_risk"],
"risk_score": cp["risk_score"],
"priority": priority,
"sla": sla,
"complexity": cp["fix_complexity"],
"remediation": cp["remediation"],
})
return pd.DataFrame(plan)
def print_summary(self):
"""Print analysis summary."""
if not self.choke_points:
self.find_choke_points()
total_nodes = self.graph.number_of_nodes()
total_edges = self.graph.number_of_edges()
total_choke = len(self.choke_points)
print(f"\n{'=' * 70}")
print("ATTACK PATH ANALYSIS SUMMARY")
print(f"{'=' * 70}")
print(f"Total entities: {total_nodes}")
print(f"Total attack edges: {total_edges}")
print(f"Critical assets: {len(self.critical_assets)}")
print(f"Choke points found: {total_choke}")
print(f"Choke point ratio: {total_choke / max(total_nodes, 1) * 100:.1f}%")
if self.choke_points:
print(f"\nTop 10 Choke Points:")
for i, cp in enumerate(self.choke_points[:10], 1):
print(f" {i}. {cp['entity_name']}")
print(f" Type: {cp['entity_type']} | "
f"Category: {cp['exposure_category']}")
print(f" Paths: {cp['paths_through']} | "
f"Assets at risk: {cp['critical_assets_at_risk']} | "
f"Risk: {cp['risk_score']}")
categories = defaultdict(int)
for cp in self.choke_points:
categories[cp["exposure_category"]] += 1
print(f"\nChoke Points by Category:")
for cat, count in sorted(categories.items(),
key=lambda x: x[1], reverse=True):
print(f" {cat}: {count}")
def main():
parser = argparse.ArgumentParser(
description="Attack Path Analysis and Choke Point Prioritization"
)
subparsers = parser.add_subparsers(dest="command")
analyze_p = subparsers.add_parser("analyze", help="Analyze attack paths")
analyze_p.add_argument("--input", required=True, help="Attack paths JSON file")
analyze_p.add_argument("--output", default="choke_points.csv")
report_p = subparsers.add_parser("report", help="Generate summary report")
report_p.add_argument("--input", required=True, help="Attack paths JSON file")
plan_p = subparsers.add_parser("plan", help="Generate remediation plan")
plan_p.add_argument("--input", required=True, help="Attack paths JSON file")
plan_p.add_argument("--output", default="remediation_plan.csv")
args = parser.parse_args()
analyzer = AttackPathAnalyzer()
if not args.command:
parser.print_help()
sys.exit(1)
with open(args.input) as f:
data = json.load(f)
analyzer.load_attack_paths(data)
if args.command == "analyze":
choke_points = analyzer.find_choke_points()
df = pd.DataFrame(choke_points)
df.to_csv(args.output, index=False)
print(f"[+] Choke points saved to {args.output}")
analyzer.print_summary()
elif args.command == "report":
analyzer.print_summary()
elif args.command == "plan":
plan_df = analyzer.generate_remediation_plan()
plan_df.to_csv(args.output, index=False)
print(plan_df.to_string(index=False))
print(f"\n[+] Remediation plan saved to {args.output}")
if __name__ == "__main__":
main()