threat intelligence

Monitoring Dark Web Sources

Monitors dark web forums, marketplaces, paste sites, and ransomware leak sites for mentions of organizational assets, leaked credentials, threatened attacks, and threat actor communications to provide early warning intelligence. Use when establishing dark web monitoring coverage, investigating specific data breach claims, or enriching incident investigations with dark web context. Activates for requests involving dark web OSINT, leak site monitoring, credential exposure, Recorded Future dark web, or Tor hidden service intelligence.

credential-monitoringctidark-webosintransomware-leaksrecorded-futurespiderfoot
Install this skill
npx skills add mukul975/Anthropic-Cybersecurity-Skills
Framework mappings

When to Use

Use this skill when:

  • Establishing continuous monitoring for organizational domain names, executive names, and product brands on dark web forums
  • Investigating a reported data breach claim found on a ransomware leak site or paste site
  • Enriching an incident investigation with context about stolen credentials or planned attacks

Do not use this skill without proper operational security measures — dark web browsing without isolation exposes analyst infrastructure to adversary counter-intelligence.

Prerequisites

  • Commercial dark web monitoring service (Recorded Future, Flashpoint, Intel 471, or Cybersixgill)
  • Isolated operational environment: Whonix OS or Tails OS running in a VM with no persistent storage
  • Keyword watchlist: organization domain, key executive names, product names, IP ranges, known credentials
  • Legal guidance confirming passive monitoring is authorized in your jurisdiction

Workflow

Step 1: Establish Keyword Monitoring via Commercial Services

Configure dark web monitoring keywords in your CTI platform (e.g., Recorded Future Exposure module):

  • Domain variations: company.com, @company.com, company[dot]com
  • Executive names: CEO, CISO, CFO full names
  • Product/brand names
  • Internal codenames or project names (if suspected breach scope is broad)
  • Known email domains for credential monitoring

Most commercial services (Flashpoint, Intel 471, Cybersixgill) crawl forums like XSS, Exploit[.]in, BreachForums, and Russian-language cybercriminal communities without analyst exposure.

Step 2: Manual Investigation with Operational Security

For investigations requiring direct dark web access:

Environment setup:

  1. Use a dedicated physical machine or air-gapped VM (Whonix + VirtualBox)
  2. Connect via Tor Browser only — never via standard browser
  3. Use a cover identity with no links to organization
  4. Never log in with real credentials to any dark web site
  5. Document all sessions in investigation log with timestamps

Paste site monitoring (clearnet-accessible, no Tor required):

# Hunt paste sites via API
curl "https://psbdmp.ws/api/search/company.com" | jq '.data[].id'
curl "https://pastebin.com/search?q=company.com" # Rate-limited public search

Step 3: Investigate Ransomware Leak Sites

Ransomware groups maintain .onion leak sites. Monitor these through commercial services rather than direct access. When a claim appears about your organization:

  1. Capture screenshot evidence via commercial service (do not access directly)
  2. Assess legitimacy: Does the threat actor's claimed data align with any known internal systems?
  3. Check timestamp: Is this claim recent or historical?
  4. Cross-reference with any known security incidents or phishing campaigns from that timeframe
  5. Engage IR team if claim appears credible before public disclosure

Known active ransomware leak site operators (as of early 2025): LockBit (disrupted Feb 2024), ALPHV/BlackCat (disrupted Dec 2023), Cl0p, RansomHub, Play.

Step 4: Credential Exposure Monitoring

For leaked credential monitoring:

  • Have I Been Pwned Enterprise: Domain-level notification for credential exposures in breach datasets
  • SpyCloud: Commercial credential monitoring with anti-cracking and plaintext password recovery from criminal markets
  • Flare Systems: Automated monitoring of paste sites and dark web markets for credential dumps

When credential exposures are confirmed:

  1. Force password reset for affected accounts immediately
  2. Check if credentials provide access to any organizational systems (SSO, VPN)
  3. Review access logs for the period between credential exposure and detection for unauthorized access

Step 5: Document and Escalate Findings

For each dark web finding:

  • Capture evidence (commercial service screenshot, paste site archive)
  • Classify severity: P1 (imminent attack threat or active data exposure), P2 (credential exposure), P3 (general mention)
  • Notify appropriate stakeholders within defined SLAs
  • Open investigation ticket and link to evidence artifacts
  • Apply TLP:RED for any findings referencing named executives or specific attack plans

Key Concepts

Term Definition
Dark Web Tor-accessible hidden services (.onion domains) not indexed by standard search engines; hosts both legitimate and criminal content
Paste Site Clearnet text-sharing sites (Pastebin, Ghostbin) frequently used to publish stolen data or malware configurations
Ransomware Leak Site .onion site operated by ransomware group to publish stolen victim data as extortion leverage
Operational Security (OPSEC) Protecting analyst identity and organizational affiliation during dark web investigation
Credential Stuffing Automated use of leaked username/password pairs against authentication systems
Stealer Logs Data packages exfiltrated by infostealer malware containing saved browser credentials, cookies, and session tokens

Tools & Systems

  • Recorded Future Dark Web Module: Automated monitoring of dark web sources with alerting on organization-specific keywords
  • Flashpoint: Dark web forum monitoring with human intelligence augmentation for criminal community context
  • Intel 471: Closed-source access to cybercriminal communities with structured intelligence on threat actors
  • SpyCloud: Credential exposure monitoring with recaptured plaintext passwords from criminal markets
  • Have I Been Pwned Enterprise: Domain-level breach notification API for credential monitoring at scale

Common Pitfalls

  • Direct access without OPSEC: Accessing dark web forums without Tor and a cover identity can expose analyst IP, browser fingerprint, and organization affiliation to adversaries.
  • Overreacting to unverified claims: Ransomware groups and forum posters fabricate attack claims for extortion or reputation. Verify before escalating to incident response.
  • Missing clearnet sources: Most dark web intelligence programs miss Telegram channels, Discord servers, and paste sites which operate on the clearnet and host significant criminal activity.
  • Inadequate legal review: Dark web monitoring must be reviewed by legal counsel — passive monitoring is generally lawful but active participation in criminal markets is not.
  • No evidence preservation: Dark web content disappears rapidly. Capture timestamped evidence immediately upon discovery using commercial service exports.
Source materials

References and resources

Everything below is rendered for inspection. Script files are read-only and never run.

References 1

api-reference.md2.2 KB

API Reference: Monitoring Dark Web Sources

Have I Been Pwned API v3

Endpoint Method Description
/api/v3/breaches GET List all known data breaches
/api/v3/breach/{name} GET Get details of a specific breach
/api/v3/pasteaccount/{email} GET Search paste site archives for an email
/api/v3/breachedaccount/{email} GET Check if email appears in breaches

Dehashed API

Endpoint Method Description
/search?query=domain:example.com GET Search exposed credentials by domain
/search?query=email:user@example.com GET Search by specific email address

Ransomware.live API

Endpoint Method Description
/recentvictims GET List recent ransomware leak site victims
/groups GET List tracked ransomware groups
/group/{name} GET Get details for a specific ransomware group

Recorded Future Dark Web Module

Endpoint Method Description
/v2/darkweb/search GET Search dark web mentions by keyword
/v2/credentials/search GET Search exposed credentials

Key Libraries

  • requests: HTTP client for HIBP, Dehashed, and ransomware.live APIs
  • spiderfoot (CLI): OSINT automation including dark web module sfp_darkweb
  • theHarvester: Domain reconnaissance including breach data sources

Configuration

Variable Description
HIBP_API_KEY Have I Been Pwned API key (paid tier for domain search)
DEHASHED_API_KEY Dehashed API key for credential exposure search
DEHASHED_EMAIL Dehashed account email for API authentication
RF_API_TOKEN Recorded Future API token for dark web module

Rate Limits

API Rate Limit
HIBP 10 requests/minute (paid key)
Dehashed 5 requests/second
Ransomware.live No published limit (be respectful)

References

Scripts 1

agent.py6.6 KB
Display-only source. This catalog never executes bundled scripts.
#!/usr/bin/env python3
"""
Dark Web Source Monitoring Agent
Monitors dark web forums, paste sites, and ransomware leak sites for
organizational asset mentions using commercial APIs and OSINT tools.
"""

import json
import os
import sys
from datetime import datetime, timezone

import requests


HAVE_I_BEEN_PWNED_API = "https://haveibeenpwned.com/api/v3"
DEHASHED_API = "https://api.dehashed.com/search"


def check_breach_exposure(domain: str, hibp_api_key: str) -> list[dict]:
    """Check Have I Been Pwned for domain breach exposure."""
    if not hibp_api_key:
        return [{"error": "HIBP_API_KEY not set"}]

    headers = {
        "hibp-api-key": hibp_api_key,
        "user-agent": "DarkWebMonitor-Agent",
    }
    resp = requests.get(
        f"{HAVE_I_BEEN_PWNED_API}/breaches",
        headers=headers, timeout=30,
    )
    if resp.status_code != 200:
        return [{"error": f"HIBP returned {resp.status_code}"}]

    breaches = resp.json()
    relevant = []
    for breach in breaches:
        if domain.lower() in breach.get("Domain", "").lower():
            relevant.append({
                "name": breach["Name"],
                "domain": breach["Domain"],
                "breach_date": breach.get("BreachDate", ""),
                "pwn_count": breach.get("PwnCount", 0),
                "data_classes": breach.get("DataClasses", []),
                "is_verified": breach.get("IsVerified", False),
            })

    return relevant


def search_paste_sites(org_keywords: list[str], api_key: str) -> list[dict]:
    """Search paste site archives for organization mentions."""
    results = []
    for keyword in org_keywords:
        resp = requests.get(
            f"{HAVE_I_BEEN_PWNED_API}/pasteaccount/{keyword}",
            headers={"hibp-api-key": api_key, "user-agent": "DarkWebMonitor-Agent"},
            timeout=30,
        )
        if resp.status_code == 200:
            pastes = resp.json()
            for paste in pastes:
                results.append({
                    "keyword": keyword,
                    "source": paste.get("Source", ""),
                    "id": paste.get("Id", ""),
                    "title": paste.get("Title", ""),
                    "date": paste.get("Date", ""),
                    "email_count": paste.get("EmailCount", 0),
                })

    return results


def check_credential_exposure(domain: str, dehashed_key: str, dehashed_email: str) -> dict:
    """Search Dehashed for exposed credentials matching domain."""
    if not dehashed_key:
        return {"error": "DEHASHED_API_KEY not set", "results": []}

    resp = requests.get(
        DEHASHED_API,
        params={"query": f"domain:{domain}", "size": 100},
        auth=(dehashed_email, dehashed_key),
        headers={"Accept": "application/json"},
        timeout=30,
    )

    if resp.status_code != 200:
        return {"error": f"Dehashed returned {resp.status_code}", "results": []}

    data = resp.json()
    entries = data.get("entries", [])
    return {
        "total_exposed": data.get("total", 0),
        "results_returned": len(entries),
        "sources": list(set(e.get("database_name", "") for e in entries)),
        "sample_entries": [
            {"email": e.get("email", ""), "source": e.get("database_name", ""),
             "has_password": bool(e.get("password") or e.get("hashed_password"))}
            for e in entries[:20]
        ],
    }


def monitor_ransomware_leak_sites(org_name: str) -> dict:
    """Check ransomware leak site intelligence feeds for organization mentions.
    Uses Ransomware.live API (public aggregator)."""
    results = {"mentions": [], "checked_groups": []}

    resp = requests.get(
        "https://api.ransomware.live/recentvictims",
        timeout=30,
    )
    if resp.status_code == 200:
        victims = resp.json()
        for victim in victims:
            victim_name = victim.get("victim", "").lower()
            if org_name.lower() in victim_name:
                results["mentions"].append({
                    "victim": victim.get("victim", ""),
                    "group": victim.get("group_name", ""),
                    "discovered": victim.get("discovered", ""),
                    "url": victim.get("post_url", ""),
                })

    resp2 = requests.get("https://api.ransomware.live/groups", timeout=30)
    if resp2.status_code == 200:
        groups = resp2.json()
        results["checked_groups"] = [g.get("name", "") for g in groups[:30]]

    return results


def generate_monitoring_report(
    domain: str, breaches: list, pastes: list, creds: dict, leak_results: dict
) -> str:
    """Generate dark web monitoring report."""
    lines = [
        "DARK WEB MONITORING REPORT",
        "=" * 50,
        f"Monitored Domain: {domain}",
        f"Report Date: {datetime.now(timezone.utc).strftime('%Y-%m-%d %H:%M UTC')}",
        "",
        "BREACH EXPOSURE:",
        f"  Known Breaches Involving Domain: {len(breaches)}",
    ]
    for b in breaches[:5]:
        lines.append(f"  - {b['name']} ({b['breach_date']}) - {b['pwn_count']:,} accounts")

    lines.extend([
        "",
        "PASTE SITE EXPOSURE:",
        f"  Paste Mentions Found: {len(pastes)}",
    ])

    lines.extend([
        "",
        "CREDENTIAL EXPOSURE:",
        f"  Total Exposed Records: {creds.get('total_exposed', 0):,}",
        f"  Source Databases: {len(creds.get('sources', []))}",
    ])

    lines.extend([
        "",
        "RANSOMWARE LEAK SITES:",
        f"  Groups Monitored: {len(leak_results.get('checked_groups', []))}",
        f"  Mentions Found: {len(leak_results.get('mentions', []))}",
    ])
    for m in leak_results.get("mentions", []):
        lines.append(f"  - {m['victim']} by {m['group']} ({m['discovered']})")

    return "\n".join(lines)


if __name__ == "__main__":
    domain = sys.argv[1] if len(sys.argv) > 1 else "example.com"
    hibp_key = os.getenv("HIBP_API_KEY", "")
    dehashed_key = os.getenv("DEHASHED_API_KEY", "")
    dehashed_email = os.getenv("DEHASHED_EMAIL", "")

    print(f"[*] Dark web monitoring for: {domain}")

    breaches = check_breach_exposure(domain, hibp_key)
    pastes = search_paste_sites([f"@{domain}"], hibp_key)
    creds = check_credential_exposure(domain, dehashed_key, dehashed_email)
    leak_results = monitor_ransomware_leak_sites(domain.split(".")[0])

    report = generate_monitoring_report(domain, breaches, pastes, creds, leak_results)
    print(report)

    output = f"darkweb_monitor_{domain.replace('.', '_')}_{datetime.now(timezone.utc).strftime('%Y%m%d')}.json"
    with open(output, "w") as f:
        json.dump({"breaches": breaches, "pastes": pastes, "credentials": creds, "leak_sites": leak_results}, f, indent=2)
    print(f"\n[*] Results saved to {output}")
Keep exploring