// Clipboard Injection Detector
// Detects malicious clipboard manipulation via JavaScript APIs
// Intercepts navigator.clipboard API and ClipboardEvent manipulation

import { BaseDetector } from '../base-detector.js';

export class ClipboardInjection extends BaseDetector {
  constructor(config = {}) {
    super(config);
    this.injectionAttempts = [];
  }

  async detect(target, ruleRegistry) {
    const findings = [];
    const rules = ruleRegistry.getRules('data-theft', 'clipboard-injection') || [];

    const { clipboardData, source } = target;

    if (!clipboardData) {
      return { detector: 'clipboard-injection', matched: false, findings: [], riskScore: 0 };
    }

    // Analyze clipboard content against command patterns
    const commandAnalysis = this.analyzeCommandPatterns(clipboardData);
    if (commandAnalysis.matched) {
      findings.push({
        detector: 'clipboard-injection',
        type: 'malicious-command',
        description: `Malicious command detected in clipboard: ${commandAnalysis.commandType}`,
        severity: 'critical',
        weight: 5,
        evidence: {
          commandType: commandAnalysis.commandType,
          techniques: commandAnalysis.techniques,
          obfuscation: commandAnalysis.obfuscation
        },
        mitre: ['T1059.001', 'T1059.003', 'T1566.001'] // Command execution, phishing
      });
    }

    // Check for cryptocurrency address swapping
    const cryptoAnalysis = this.analyzeCryptoSwapping(clipboardData);
    if (cryptoAnalysis.matched) {
      findings.push({
        detector: 'clipboard-injection',
        type: 'crypto-address-swap',
        description: `Cryptocurrency address detected in clipboard: ${cryptoAnalysis.currency}`,
        severity: 'critical',
        weight: 5,
        evidence: cryptoAnalysis,
        mitre: ['T1056.002', 'T1185'] // Input capture, browser session hijacking
      });
    }

    // Check for credential/sensitive data injection
    const sensitiveAnalysis = this.analyzeSensitiveData(clipboardData);
    if (sensitiveAnalysis.matched) {
      findings.push({
        detector: 'clipboard-injection',
        type: 'sensitive-data-injection',
        description: `Sensitive data detected in clipboard: ${sensitiveAnalysis.dataType}`,
        severity: 'high',
        weight: 4,
        evidence: sensitiveAnalysis,
        mitre: ['T1056.002', 'T1555'] // Input capture, credentials from password stores
      });
    }

    // Check for phishing URLs
    const urlAnalysis = this.analyzePhishingUrls(clipboardData);
    if (urlAnalysis.matched) {
      findings.push({
        detector: 'clipboard-injection',
        type: 'phishing-url-injection',
        description: 'Suspicious URL detected in clipboard',
        severity: 'high',
        weight: 3,
        evidence: urlAnalysis,
        mitre: ['T1566.002'] // Phishing: spearphishing link
      });
    }

    return {
      detector: 'clipboard-injection',
      matched: findings.length > 0,
      findings,
      riskScore: this.calculateRiskScore(findings)
    };
  }

  /**
   * Comprehensive command pattern analysis
   */
  analyzeCommandPatterns(text) {
    const commandTypes = [];
    const techniques = new Set();
    let obfuscationScore = 0;

    // PowerShell command patterns
    const powershellPatterns = [
      {
        pattern: /powershell(?:\.exe)?.*?(?:Invoke-WebRequest|iwr|wget|curl)/i,
        type: 'PowerShell Download',
        severity: 'critical',
        technique: 'File Download'
      },
      {
        pattern: /powershell(?:\.exe)?.*?(?:Invoke-Expression|iex)/i,
        type: 'PowerShell Remote Execution',
        severity: 'critical',
        technique: 'Remote Code Execution'
      },
      {
        pattern: /powershell(?:\.exe)?.*?(?:Start-Process|start)/i,
        type: 'PowerShell Process Start',
        severity: 'high',
        technique: 'Process Execution'
      },
      {
        pattern: /powershell(?:\.exe)?.*?(?:-enc(?:odedcommand)?|-e)\s+[A-Za-z0-9+\/=]{20,}/i,
        type: 'PowerShell Encoded Command',
        severity: 'critical',
        technique: 'Obfuscated Command'
      },
      {
        pattern: /powershell(?:\.exe)?.*?(?:-w(?:indowstyle)?\s+hidden|-nop|-ep\s+bypass)/i,
        type: 'PowerShell Hidden/Bypass',
        severity: 'critical',
        technique: 'Defense Evasion'
      },
      {
        pattern: /powershell(?:\.exe)?.*?(?:DownloadString|DownloadFile)/i,
        type: 'PowerShell Download String/File',
        severity: 'critical',
        technique: 'File Download'
      },
      {
        pattern: /powershell(?:\.exe)?.*?(?:Add-MpPreference.*?-ExclusionPath)/i,
        type: 'PowerShell Disable Defender',
        severity: 'critical',
        technique: 'Disable Security Tools'
      }
    ];

    // CMD/Batch command patterns
    const cmdPatterns = [
      {
        pattern: /cmd(?:\.exe)?.*?\/c.*?(?:curl|certutil|bitsadmin).*?http/i,
        type: 'CMD Download via HTTP',
        severity: 'critical',
        technique: 'File Download'
      },
      {
        pattern: /certutil(?:\.exe)?.*?-urlcache.*?http/i,
        type: 'Certutil Download',
        severity: 'critical',
        technique: 'LOLBin Download'
      },
      {
        pattern: /bitsadmin(?:\.exe)?.*?\/transfer/i,
        type: 'BITS Transfer',
        severity: 'critical',
        technique: 'Background Download'
      },
      {
        pattern: /mshta(?:\.exe)?.*?http/i,
        type: 'MSHTA Remote Execution',
        severity: 'critical',
        technique: 'LOLBin Execution'
      },
      {
        pattern: /regsvr32(?:\.exe)?.*?\/[si].*?http/i,
        type: 'Regsvr32 Remote Execution',
        severity: 'critical',
        technique: 'LOLBin Execution'
      },
      {
        pattern: /rundll32(?:\.exe)?.*?http/i,
        type: 'Rundll32 Remote Load',
        severity: 'critical',
        technique: 'LOLBin Execution'
      },
      {
        pattern: /wmic.*?process.*?call.*?create/i,
        type: 'WMIC Process Creation',
        severity: 'high',
        technique: 'Process Execution'
      },
      {
        pattern: /cmd(?:\.exe)?.*?\/c.*?echo.*?(?:>|>>).*?%temp%.*?\.(?:bat|cmd|vbs|js|ps1)/i,
        type: 'CMD Echo Script to Temp',
        severity: 'critical',
        technique: 'Script File Creation'
      },
      {
        pattern: /cmd(?:\.exe)?.*?\/c.*?echo.*?CreateObject/i,
        type: 'CMD Echo VBScript/JScript',
        severity: 'critical',
        technique: 'VBScript Generation'
      },
      {
        pattern: /CreateObject\s*\(\s*["'](?:WinHttp\.WinHttpRequest|MSXML2\.XMLHTTP|MSXML2\.ServerXMLHTTP|Scripting\.FileSystemObject)/i,
        type: 'VBScript/JScript CreateObject',
        severity: 'critical',
        technique: 'COM Object Instantiation'
      },
      {
        pattern: /(?:WinHttpRequest|XMLHTTP).*?\.Open.*?["']GET["'].*?http/i,
        type: 'VBScript HTTP Request',
        severity: 'critical',
        technique: 'Remote Resource Access'
      },
      {
        pattern: /Execute\s+(?:h|response|obj)\.ResponseText/i,
        type: 'VBScript Execute Remote Response',
        severity: 'critical',
        technique: 'Remote Code Execution'
      },
      {
        pattern: /https?:\/\/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/,
        type: 'IP Address URL',
        severity: 'high',
        technique: 'Direct IP Connection'
      },
      {
        pattern: /https?:\/\/[^\/\s]+:\d{4,5}\//,
        type: 'Non-Standard Port URL',
        severity: 'high',
        technique: 'Unusual Port Access'
      }
    ];

    // Bash/Linux command patterns
    const bashPatterns = [
      {
        pattern: /(?:curl|wget).*?(?:http|ftp).*?\|.*?(?:bash|sh|python|perl)/i,
        type: 'Bash Pipe Execution',
        severity: 'critical',
        technique: 'Remote Code Execution'
      },
      {
        pattern: /(?:curl|wget).*?-o.*?\/tmp.*?;.*?chmod.*?\+x/i,
        type: 'Download and Execute',
        severity: 'critical',
        technique: 'File Download + Execution'
      },
      {
        pattern: /base64\s+-d.*?\|.*?(?:bash|sh)/i,
        type: 'Base64 Decode and Execute',
        severity: 'critical',
        technique: 'Obfuscated Execution'
      },
      {
        pattern: /nc\s+-[el].*?\d+.*?-e.*?(?:\/bin\/(?:ba)?sh|cmd\.exe)/i,
        type: 'Netcat Reverse Shell',
        severity: 'critical',
        technique: 'Reverse Shell'
      }
    ];

    // Registry manipulation
    const registryPatterns = [
      {
        pattern: /reg(?:\.exe)?.*?add.*?(?:HKCU|HKLM).*?(?:Run|RunOnce)/i,
        type: 'Registry Run Key Persistence',
        severity: 'critical',
        technique: 'Persistence'
      },
      {
        pattern: /reg(?:\.exe)?.*?delete.*?(?:Windows Defender|Security)/i,
        type: 'Security Software Removal',
        severity: 'critical',
        technique: 'Defense Evasion'
      }
    ];

    // Check all pattern categories
    const allPatterns = [
      ...powershellPatterns,
      ...cmdPatterns,
      ...bashPatterns,
      ...registryPatterns
    ];

    for (const { pattern, type, technique } of allPatterns) {
      if (pattern.test(text)) {
        commandTypes.push(type);
        techniques.add(technique);
      }
    }

    // Detect obfuscation techniques
    const obfuscationIndicators = [
      { pattern: /\^/g, name: 'Caret Escaping' },
      { pattern: /`/g, name: 'Backtick Escaping' },
      { pattern: /\$\{[^}]+\}/g, name: 'Variable Expansion' },
      { pattern: /\[char\]/gi, name: 'Character Code Obfuscation' },
      { pattern: /-join/gi, name: 'String Joining' },
      { pattern: /frombase64string|base64/gi, name: 'Base64 Encoding' },
      { pattern: /\x[0-9a-f]{2}/gi, name: 'Hex Encoding' },
      { pattern: /\\u[0-9a-f]{4}/gi, name: 'Unicode Encoding' }
    ];

    for (const indicator of obfuscationIndicators) {
      const matches = text.match(indicator.pattern);
      if (matches && matches.length > 2) {
        obfuscationScore++;
      }
    }

    // Check for redirection/piping (command chaining)
    const redirectionPatterns = [
      /\|\|/g, // OR chain
      /&&/g,   // AND chain
      /;/g,    // Sequential
      /\|/g,   // Pipe
      />/g,    // Redirect
      /%temp%|%appdata%|%programdata%/gi // Environment variables
    ];

    let redirectionCount = 0;
    for (const pattern of redirectionPatterns) {
      const matches = text.match(pattern);
      if (matches) redirectionCount += matches.length;
    }

    // Detect suspicious file operations
    const fileOperations = [
      /-OutFile/i,
      />\s*[a-z]:\\/i,
      />\s*%temp%/i,
      />\s*\/tmp/i,
      /Start-Process/i,
      /chmod\s+\+x/i
    ];

    let fileOpCount = 0;
    for (const pattern of fileOperations) {
      if (pattern.test(text)) fileOpCount++;
    }

    // Calculate overall suspicion
    const matched = commandTypes.length > 0 ||
                    obfuscationScore >= 2 ||
                    (redirectionCount >= 3 && fileOpCount >= 1);

    return {
      matched,
      commandType: commandTypes.join(', ') || 'Unknown',
      techniques: Array.from(techniques),
      obfuscation: {
        score: obfuscationScore,
        detected: obfuscationScore >= 2
      },
      complexity: {
        redirections: redirectionCount,
        fileOperations: fileOpCount
      }
    };
  }

  /**
   * Analyze cryptocurrency address swapping
   */
  analyzeCryptoSwapping(text) {
    const cryptoPatterns = {
      bitcoin: /\b[13][a-km-zA-HJ-NP-Z1-9]{25,34}\b/g,
      ethereum: /\b0x[a-fA-F0-9]{40}\b/g,
      litecoin: /\b[LM3][a-km-zA-HJ-NP-Z1-9]{26,33}\b/g,
      dogecoin: /\bD{1}[5-9A-HJ-NP-U]{1}[1-9A-HJ-NP-Za-km-z]{32}\b/g,
      monero: /\b4[0-9AB][1-9A-HJ-NP-Za-km-z]{93}\b/g,
      ripple: /\br[a-zA-Z0-9]{24,34}\b/g
    };

    const detected = [];
    for (const [currency, pattern] of Object.entries(cryptoPatterns)) {
      const matches = text.match(pattern);
      if (matches) {
        detected.push({
          currency,
          count: matches.length,
          addresses: matches.slice(0, 3) // Store first 3 for analysis
        });
      }
    }

    return {
      matched: detected.length > 0,
      currency: detected.map(d => d.currency).join(', '),
      detected
    };
  }

  /**
   * Analyze sensitive data patterns
   */
  analyzeSensitiveData(text) {
    const patterns = [
      {
        pattern: /(?:password|passwd|pwd)\s*[:=]\s*\S+/i,
        type: 'Password',
        severity: 'critical'
      },
      {
        pattern: /(?:api[_-]?key|apikey)\s*[:=]\s*[\w-]+/i,
        type: 'API Key',
        severity: 'critical'
      },
      {
        pattern: /(?:token|bearer)\s*[:=]\s*[\w.-]+/i,
        type: 'Auth Token',
        severity: 'critical'
      },
      {
        pattern: /-----BEGIN (?:RSA |DSA )?PRIVATE KEY-----/,
        type: 'Private Key',
        severity: 'critical'
      },
      {
        pattern: /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b/,
        type: 'Email Address',
        severity: 'medium'
      },
      {
        pattern: /\b\d{3}-\d{2}-\d{4}\b/,
        type: 'SSN',
        severity: 'critical'
      },
      {
        pattern: /\b(?:\d{4}[-\s]?){3}\d{4}\b/,
        type: 'Credit Card',
        severity: 'critical'
      }
    ];

    const detected = [];
    for (const { pattern, type, severity } of patterns) {
      if (pattern.test(text)) {
        detected.push({ type, severity });
      }
    }

    return {
      matched: detected.length > 0,
      dataType: detected.map(d => d.type).join(', '),
      detected
    };
  }

  /**
   * Analyze phishing URLs
   */
  analyzePhishingUrls(text) {
    const urlPattern = /https?:\/\/[^\s]+/gi;
    const urls = text.match(urlPattern) || [];

    const suspicious = [];
    for (const url of urls) {
      try {
        const urlObj = new URL(url);

        // Check for IP addresses
        if (/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(urlObj.hostname)) {
          suspicious.push({ url, reason: 'IP Address URL' });
        }

        // Check for suspicious ports
        if (urlObj.port && !['80', '443', '8080'].includes(urlObj.port)) {
          suspicious.push({ url, reason: 'Non-Standard Port' });
        }

        // Check for free TLDs
        if (/\.(tk|ml|ga|cf|gq)$/i.test(urlObj.hostname)) {
          suspicious.push({ url, reason: 'Free TLD' });
        }

        // Check for punycode
        if (urlObj.hostname.startsWith('xn--')) {
          suspicious.push({ url, reason: 'Punycode Domain' });
        }
      } catch (e) {
        // Invalid URL
      }
    }

    return {
      matched: suspicious.length > 0,
      count: urls.length,
      suspicious
    };
  }
}
