#!/usr/bin/env python3
"""Agent for performing initial access simulation with Evilginx3 phishlet analysis — educational/authorized pentest use."""

import json
import argparse
import subprocess
import re
from pathlib import Path


def parse_phishlet(phishlet_path):
    """Parse an Evilginx3 YAML phishlet file and extract configuration."""
    try:
        import yaml
    except ImportError:
        return {"error": "pyyaml not installed — pip install pyyaml"}
    content = Path(phishlet_path).read_text(encoding="utf-8")
    config = yaml.safe_load(content)
    proxy_hosts = config.get("proxy_hosts", [])
    sub_filters = config.get("sub_filters", [])
    auth_tokens = config.get("auth_tokens", [])
    cred_fields = config.get("credentials", {})
    return {
        "phishlet": phishlet_path,
        "name": config.get("name", ""),
        "author": config.get("author", ""),
        "target_domain": proxy_hosts[0].get("domain", "") if proxy_hosts else "",
        "proxy_hosts": [{"phish_sub": h.get("phish_sub"), "orig_sub": h.get("orig_sub"), "domain": h.get("domain")} for h in proxy_hosts],
        "auth_tokens": [{"domain": t.get("domain"), "keys": t.get("keys", [])} for t in auth_tokens],
        "credential_fields": cred_fields,
        "sub_filters_count": len(sub_filters),
        "analysis": {
            "captures_session_tokens": len(auth_tokens) > 0,
            "captures_credentials": bool(cred_fields),
            "mfa_bypass_capable": len(auth_tokens) > 0,
        },
    }


def analyze_session_log(log_file):
    """Analyze Evilginx session capture logs."""
    content = Path(log_file).read_text(encoding="utf-8", errors="replace")
    sessions = []
    current = {}
    for line in content.splitlines():
        if "new session" in line.lower() or "session started" in line.lower():
            if current:
                sessions.append(current)
            current = {"start": line.strip(), "tokens": [], "credentials": []}
        elif "token" in line.lower() or "cookie" in line.lower():
            current.setdefault("tokens", []).append(line.strip()[:200])
        elif "username" in line.lower() or "password" in line.lower() or "credential" in line.lower():
            current.setdefault("credentials", []).append(line.strip()[:200])
        elif "landing_url" in line.lower() or "remote_addr" in line.lower():
            ip_match = re.search(r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}", line)
            if ip_match:
                current["source_ip"] = ip_match.group()
    if current:
        sessions.append(current)
    return {
        "log_file": log_file,
        "total_sessions": len(sessions),
        "sessions_with_tokens": sum(1 for s in sessions if s.get("tokens")),
        "sessions_with_creds": sum(1 for s in sessions if s.get("credentials")),
        "sessions": sessions[:20],
    }


def check_evilginx_installation():
    """Check if Evilginx3 is installed and get version."""
    try:
        result = subprocess.run(["evilginx", "--version"], capture_output=True, text=True, timeout=10)
        version = result.stdout.strip() or result.stderr.strip()
        return {"installed": True, "version": version}
    except FileNotFoundError:
        return {"installed": False, "error": "evilginx not found in PATH"}
    except Exception as e:
        return {"installed": False, "error": str(e)}


def list_phishlets(phishlet_dir):
    """List available phishlets in a directory."""
    p = Path(phishlet_dir)
    if not p.is_dir():
        return {"error": f"Directory not found: {phishlet_dir}"}
    phishlets = []
    for f in sorted(p.glob("*.yaml")) + sorted(p.glob("*.yml")):
        phishlets.append({"name": f.stem, "path": str(f), "size": f.stat().st_size})
    return {"directory": phishlet_dir, "count": len(phishlets), "phishlets": phishlets}


def generate_detection_rules(phishlet_path):
    """Generate detection signatures for a phishlet's attack patterns."""
    try:
        import yaml
    except ImportError:
        return {"error": "pyyaml not installed"}
    config = yaml.safe_load(Path(phishlet_path).read_text())
    proxy_hosts = config.get("proxy_hosts", [])
    rules = []
    for host in proxy_hosts:
        domain = host.get("domain", "")
        phish_sub = host.get("phish_sub", "")
        rules.append({
            "type": "dns_monitor",
            "description": f"Monitor for DNS queries to subdomains impersonating {domain}",
            "pattern": f"*.{domain}",
            "indicator": f"Phishing subdomain: {phish_sub}.{domain}",
        })
    auth_tokens = config.get("auth_tokens", [])
    for token in auth_tokens:
        for key in token.get("keys", []):
            rules.append({
                "type": "cookie_monitor",
                "description": f"Monitor for session token relay of {key}",
                "cookie_name": key,
                "domain": token.get("domain", ""),
            })
    rules.append({
        "type": "network_signature",
        "description": "Detect reverse proxy header anomalies",
        "indicators": ["X-Forwarded-For mismatch", "Origin header discrepancy", "TLS certificate mismatch"],
    })
    return {
        "phishlet": phishlet_path,
        "detection_rules": rules,
        "total_rules": len(rules),
        "recommendations": [
            "Enable FIDO2/WebAuthn MFA to prevent session token theft",
            "Monitor for certificate transparency log entries with suspicious subdomains",
            "Deploy conditional access policies requiring compliant devices",
        ],
    }


def main():
    parser = argparse.ArgumentParser(description="Evilginx3 Phishlet Analysis Agent (Authorized Testing Only)")
    sub = parser.add_subparsers(dest="command")
    p = sub.add_parser("parse", help="Parse phishlet YAML")
    p.add_argument("--phishlet", required=True)
    l = sub.add_parser("logs", help="Analyze session logs")
    l.add_argument("--file", required=True)
    sub.add_parser("check", help="Check Evilginx installation")
    ls = sub.add_parser("list", help="List available phishlets")
    ls.add_argument("--dir", required=True)
    d = sub.add_parser("detect", help="Generate detection rules")
    d.add_argument("--phishlet", required=True)
    args = parser.parse_args()
    if args.command == "parse":
        result = parse_phishlet(args.phishlet)
    elif args.command == "logs":
        result = analyze_session_log(args.file)
    elif args.command == "check":
        result = check_evilginx_installation()
    elif args.command == "list":
        result = list_phishlets(args.dir)
    elif args.command == "detect":
        result = generate_detection_rules(args.phishlet)
    else:
        parser.print_help()
        return
    print(json.dumps(result, indent=2, default=str))


if __name__ == "__main__":
    main()
