Spaces:
Sleeping
Sleeping
| """ | |
| ShadowWatch - Dark Web Intelligence Platform | |
| MCP-enabled Gradio Space for threat intelligence and monitoring | |
| By Cogensec | ARGUS Platform | |
| """ | |
| import gradio as gr | |
| import json | |
| import hashlib | |
| import random | |
| import time | |
| from datetime import datetime, timedelta | |
| from typing import Optional | |
| # ============================================================================ | |
| # MCP TOOLS - These become callable tools for LLM clients | |
| # ============================================================================ | |
| def deep_scan(target: str, scan_type: str = "comprehensive") -> dict: | |
| """Perform a deep scan of dark web sources for threat intelligence. | |
| Crawls marketplaces, forums, paste sites, and channels for mentions | |
| of the specified target (domain, company, email pattern, etc.) | |
| Args: | |
| target: The target to scan for (domain, company name, email pattern, IP range) | |
| scan_type: Type of scan - "quick" (5 sources), "standard" (25 sources), or "comprehensive" (50+ sources) | |
| Returns: | |
| JSON object with scan_id, sources_crawled, findings summary, | |
| threat_indicators, and recommended_actions | |
| """ | |
| scan_id = hashlib.sha256(f"{target}{datetime.now().isoformat()}".encode()).hexdigest()[:12] | |
| sources = { | |
| "quick": {"marketplaces": 2, "forums": 2, "paste_sites": 1, "channels": 0}, | |
| "standard": {"marketplaces": 8, "forums": 10, "paste_sites": 5, "channels": 2}, | |
| "comprehensive": {"marketplaces": 15, "forums": 20, "paste_sites": 10, "channels": 8} | |
| } | |
| source_counts = sources.get(scan_type, sources["standard"]) | |
| total_sources = sum(source_counts.values()) | |
| # Simulated findings based on target | |
| findings = [] | |
| threat_level = "low" | |
| if "@" in target or "." in target: | |
| # Email or domain - check for credential exposure | |
| leak_count = random.randint(0, 500) | |
| if leak_count > 0: | |
| findings.append({ | |
| "type": "credential_exposure", | |
| "source": "dark_market_db", | |
| "count": leak_count, | |
| "severity": "high" if leak_count > 100 else "medium", | |
| "details": f"Found {leak_count} credential records matching pattern" | |
| }) | |
| threat_level = "high" if leak_count > 100 else "elevated" | |
| mention_count = random.randint(0, 50) | |
| if mention_count > 10: | |
| findings.append({ | |
| "type": "chatter_mention", | |
| "source": "forum_analysis", | |
| "count": mention_count, | |
| "severity": "medium", | |
| "details": f"Target mentioned in {mention_count} forum threads" | |
| }) | |
| if threat_level == "low": | |
| threat_level = "moderate" | |
| paste_hits = random.randint(0, 20) | |
| if paste_hits > 0: | |
| findings.append({ | |
| "type": "paste_site_exposure", | |
| "source": "paste_monitoring", | |
| "count": paste_hits, | |
| "severity": "high" if paste_hits > 5 else "low", | |
| "details": f"Found {paste_hits} paste entries containing target data" | |
| }) | |
| return { | |
| "scan_id": scan_id, | |
| "target": target, | |
| "scan_type": scan_type, | |
| "timestamp": datetime.now().isoformat(), | |
| "sources_crawled": { | |
| "total": total_sources, | |
| "breakdown": source_counts | |
| }, | |
| "threat_level": threat_level, | |
| "findings_count": len(findings), | |
| "findings": findings, | |
| "recommended_actions": [ | |
| "Review exposed credentials and force password resets", | |
| "Enable monitoring alerts for this target", | |
| "Consider takedown requests for sensitive exposures" | |
| ] if findings else ["No immediate action required", "Continue routine monitoring"] | |
| } | |
| def credential_trace(identifier: str, search_depth: str = "standard") -> dict: | |
| """Trace credential exposure across dark web databases and breach compilations. | |
| Searches known breach databases, combolists, and credential markets | |
| for exposure of the specified email, username, or domain pattern. | |
| Args: | |
| identifier: Email address, username, or domain pattern to trace | |
| search_depth: "surface" (recent breaches), "standard" (2 years), or "deep" (all known) | |
| Returns: | |
| JSON object with exposure_summary, breach_list, risk_score, | |
| password_patterns detected, and remediation steps | |
| """ | |
| trace_id = hashlib.sha256(f"trace_{identifier}".encode()).hexdigest()[:10] | |
| # Simulated breach data | |
| known_breaches = [ | |
| {"name": "Collection #1", "date": "2019-01", "records": "773M"}, | |
| {"name": "LinkedIn 2021", "date": "2021-06", "records": "700M"}, | |
| {"name": "Facebook 2019", "date": "2019-04", "records": "533M"}, | |
| {"name": "Exactis", "date": "2018-06", "records": "340M"}, | |
| {"name": "Apollo", "date": "2018-07", "records": "126M"}, | |
| ] | |
| # Randomly select some breaches for demo | |
| exposed_in = random.sample(known_breaches, k=random.randint(0, 4)) | |
| risk_score = min(100, len(exposed_in) * 25 + random.randint(0, 20)) | |
| password_patterns = [] | |
| if exposed_in: | |
| password_patterns = [ | |
| {"pattern": "plaintext", "instances": random.randint(1, 5)}, | |
| {"pattern": "md5_hash", "instances": random.randint(0, 3)}, | |
| {"pattern": "bcrypt", "instances": random.randint(0, 2)}, | |
| ] | |
| password_patterns = [p for p in password_patterns if p["instances"] > 0] | |
| return { | |
| "trace_id": trace_id, | |
| "identifier": identifier, | |
| "search_depth": search_depth, | |
| "timestamp": datetime.now().isoformat(), | |
| "exposure_summary": { | |
| "total_breaches": len(exposed_in), | |
| "earliest_exposure": exposed_in[0]["date"] if exposed_in else None, | |
| "risk_score": risk_score, | |
| "risk_level": "critical" if risk_score > 75 else "high" if risk_score > 50 else "moderate" if risk_score > 25 else "low" | |
| }, | |
| "breach_list": exposed_in, | |
| "password_patterns": password_patterns, | |
| "remediation": [ | |
| "Immediately change passwords on all associated accounts", | |
| "Enable 2FA/MFA on all critical services", | |
| "Monitor for unauthorized access attempts", | |
| "Consider identity monitoring services" | |
| ] if exposed_in else ["No known exposures found", "Maintain strong password hygiene"] | |
| } | |
| def chatter_analysis(keywords: str, timeframe_hours: int = 24) -> dict: | |
| """Analyze dark web chatter for specific keywords or entities. | |
| Monitors forums, markets, and communication channels for discussions | |
| involving the specified keywords to detect emerging threats. | |
| Args: | |
| keywords: Comma-separated keywords to monitor (company names, product names, executives) | |
| timeframe_hours: How far back to analyze (1-168 hours) | |
| Returns: | |
| JSON object with mention_count, sentiment_analysis, threat_indicators, | |
| top_sources, and sample_contexts | |
| """ | |
| keyword_list = [k.strip() for k in keywords.split(",")] | |
| analysis_id = hashlib.sha256(f"chatter_{keywords}".encode()).hexdigest()[:10] | |
| mention_count = random.randint(5, 200) | |
| # Simulated sentiment breakdown | |
| sentiment = { | |
| "hostile": random.randint(0, 30), | |
| "suspicious": random.randint(10, 40), | |
| "neutral": random.randint(20, 50), | |
| "commercial": random.randint(5, 25) # Selling data/access | |
| } | |
| threat_indicators = [] | |
| if sentiment["hostile"] > 20: | |
| threat_indicators.append({ | |
| "type": "targeted_discussion", | |
| "severity": "high", | |
| "detail": "Elevated hostile mentions detected" | |
| }) | |
| if sentiment["commercial"] > 15: | |
| threat_indicators.append({ | |
| "type": "data_sale_indicators", | |
| "severity": "critical", | |
| "detail": "Potential sale of company data/access detected" | |
| }) | |
| top_sources = [ | |
| {"source": "RaidForums successor", "mentions": random.randint(10, 50)}, | |
| {"source": "Telegram channels", "mentions": random.randint(5, 30)}, | |
| {"source": "Russian forums", "mentions": random.randint(2, 20)}, | |
| ] | |
| return { | |
| "analysis_id": analysis_id, | |
| "keywords": keyword_list, | |
| "timeframe_hours": timeframe_hours, | |
| "timestamp": datetime.now().isoformat(), | |
| "mention_count": mention_count, | |
| "trend": f"+{random.randint(5, 80)}%" if random.random() > 0.3 else f"-{random.randint(5, 30)}%", | |
| "sentiment_breakdown": sentiment, | |
| "threat_indicators": threat_indicators, | |
| "threat_level": "critical" if len(threat_indicators) > 1 else "elevated" if threat_indicators else "normal", | |
| "top_sources": top_sources, | |
| "recommended_actions": [ | |
| "Increase monitoring frequency", | |
| "Alert security team", | |
| "Prepare incident response" | |
| ] if threat_indicators else ["Continue routine monitoring"] | |
| } | |
| def identity_alert(name: str, additional_identifiers: Optional[str] = None) -> dict: | |
| """Check for identity exposure and impersonation attempts. | |
| Searches for PII exposure, fake profiles, impersonation attempts, | |
| and social engineering setups targeting the specified identity. | |
| Args: | |
| name: Full name of the person to check | |
| additional_identifiers: Optional comma-separated identifiers (email, phone, social handles) | |
| Returns: | |
| JSON object with exposure_findings, impersonation_alerts, | |
| social_engineering_indicators, and protection_recommendations | |
| """ | |
| alert_id = hashlib.sha256(f"identity_{name}".encode()).hexdigest()[:10] | |
| identifiers = [name] | |
| if additional_identifiers: | |
| identifiers.extend([i.strip() for i in additional_identifiers.split(",")]) | |
| exposure_findings = [] | |
| # Check for PII exposure | |
| if random.random() > 0.4: | |
| exposure_findings.append({ | |
| "type": "pii_exposure", | |
| "data_types": random.sample(["email", "phone", "address", "ssn_partial", "dob"], k=random.randint(1, 3)), | |
| "source": "data_broker_leak", | |
| "severity": "high" | |
| }) | |
| # Check for impersonation | |
| impersonation_alerts = [] | |
| if random.random() > 0.6: | |
| impersonation_alerts.append({ | |
| "platform": random.choice(["LinkedIn", "Twitter", "Facebook", "Instagram"]), | |
| "type": "fake_profile", | |
| "confidence": f"{random.randint(70, 95)}%", | |
| "created": (datetime.now() - timedelta(days=random.randint(1, 90))).strftime("%Y-%m-%d") | |
| }) | |
| # Social engineering indicators | |
| se_indicators = [] | |
| if random.random() > 0.5: | |
| se_indicators.append({ | |
| "type": "phishing_domain", | |
| "detail": f"Domain registered resembling target organization", | |
| "registered": (datetime.now() - timedelta(days=random.randint(1, 30))).strftime("%Y-%m-%d") | |
| }) | |
| risk_score = len(exposure_findings) * 30 + len(impersonation_alerts) * 25 + len(se_indicators) * 20 | |
| return { | |
| "alert_id": alert_id, | |
| "identity": name, | |
| "identifiers_checked": identifiers, | |
| "timestamp": datetime.now().isoformat(), | |
| "risk_score": min(100, risk_score), | |
| "exposure_findings": exposure_findings, | |
| "impersonation_alerts": impersonation_alerts, | |
| "social_engineering_indicators": se_indicators, | |
| "protection_recommendations": [ | |
| "Set up identity monitoring alerts", | |
| "Report fake profiles for takedown", | |
| "Brief the individual on social engineering risks", | |
| "Consider executive protection services" | |
| ] if (exposure_findings or impersonation_alerts) else ["No immediate threats detected", "Continue periodic monitoring"] | |
| } | |
| def generate_threat_report(organization: str, report_type: str = "executive") -> str: | |
| """Generate a comprehensive threat intelligence report. | |
| Creates a detailed report on the current threat landscape for | |
| the specified organization based on ShadowWatch monitoring data. | |
| Args: | |
| organization: Organization name to generate report for | |
| report_type: "executive" (summary), "technical" (detailed), or "incident" (specific event) | |
| Returns: | |
| Formatted markdown threat intelligence report | |
| """ | |
| report_id = hashlib.sha256(f"report_{organization}{datetime.now().isoformat()}".encode()).hexdigest()[:8] | |
| report = f"""# 🛡️ SHADOWWATCH THREAT INTELLIGENCE REPORT | |
| **Organization:** {organization} | |
| **Report ID:** {report_id.upper()} | |
| **Classification:** CONFIDENTIAL | |
| **Generated:** {datetime.now().strftime('%Y-%m-%d %H:%M:%S UTC')} | |
| **Report Type:** {report_type.upper()} | |
| --- | |
| ## EXECUTIVE SUMMARY | |
| ShadowWatch has been monitoring dark web activity related to **{organization}** across 47 marketplaces, 156 forums, and 89 communication channels. | |
| ### Current Threat Level: ⚠️ ELEVATED | |
| | Metric | Value | Trend | | |
| |--------|-------|-------| | |
| | Total Mentions (24h) | 127 | +23% | | |
| | Credential Exposures | 2,847 | +156 | | |
| | Active Threat Actors | 3 | Stable | | |
| | Data Sale Listings | 1 | NEW | | |
| --- | |
| ## ACTIVE THREATS | |
| ### 🔴 CRITICAL: Credential Database Listing | |
| **Detected:** {(datetime.now() - timedelta(hours=random.randint(1, 12))).strftime('%Y-%m-%d %H:%M')} UTC | |
| **Source:** Underground marketplace (Tier 1) | |
| **Details:** Threat actor "darkphantom_x" listed database claiming to contain {organization} employee credentials. Listing indicates 26,752 records including email/password combinations. | |
| **Recommended Actions:** | |
| - Immediate password reset for all employees | |
| - Enable MFA enforcement | |
| - Monitor for unauthorized access attempts | |
| ### 🟡 WARNING: Increased Forum Chatter | |
| **Detected:** Last 48 hours | |
| **Sources:** 3 Russian-language forums, 2 English forums | |
| **Details:** 72% increase in mentions of {organization} in hacking forums. Discussion topics include network reconnaissance and vulnerability scanning. | |
| ### 🟢 MONITORING: Phishing Infrastructure | |
| **Detected:** {(datetime.now() - timedelta(days=random.randint(1, 7))).strftime('%Y-%m-%d')} | |
| **Details:** 2 domains registered with similarity to {organization} primary domain. Currently parked but warrant monitoring. | |
| --- | |
| ## THREAT ACTOR PROFILES | |
| ### darkphantom_x | |
| - **First Seen:** 2023-04 | |
| - **Reputation:** Established seller (47 positive reviews) | |
| - **Specialization:** Corporate credential dumps | |
| - **Risk Level:** HIGH | |
| ### APT-SHADOW-7 (Suspected Nation-State) | |
| - **Attribution:** Medium confidence | |
| - **Known Targets:** Financial sector, Government contractors | |
| - **TTPs:** Spearphishing, Supply chain compromise | |
| - **Risk Level:** CRITICAL | |
| --- | |
| ## RECOMMENDATIONS | |
| 1. **Immediate (24-48 hours)** | |
| - Force password resets for potentially exposed accounts | |
| - Brief security team on elevated threat status | |
| - Increase monitoring of authentication logs | |
| 2. **Short-term (1-2 weeks)** | |
| - Conduct phishing simulation to test employee awareness | |
| - Review and harden external-facing systems | |
| - Engage takedown services for fraudulent domains | |
| 3. **Ongoing** | |
| - Maintain elevated monitoring posture | |
| - Weekly threat briefings for security leadership | |
| - Consider threat intelligence sharing with industry peers | |
| --- | |
| ## MONITORING CONFIGURATION | |
| | Source Type | Count | Status | | |
| |-------------|-------|--------| | |
| | Dark Web Markets | 15 | ✅ Active | | |
| | Hacking Forums | 23 | ✅ Active | | |
| | Paste Sites | 12 | ✅ Active | | |
| | Telegram Channels | 8 | ✅ Active | | |
| | IRC Channels | 4 | ✅ Active | | |
| --- | |
| *Report generated by ShadowWatch | Cogensec ARGUS Platform* | |
| *For questions: intel@cogensec.ai | 24/7 SOC: +1-XXX-XXX-XXXX* | |
| **CONFIDENTIAL - DO NOT DISTRIBUTE** | |
| """ | |
| return report | |
| # ============================================================================ | |
| # CUSTOM CSS - Matching the Dark Web Intelligence aesthetic | |
| # ============================================================================ | |
| custom_css = """ | |
| @import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600;700&family=Inter:wght@400;500;600&display=swap'); | |
| :root { | |
| --sw-bg-dark: #0a0f1a; | |
| --sw-bg-card: #111827; | |
| --sw-bg-card-hover: #1a2332; | |
| --sw-border: #1e3a5f; | |
| --sw-cyan: #00ffd5; | |
| --sw-cyan-dim: #00b396; | |
| --sw-yellow: #fbbf24; | |
| --sw-red: #ef4444; | |
| --sw-orange: #f97316; | |
| --sw-green: #22c55e; | |
| --sw-text: #e2e8f0; | |
| --sw-text-dim: #64748b; | |
| } | |
| /* Global styles */ | |
| .gradio-container { | |
| background: var(--sw-bg-dark) !important; | |
| font-family: 'Inter', sans-serif !important; | |
| max-width: 100% !important; | |
| } | |
| .dark { | |
| --background-fill-primary: var(--sw-bg-dark) !important; | |
| --background-fill-secondary: var(--sw-bg-card) !important; | |
| --border-color-primary: var(--sw-border) !important; | |
| } | |
| /* Header styling */ | |
| .header-bar { | |
| background: linear-gradient(90deg, var(--sw-bg-card) 0%, #0d1520 100%); | |
| border: 1px solid var(--sw-border); | |
| border-radius: 8px; | |
| padding: 16px 24px; | |
| margin-bottom: 20px; | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| } | |
| .logo-section { | |
| display: flex; | |
| align-items: center; | |
| gap: 12px; | |
| } | |
| .logo-icon { | |
| width: 40px; | |
| height: 40px; | |
| background: var(--sw-cyan); | |
| border-radius: 8px; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| } | |
| .logo-text { | |
| font-family: 'JetBrains Mono', monospace; | |
| font-size: 24px; | |
| font-weight: 700; | |
| color: white; | |
| letter-spacing: 2px; | |
| } | |
| .logo-subtitle { | |
| font-size: 11px; | |
| color: var(--sw-text-dim); | |
| letter-spacing: 3px; | |
| text-transform: uppercase; | |
| } | |
| .status-indicators { | |
| display: flex; | |
| gap: 24px; | |
| align-items: center; | |
| font-family: 'JetBrains Mono', monospace; | |
| font-size: 12px; | |
| } | |
| .status-item { | |
| display: flex; | |
| align-items: center; | |
| gap: 8px; | |
| } | |
| .status-dot { | |
| width: 8px; | |
| height: 8px; | |
| border-radius: 50%; | |
| background: var(--sw-green); | |
| box-shadow: 0 0 8px var(--sw-green); | |
| animation: pulse 2s infinite; | |
| } | |
| @keyframes pulse { | |
| 0%, 100% { opacity: 1; } | |
| 50% { opacity: 0.5; } | |
| } | |
| .status-label { | |
| color: var(--sw-text-dim); | |
| } | |
| .status-value { | |
| color: var(--sw-cyan); | |
| } | |
| .killswitch-btn { | |
| background: linear-gradient(135deg, #dc2626 0%, #991b1b 100%); | |
| color: white; | |
| border: none; | |
| padding: 8px 16px; | |
| border-radius: 6px; | |
| font-family: 'JetBrains Mono', monospace; | |
| font-weight: 600; | |
| cursor: pointer; | |
| display: flex; | |
| align-items: center; | |
| gap: 8px; | |
| } | |
| /* Card styling */ | |
| .info-card { | |
| background: var(--sw-bg-card); | |
| border: 1px solid var(--sw-border); | |
| border-radius: 8px; | |
| padding: 20px; | |
| margin-bottom: 16px; | |
| } | |
| .card-header { | |
| font-family: 'JetBrains Mono', monospace; | |
| font-size: 14px; | |
| font-weight: 600; | |
| color: var(--sw-cyan); | |
| letter-spacing: 2px; | |
| text-transform: uppercase; | |
| margin-bottom: 16px; | |
| display: flex; | |
| align-items: center; | |
| gap: 8px; | |
| } | |
| /* Terminal styling */ | |
| .terminal-output { | |
| background: #000 !important; | |
| border: 1px solid var(--sw-border); | |
| border-radius: 6px; | |
| padding: 16px; | |
| font-family: 'JetBrains Mono', monospace !important; | |
| font-size: 13px; | |
| line-height: 1.6; | |
| color: var(--sw-green); | |
| max-height: 300px; | |
| overflow-y: auto; | |
| } | |
| .terminal-output .error { | |
| color: var(--sw-red); | |
| } | |
| .terminal-output .warning { | |
| color: var(--sw-yellow); | |
| } | |
| .terminal-output .info { | |
| color: var(--sw-cyan); | |
| } | |
| /* Threat level meter */ | |
| .threat-meter { | |
| background: var(--sw-bg-card); | |
| border: 1px solid var(--sw-border); | |
| border-radius: 8px; | |
| padding: 20px; | |
| } | |
| .threat-bar { | |
| height: 8px; | |
| background: linear-gradient(90deg, var(--sw-green) 0%, var(--sw-yellow) 50%, var(--sw-red) 100%); | |
| border-radius: 4px; | |
| margin: 12px 0; | |
| position: relative; | |
| } | |
| .threat-indicator { | |
| position: absolute; | |
| top: -4px; | |
| width: 16px; | |
| height: 16px; | |
| background: white; | |
| border-radius: 50%; | |
| border: 2px solid var(--sw-bg-dark); | |
| transform: translateX(-50%); | |
| } | |
| .threat-labels { | |
| display: flex; | |
| justify-content: space-between; | |
| font-size: 11px; | |
| color: var(--sw-text-dim); | |
| text-transform: uppercase; | |
| letter-spacing: 1px; | |
| } | |
| /* Alert badges */ | |
| .badge { | |
| display: inline-block; | |
| padding: 4px 12px; | |
| border-radius: 4px; | |
| font-family: 'JetBrains Mono', monospace; | |
| font-size: 11px; | |
| font-weight: 600; | |
| letter-spacing: 1px; | |
| } | |
| .badge-critical { | |
| background: var(--sw-red); | |
| color: white; | |
| } | |
| .badge-warning { | |
| background: var(--sw-orange); | |
| color: white; | |
| } | |
| .badge-elevated { | |
| background: var(--sw-yellow); | |
| color: black; | |
| } | |
| .badge-normal { | |
| background: var(--sw-green); | |
| color: white; | |
| } | |
| /* Button styling */ | |
| .action-btn { | |
| background: var(--sw-bg-card) !important; | |
| border: 1px solid var(--sw-border) !important; | |
| color: var(--sw-text) !important; | |
| font-family: 'JetBrains Mono', monospace !important; | |
| padding: 12px 20px !important; | |
| border-radius: 6px !important; | |
| transition: all 0.2s !important; | |
| } | |
| .action-btn:hover { | |
| background: var(--sw-bg-card-hover) !important; | |
| border-color: var(--sw-cyan) !important; | |
| } | |
| .primary-btn { | |
| background: linear-gradient(135deg, var(--sw-cyan-dim) 0%, #007a6a 100%) !important; | |
| border: none !important; | |
| color: white !important; | |
| } | |
| /* Input styling */ | |
| .input-field input, .input-field textarea { | |
| background: var(--sw-bg-dark) !important; | |
| border: 1px solid var(--sw-border) !important; | |
| color: var(--sw-text) !important; | |
| font-family: 'JetBrains Mono', monospace !important; | |
| } | |
| .input-field input:focus, .input-field textarea:focus { | |
| border-color: var(--sw-cyan) !important; | |
| box-shadow: 0 0 0 2px rgba(0, 255, 213, 0.1) !important; | |
| } | |
| /* Tab styling */ | |
| .tabs { | |
| border: none !important; | |
| } | |
| .tab-nav { | |
| background: var(--sw-bg-card) !important; | |
| border: 1px solid var(--sw-border) !important; | |
| border-radius: 8px !important; | |
| padding: 4px !important; | |
| margin-bottom: 20px !important; | |
| } | |
| .tab-nav button { | |
| font-family: 'JetBrains Mono', monospace !important; | |
| font-size: 12px !important; | |
| letter-spacing: 1px !important; | |
| text-transform: uppercase !important; | |
| color: var(--sw-text-dim) !important; | |
| border-radius: 6px !important; | |
| padding: 12px 20px !important; | |
| } | |
| .tab-nav button.selected { | |
| background: var(--sw-cyan) !important; | |
| color: var(--sw-bg-dark) !important; | |
| } | |
| /* JSON output styling */ | |
| .json-output { | |
| background: #000 !important; | |
| border: 1px solid var(--sw-border) !important; | |
| border-radius: 6px !important; | |
| font-family: 'JetBrains Mono', monospace !important; | |
| } | |
| /* Markdown styling */ | |
| .markdown-body { | |
| background: var(--sw-bg-card) !important; | |
| color: var(--sw-text) !important; | |
| font-family: 'Inter', sans-serif !important; | |
| } | |
| .markdown-body h1, .markdown-body h2, .markdown-body h3 { | |
| color: var(--sw-cyan) !important; | |
| font-family: 'JetBrains Mono', monospace !important; | |
| } | |
| .markdown-body code { | |
| background: var(--sw-bg-dark) !important; | |
| color: var(--sw-cyan) !important; | |
| } | |
| .markdown-body table { | |
| border-color: var(--sw-border) !important; | |
| } | |
| .markdown-body th { | |
| background: var(--sw-bg-dark) !important; | |
| color: var(--sw-cyan) !important; | |
| } | |
| /* Footer */ | |
| .footer-bar { | |
| background: var(--sw-bg-card); | |
| border: 1px solid var(--sw-border); | |
| border-radius: 8px; | |
| padding: 12px 24px; | |
| margin-top: 20px; | |
| display: flex; | |
| justify-content: space-between; | |
| font-family: 'JetBrains Mono', monospace; | |
| font-size: 11px; | |
| color: var(--sw-text-dim); | |
| } | |
| .footer-stat { | |
| color: var(--sw-cyan); | |
| } | |
| .footer-threat { | |
| color: var(--sw-yellow); | |
| } | |
| /* Realtime indicator */ | |
| .realtime-indicator { | |
| display: flex; | |
| align-items: center; | |
| gap: 8px; | |
| font-family: 'JetBrains Mono', monospace; | |
| font-size: 12px; | |
| color: var(--sw-green); | |
| } | |
| .realtime-dot { | |
| width: 8px; | |
| height: 8px; | |
| background: var(--sw-green); | |
| border-radius: 50%; | |
| animation: pulse 1.5s infinite; | |
| } | |
| """ | |
| # ============================================================================ | |
| # GRADIO INTERFACE | |
| # ============================================================================ | |
| with gr.Blocks( | |
| title="ShadowWatch | Dark Web Intelligence", | |
| theme=gr.themes.Base( | |
| primary_hue="cyan", | |
| secondary_hue="slate", | |
| neutral_hue="slate", | |
| ).set( | |
| body_background_fill="#0a0f1a", | |
| block_background_fill="#111827", | |
| block_border_width="1px", | |
| block_border_color="#1e3a5f", | |
| button_primary_background_fill="#00b396", | |
| button_primary_text_color="white", | |
| input_background_fill="#0a0f1a", | |
| ), | |
| css=custom_css | |
| ) as demo: | |
| # Header HTML | |
| gr.HTML(""" | |
| <div class="header-bar"> | |
| <div class="logo-section"> | |
| <div class="logo-icon">🛡️</div> | |
| <div> | |
| <div class="logo-text">SHADOWWATCH</div> | |
| <div class="logo-subtitle">Dark Web Intelligence Platform</div> | |
| </div> | |
| </div> | |
| <div class="status-indicators"> | |
| <div class="status-item"> | |
| <span style="color: #fbbf24;">▪ ▪ ▪ ▪</span> | |
| </div> | |
| <div class="status-item"> | |
| <span class="status-dot"></span> | |
| <span class="status-label">TOR RELAY:</span> | |
| <span class="status-value">ACTIVE</span> | |
| </div> | |
| <div class="status-item"> | |
| <span class="status-label">ENCRYPTION:</span> | |
| <span class="status-value">AES-256</span> | |
| </div> | |
| <div class="status-item"> | |
| <span class="status-label">SESSION:</span> | |
| <span style="color: #22c55e;">SECURE</span> | |
| </div> | |
| <button class="killswitch-btn">⏻ KILLSWITCH</button> | |
| </div> | |
| </div> | |
| """) | |
| with gr.Row(): | |
| # Left sidebar | |
| with gr.Column(scale=1): | |
| # Agent card | |
| gr.HTML(""" | |
| <div class="info-card"> | |
| <div style="display: flex; align-items: center; gap: 12px; margin-bottom: 16px;"> | |
| <div style="width: 48px; height: 48px; background: #1e3a5f; border-radius: 8px; display: flex; align-items: center; justify-content: center; font-size: 24px;">👤</div> | |
| <div> | |
| <div style="font-family: 'JetBrains Mono', monospace; font-weight: 600; color: white;">AGENT-74X</div> | |
| <div style="font-size: 11px; color: #64748b; text-transform: uppercase; letter-spacing: 1px;">Senior Intelligence Analyst</div> | |
| </div> | |
| </div> | |
| <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 12px;"> | |
| <div style="background: #0a0f1a; padding: 12px; border-radius: 6px;"> | |
| <div style="font-size: 10px; color: #64748b; text-transform: uppercase; letter-spacing: 1px;">Clearance</div> | |
| <div style="font-family: 'JetBrains Mono', monospace; color: #00ffd5;">LEVEL 5</div> | |
| </div> | |
| <div style="background: #0a0f1a; padding: 12px; border-radius: 6px;"> | |
| <div style="font-size: 10px; color: #64748b; text-transform: uppercase; letter-spacing: 1px;">Status</div> | |
| <div style="font-family: 'JetBrains Mono', monospace; color: #22c55e;">ACTIVE</div> | |
| </div> | |
| <div style="background: #0a0f1a; padding: 12px; border-radius: 6px;"> | |
| <div style="font-size: 10px; color: #64748b; text-transform: uppercase; letter-spacing: 1px;">Team</div> | |
| <div style="font-family: 'JetBrains Mono', monospace; color: white;">PHANTOM</div> | |
| </div> | |
| <div style="background: #0a0f1a; padding: 12px; border-radius: 6px;"> | |
| <div style="font-size: 10px; color: #64748b; text-transform: uppercase; letter-spacing: 1px;">Since</div> | |
| <div style="font-family: 'JetBrains Mono', monospace; color: #00ffd5;">2018</div> | |
| </div> | |
| </div> | |
| </div> | |
| """) | |
| # Quick Actions - Now functional via tabs | |
| gr.HTML(""" | |
| <div class="info-card"> | |
| <div class="card-header">⚡ QUICK ACTIONS</div> | |
| </div> | |
| """) | |
| # Threat Level | |
| gr.HTML(""" | |
| <div class="threat-meter"> | |
| <div style="display: flex; justify-content: space-between; align-items: center;"> | |
| <div class="card-header" style="margin: 0;">⚠ THREAT LEVEL</div> | |
| <span class="badge badge-elevated">ELEVATED</span> | |
| </div> | |
| <div class="threat-bar"> | |
| <div class="threat-indicator" style="left: 45%;"></div> | |
| </div> | |
| <div class="threat-labels"> | |
| <span>LOW</span> | |
| <span>MODERATE</span> | |
| <span>HIGH</span> | |
| <span>CRITICAL</span> | |
| </div> | |
| <div style="margin-top: 12px; font-size: 12px; color: #22c55e;"> | |
| ● +12% DARKNET ACTIVITY | |
| </div> | |
| </div> | |
| """) | |
| # Main content area | |
| with gr.Column(scale=3): | |
| with gr.Tabs(): | |
| # Deep Scan Tab | |
| with gr.TabItem("🔍 DEEP SCAN"): | |
| gr.Markdown("**Crawl dark web sources for threat intelligence on your target.**") | |
| with gr.Row(): | |
| with gr.Column(): | |
| scan_target = gr.Textbox( | |
| label="Target", | |
| placeholder="Enter domain, company name, email pattern...", | |
| elem_classes=["input-field"] | |
| ) | |
| scan_type = gr.Radio( | |
| label="Scan Depth", | |
| choices=["quick", "standard", "comprehensive"], | |
| value="standard" | |
| ) | |
| scan_btn = gr.Button("▶ INITIATE SCAN", variant="primary") | |
| with gr.Column(): | |
| scan_output = gr.JSON(label="Scan Results", elem_classes=["json-output"]) | |
| scan_btn.click( | |
| fn=deep_scan, | |
| inputs=[scan_target, scan_type], | |
| outputs=[scan_output] | |
| ) | |
| # Credential Trace Tab | |
| with gr.TabItem("🔑 CREDENTIAL TRACE"): | |
| gr.Markdown("**Search breach databases for credential exposure.**") | |
| with gr.Row(): | |
| with gr.Column(): | |
| cred_identifier = gr.Textbox( | |
| label="Identifier", | |
| placeholder="Email, username, or domain pattern...", | |
| elem_classes=["input-field"] | |
| ) | |
| cred_depth = gr.Radio( | |
| label="Search Depth", | |
| choices=["surface", "standard", "deep"], | |
| value="standard" | |
| ) | |
| cred_btn = gr.Button("▶ TRACE CREDENTIALS", variant="primary") | |
| with gr.Column(): | |
| cred_output = gr.JSON(label="Trace Results", elem_classes=["json-output"]) | |
| cred_btn.click( | |
| fn=credential_trace, | |
| inputs=[cred_identifier, cred_depth], | |
| outputs=[cred_output] | |
| ) | |
| # Chatter Analysis Tab | |
| with gr.TabItem("💬 CHATTER ANALYSIS"): | |
| gr.Markdown("**Monitor dark web discussions for specific keywords.**") | |
| with gr.Row(): | |
| with gr.Column(): | |
| chatter_keywords = gr.Textbox( | |
| label="Keywords (comma-separated)", | |
| placeholder="company name, product, executive name...", | |
| elem_classes=["input-field"] | |
| ) | |
| chatter_timeframe = gr.Slider( | |
| label="Timeframe (hours)", | |
| minimum=1, | |
| maximum=168, | |
| value=24, | |
| step=1 | |
| ) | |
| chatter_btn = gr.Button("▶ ANALYZE CHATTER", variant="primary") | |
| with gr.Column(): | |
| chatter_output = gr.JSON(label="Analysis Results", elem_classes=["json-output"]) | |
| chatter_btn.click( | |
| fn=chatter_analysis, | |
| inputs=[chatter_keywords, chatter_timeframe], | |
| outputs=[chatter_output] | |
| ) | |
| # Identity Alert Tab | |
| with gr.TabItem("👤 IDENTITY ALERT"): | |
| gr.Markdown("**Check for identity exposure and impersonation attempts.**") | |
| with gr.Row(): | |
| with gr.Column(): | |
| identity_name = gr.Textbox( | |
| label="Full Name", | |
| placeholder="John Smith", | |
| elem_classes=["input-field"] | |
| ) | |
| identity_extras = gr.Textbox( | |
| label="Additional Identifiers (optional)", | |
| placeholder="email@company.com, @twitter_handle", | |
| elem_classes=["input-field"] | |
| ) | |
| identity_btn = gr.Button("▶ CHECK IDENTITY", variant="primary") | |
| with gr.Column(): | |
| identity_output = gr.JSON(label="Alert Results", elem_classes=["json-output"]) | |
| identity_btn.click( | |
| fn=identity_alert, | |
| inputs=[identity_name, identity_extras], | |
| outputs=[identity_output] | |
| ) | |
| # Threat Report Tab | |
| with gr.TabItem("📊 THREAT REPORT"): | |
| gr.Markdown("**Generate comprehensive threat intelligence reports.**") | |
| with gr.Row(): | |
| with gr.Column(scale=1): | |
| report_org = gr.Textbox( | |
| label="Organization", | |
| placeholder="Acme Corporation", | |
| elem_classes=["input-field"] | |
| ) | |
| report_type = gr.Radio( | |
| label="Report Type", | |
| choices=["executive", "technical", "incident"], | |
| value="executive" | |
| ) | |
| report_btn = gr.Button("▶ GENERATE REPORT", variant="primary") | |
| with gr.Column(scale=2): | |
| report_output = gr.Markdown(label="Threat Report") | |
| report_btn.click( | |
| fn=generate_threat_report, | |
| inputs=[report_org, report_type], | |
| outputs=[report_output] | |
| ) | |
| # Footer | |
| gr.HTML(""" | |
| <div class="footer-bar"> | |
| <div> | |
| <span style="margin-right: 24px;">📊 DARK WEB ACTIVITY ANALYSIS</span> | |
| <span>LAST 24H: <span class="footer-stat">1,247 ALERTS</span></span> | |
| </div> | |
| <div> | |
| <span>TOP THREAT: <span class="footer-threat">CREDENTIAL LEAKS</span></span> | |
| </div> | |
| </div> | |
| """) | |
| # MCP Integration info | |
| gr.HTML(""" | |
| <div class="info-card" style="margin-top: 20px;"> | |
| <div class="card-header">🔗 MCP INTEGRATION</div> | |
| <p style="color: #94a3b8; font-size: 13px; margin-bottom: 12px;"> | |
| Connect this Space to Claude, Cursor, or any MCP client: | |
| </p> | |
| <pre style="background: #000; padding: 16px; border-radius: 6px; font-family: 'JetBrains Mono', monospace; font-size: 12px; color: #00ffd5; overflow-x: auto;"> | |
| { | |
| "mcpServers": { | |
| "shadowwatch": { | |
| "url": "https://crypticallyrequie-shadowwatch.hf.space/gradio_api/mcp/sse" | |
| } | |
| } | |
| }</pre> | |
| <p style="color: #64748b; font-size: 11px; margin-top: 12px;"> | |
| Built by <span style="color: #00ffd5;">Cogensec</span> | Part of the ARGUS AI Security Platform | |
| </p> | |
| </div> | |
| """) | |
| # Launch with MCP server enabled | |
| if __name__ == "__main__": | |
| demo.launch(mcp_server=True) | |