threat intelligence

Evaluating Threat Intelligence Platforms

Evaluates and selects Threat Intelligence Platform (TIP) products based on organizational requirements including feed integration capability, STIX/TAXII support, workflow automation, analyst interface, and total cost of ownership. Use when conducting a TIP procurement, migrating between TIP solutions, or assessing whether the current TIP meets program maturity requirements. Activates for requests involving ThreatConnect, MISP, OpenCTI, Anomali, EclecticIQ, or TIP procurement decisions.

anomalicti-programeclecticiqmispopenctiprocurementstix-taxiithreatconnect
Install this skill
npx skills add mukul975/Anthropic-Cybersecurity-Skills
Framework mappings

When to Use

Use this skill when:

  • Conducting a formal RFP or vendor evaluation for a TIP solution
  • Assessing whether the current TIP (e.g., MISP) needs to be replaced or augmented as the CTI program scales
  • Establishing evaluation criteria aligned to organizational maturity and budget

Do not use this skill for evaluating feed quality independently of the TIP — feed evaluation is a separate workflow focused on data quality rather than platform capabilities.

Prerequisites

  • Documented CTI program requirements: team size, feed sources, integration targets, use cases
  • Budget range and procurement timeline
  • Technical staff who will administer the platform (Python/API experience for open-source TIPs)
  • List of current and planned integrations (SIEM, SOAR, EDR, firewalls)

Workflow

Step 1: Define Evaluation Criteria

Structure requirements into mandatory (M) and desired (D) categories:

Core TIP Functions:

  • M: STIX 2.1 import/export with TAXII 2.1 server
  • M: REST API for automated IOC ingestion and export
  • M: Indicator deduplication and TTL management
  • M: TLP classification enforcement
  • D: Built-in MITRE ATT&CK integration and technique tagging
  • D: Graph visualization of indicator relationships
  • D: Workflow automation for analyst triage

Integrations:

  • M: SIEM integration (Splunk, Sentinel, QRadar) via syslog, API, or native connector
  • M: EDR integration for IOC push (CrowdStrike, Defender, SentinelOne)
  • D: SOAR integration (XSOAR, Splunk SOAR) for playbook triggers
  • D: Ticketing system (ServiceNow, Jira) for intelligence task tracking

Operational:

  • M: Role-based access control with TLP-aware data segregation
  • M: Audit logging for all analyst actions
  • D: Multi-tenancy for MSSP use cases

Step 2: Evaluate Major TIP Options

MISP (Open Source):

  • Cost: Free (self-hosted infrastructure cost only)
  • Strengths: Largest community, 250+ modules, extensive ISAC usage, STIX 2.0 native
  • Weaknesses: Requires dedicated admin, limited visualization, UI dated
  • Best for: Budget-constrained teams with technical staff; government/ISAC sharing programs

OpenCTI (Open Source):

  • Cost: Free (self-hosted); paid SaaS at ~$3,000–$15,000/year
  • Strengths: Native STIX 2.1, graph visualization, ATT&CK integration, modern API
  • Weaknesses: Resource-intensive deployment (Elasticsearch, MinIO required)
  • Best for: Teams wanting open source with modern UX; SOC/CTI integration focus

ThreatConnect (Commercial):

  • Cost: $50,000–$500,000/year depending on scale
  • Strengths: End-to-end CTI lifecycle, playbook automation, TC Exchange marketplace, analyst workflow
  • Weaknesses: High cost; complex implementation; best value at larger scale
  • Best for: Mature enterprise CTI programs; MSSPs; red team/blue team integration

Anomali ThreatStream (Commercial):

  • Cost: $30,000–$200,000/year
  • Strengths: Strong feed aggregation, Splunk-native integration, extensive pre-built connectors
  • Weaknesses: Graph visualization weaker than OpenCTI; UI refresh lagging
  • Best for: Splunk-heavy environments; teams prioritizing feed volume over analysis workflows

EclecticIQ Platform (Commercial):

  • Cost: $40,000–$300,000/year
  • Strengths: STIX 2.1 native, collaborative intelligence workbench, strong European customer base
  • Weaknesses: Smaller partner ecosystem than ThreatConnect
  • Best for: Teams with MITRE ATT&CK-centric workflows; EMEA-focused organizations

Step 3: Conduct Proof of Concept

Request 30-day PoC from finalists. Test:

  1. Feed onboarding: Can your top 5 feeds be ingested within 4 hours?
  2. SIEM integration: Can enriched IOCs push to your SIEM in <5 minutes?
  3. ATT&CK mapping: Can analysts tag indicators with ATT&CK techniques efficiently?
  4. Report generation: Can the platform produce a tactical IOC bulletin with one click?
  5. API performance: Can the REST API handle 10,000 indicator queries per day?

Step 4: Score and Select

Use weighted scoring matrix (weight each criterion by organizational priority):

Criterion                 Weight   Vendor A   Vendor B
STIX 2.1 compliance       20%      95         85
SIEM integration          25%      90         70
ATT&CK mapping            15%      85         95
Cost (inverse)            20%      60         90
UI/analyst experience     10%      80         75
Vendor support quality    10%      85         80
TOTAL                     100%     82.0       81.5

Step 5: Implementation and Onboarding Planning

Plan 90-day implementation:

  • Week 1–2: Infrastructure deployment (cloud or on-prem)
  • Week 3–4: Feed onboarding and deduplication tuning
  • Week 5–6: SIEM/SOAR integration and testing
  • Week 7–8: Analyst workflow configuration and training
  • Week 9–12: Operational validation and go-live

Key Concepts

Term Definition
TIP Threat Intelligence Platform — software for collecting, processing, analyzing, and disseminating cyber threat intelligence
TAXII Server Component of a TIP that serves STIX bundles to consuming systems on request
TC Exchange ThreatConnect's commercial marketplace for pre-built feed integrations and app connectors
Multi-tenancy TIP capability to serve multiple organizational units or customers with isolated data environments
Deduplication Process of identifying and merging duplicate indicators within a TIP to reduce analyst noise

Tools & Systems

  • MISP: Open-source TIP used by 6,000+ organizations; strongest ISAC/government community integration
  • OpenCTI: Modern open-source TIP with native STIX 2.1 and graph-based analysis
  • ThreatConnect: Enterprise commercial TIP with lifecycle management and SOAR playbook integration
  • Anomali ThreatStream: Commercial TIP with strong Splunk ecosystem integration
  • EclecticIQ: Commercial TIP with ATT&CK-centric workflow design

Common Pitfalls

  • Selecting TIP before defining requirements: Technology selection before use case definition leads to expensive mismatches.
  • Underestimating administration burden: MISP and OpenCTI require dedicated admin time (minimum 0.25 FTE); budget accordingly.
  • Ignoring data migration costs: Moving historical intelligence from one TIP to another is costly and often impractical for legacy systems.
  • Not testing SIEM integration in PoC: TIP value depends heavily on downstream integration quality; always test SIEM/SOAR connectivity during evaluation.
Source materials

References and resources

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

References 1

api-reference.md2.7 KB

Threat Intelligence Platform Evaluation API Reference

MISP REST API

# Get version
curl "https://misp.example.com/servers/getVersion.json" \
  -H "Authorization: YOUR_API_KEY" -H "Accept: application/json"
 
# Search events
curl -X POST "https://misp.example.com/events/restSearch" \
  -H "Authorization: YOUR_API_KEY" -H "Content-Type: application/json" \
  -d '{"tags": ["apt28"], "limit": 50}'
 
# Export STIX 2.1
curl "https://misp.example.com/events/restSearch" \
  -H "Authorization: YOUR_API_KEY" -H "Accept: application/json" \
  -d '{"returnFormat": "stix2"}'
 
# Feed management
curl "https://misp.example.com/feeds/index.json" -H "Authorization: YOUR_API_KEY"

OpenCTI GraphQL API

# Get platform version
query { about { version } }
 
# Search indicators
query {
  indicators(filters: { key: "pattern_type", values: ["stix"] }) {
    edges { node { name pattern valid_from valid_until } }
  }
}
 
# Get campaigns
query {
  campaigns(first: 20, orderBy: created_at, orderMode: desc) {
    edges { node { name first_seen last_seen objectLabel { value } } }
  }
}

ThreatConnect REST API

# List indicators
curl "https://api.threatconnect.com/v3/indicators" \
  -H "Authorization: TC <ACCESS_ID>:<HMAC_SIGNATURE>"
 
# Create indicator
curl -X POST "https://api.threatconnect.com/v3/indicators" \
  -H "Content-Type: application/json" \
  -d '{"type":"Host","hostName":"evil.example.com","rating":5,"confidence":80}'

TAXII 2.1 API

# Discovery
curl https://taxii.example.com/taxii2/ -H "Accept: application/taxii+json;version=2.1"
 
# Get API roots
curl https://taxii.example.com/api1/ -H "Accept: application/taxii+json;version=2.1"
 
# List collections
curl https://taxii.example.com/api1/collections/ -H "Accept: application/taxii+json;version=2.1"
 
# Get objects from collection
curl "https://taxii.example.com/api1/collections/{id}/objects/" \
  -H "Accept: application/stix+json;version=2.1"

TIP Evaluation Criteria Weights

Category Criterion Weight
Core STIX 2.1 support 10
Core REST API 9
Core TAXII server 8
Core TLP enforcement 8
Integration SIEM integration 9
Integration Feed ingestion 8
Integration EDR integration 7
Operations Sharing (ISAC) 7
Operations Analyst workflow 7
Operations Reporting 6

Platform Comparison Matrix

Feature MISP OpenCTI ThreatConnect
License Open Source Open Source Commercial
STIX 2.1 Native Native Import/Export
TAXII 2.1 Yes Yes Yes
ATT&CK Plugin Native Module
Graph Viz Basic Advanced Advanced
SOAR API Connectors Playbooks

Scripts 1

agent.py9.3 KB
Display-only source. This catalog never executes bundled scripts.
#!/usr/bin/env python3
"""Threat Intelligence Platform evaluation agent for MISP, OpenCTI, and ThreatConnect."""

import json
import sys
import urllib.request
import ssl
from datetime import datetime


class TIPEvaluator:
    """Evaluate and test TIP platform capabilities."""

    EVALUATION_CRITERIA = {
        "core_functions": {
            "stix_support": {"weight": 10, "description": "STIX 2.1 import/export support"},
            "taxii_server": {"weight": 8, "description": "TAXII 2.1 server capability"},
            "rest_api": {"weight": 9, "description": "RESTful API for automation"},
            "deduplication": {"weight": 7, "description": "Indicator deduplication and TTL management"},
            "tlp_enforcement": {"weight": 8, "description": "TLP classification enforcement"},
            "attack_mapping": {"weight": 6, "description": "MITRE ATT&CK integration"},
            "graph_viz": {"weight": 5, "description": "Graph visualization of relationships"},
        },
        "integrations": {
            "siem_integration": {"weight": 9, "description": "SIEM bi-directional integration"},
            "edr_integration": {"weight": 7, "description": "EDR IOC push capability"},
            "soar_integration": {"weight": 7, "description": "SOAR playbook integration"},
            "firewall_integration": {"weight": 6, "description": "Firewall blocklist export"},
            "feed_ingestion": {"weight": 8, "description": "Multiple feed source support"},
        },
        "operations": {
            "analyst_workflow": {"weight": 7, "description": "Investigation workflow tools"},
            "reporting": {"weight": 6, "description": "Report generation and export"},
            "sharing": {"weight": 7, "description": "Community/ISAC sharing support"},
            "rbac": {"weight": 5, "description": "Role-based access control"},
            "audit_logging": {"weight": 4, "description": "Audit trail for compliance"},
        },
    }

    def score_platform(self, platform_name, scores):
        """Calculate weighted score for a TIP platform.

        scores: dict of criterion_name -> score (0-10)
        """
        total_weight = 0
        weighted_score = 0
        details = []

        for category, criteria in self.EVALUATION_CRITERIA.items():
            for criterion, info in criteria.items():
                score = scores.get(criterion, 0)
                weight = info["weight"]
                total_weight += weight
                weighted_score += score * weight
                details.append({
                    "category": category,
                    "criterion": criterion,
                    "description": info["description"],
                    "score": score,
                    "weight": weight,
                    "weighted": score * weight,
                })

        final_score = round(weighted_score / total_weight, 1) if total_weight > 0 else 0
        return {
            "platform": platform_name,
            "overall_score": final_score,
            "max_possible": 10,
            "total_weight": total_weight,
            "details": sorted(details, key=lambda x: x["weighted"], reverse=True),
            "evaluation_date": datetime.utcnow().isoformat() + "Z",
        }

    def compare_platforms(self, evaluations):
        """Compare multiple TIP platform evaluations side by side."""
        comparison = []
        for eval_result in evaluations:
            comparison.append({
                "platform": eval_result["platform"],
                "overall_score": eval_result["overall_score"],
            })
        comparison.sort(key=lambda x: x["overall_score"], reverse=True)
        return {"ranking": comparison, "count": len(comparison)}


def test_misp_api(misp_url, api_key, verify_ssl=False):
    """Test MISP API connectivity and basic operations."""
    ctx = ssl.create_default_context()
    if not verify_ssl:
        ctx.check_hostname = False
        ctx.verify_mode = ssl.CERT_NONE

    results = {}
    endpoints = {
        "version": "/servers/getVersion.json",
        "statistics": "/attributes/attributeStatistics/type/percentage.json",
        "feeds": "/feeds/index.json",
    }

    for name, path in endpoints.items():
        url = f"{misp_url.rstrip('/')}{path}"
        req = urllib.request.Request(url, headers={
            "Authorization": api_key,
            "Accept": "application/json",
        })
        try:
            with urllib.request.urlopen(req, context=ctx, timeout=15) as resp:
                results[name] = {
                    "status": resp.status,
                    "data": json.loads(resp.read().decode()),
                }
        except Exception as e:
            results[name] = {"status": "error", "message": str(e)}

    return {"platform": "MISP", "url": misp_url, "tests": results}


def test_opencti_api(opencti_url, api_token, verify_ssl=False):
    """Test OpenCTI GraphQL API connectivity."""
    ctx = ssl.create_default_context()
    if not verify_ssl:
        ctx.check_hostname = False
        ctx.verify_mode = ssl.CERT_NONE

    query = '{"query": "{ about { version } }"}'
    url = f"{opencti_url.rstrip('/')}/graphql"
    req = urllib.request.Request(
        url,
        data=query.encode(),
        headers={
            "Authorization": f"Bearer {api_token}",
            "Content-Type": "application/json",
        },
        method="POST",
    )
    try:
        with urllib.request.urlopen(req, context=ctx, timeout=15) as resp:
            return {
                "platform": "OpenCTI",
                "url": opencti_url,
                "status": resp.status,
                "data": json.loads(resp.read().decode()),
            }
    except Exception as e:
        return {"platform": "OpenCTI", "url": opencti_url, "status": "error", "message": str(e)}


def generate_evaluation_template():
    """Generate an evaluation scoring template for a TIP assessment."""
    evaluator = TIPEvaluator()
    template = {"instructions": "Score each criterion 0-10", "criteria": {}}
    for category, criteria in evaluator.EVALUATION_CRITERIA.items():
        template["criteria"][category] = {}
        for name, info in criteria.items():
            template["criteria"][category][name] = {
                "description": info["description"],
                "weight": info["weight"],
                "score": 0,
            }
    return template


def generate_comparison_report():
    """Generate a sample comparison report for common TIP platforms."""
    evaluator = TIPEvaluator()

    misp_scores = {
        "stix_support": 9, "taxii_server": 7, "rest_api": 9, "deduplication": 7,
        "tlp_enforcement": 9, "attack_mapping": 6, "graph_viz": 5,
        "siem_integration": 7, "edr_integration": 5, "soar_integration": 6,
        "firewall_integration": 7, "feed_ingestion": 9,
        "analyst_workflow": 5, "reporting": 5, "sharing": 10,
        "rbac": 6, "audit_logging": 5,
    }

    opencti_scores = {
        "stix_support": 10, "taxii_server": 9, "rest_api": 9, "deduplication": 8,
        "tlp_enforcement": 9, "attack_mapping": 10, "graph_viz": 10,
        "siem_integration": 7, "edr_integration": 6, "soar_integration": 7,
        "firewall_integration": 6, "feed_ingestion": 8,
        "analyst_workflow": 8, "reporting": 7, "sharing": 8,
        "rbac": 8, "audit_logging": 7,
    }

    threatconnect_scores = {
        "stix_support": 8, "taxii_server": 8, "rest_api": 9, "deduplication": 9,
        "tlp_enforcement": 8, "attack_mapping": 8, "graph_viz": 8,
        "siem_integration": 9, "edr_integration": 8, "soar_integration": 9,
        "firewall_integration": 8, "feed_ingestion": 9,
        "analyst_workflow": 9, "reporting": 9, "sharing": 7,
        "rbac": 9, "audit_logging": 9,
    }

    results = [
        evaluator.score_platform("MISP (Open Source)", misp_scores),
        evaluator.score_platform("OpenCTI (Open Source)", opencti_scores),
        evaluator.score_platform("ThreatConnect (Commercial)", threatconnect_scores),
    ]

    comparison = evaluator.compare_platforms(results)
    return {
        "timestamp": datetime.utcnow().isoformat() + "Z",
        "comparison": comparison,
        "detailed_evaluations": results,
    }


if __name__ == "__main__":
    import os
    action = sys.argv[1] if len(sys.argv) > 1 else "compare"
    if action == "compare":
        print(json.dumps(generate_comparison_report(), indent=2, default=str))
    elif action == "template":
        print(json.dumps(generate_evaluation_template(), indent=2))
    elif action == "test-misp":
        url = os.environ.get("MISP_URL", sys.argv[2] if len(sys.argv) > 2 else "")
        key = os.environ.get("MISP_KEY", sys.argv[3] if len(sys.argv) > 3 else "")
        if url and key:
            print(json.dumps(test_misp_api(url, key), indent=2, default=str))
        else:
            print("Set MISP_URL and MISP_KEY env vars or pass as arguments")
    elif action == "test-opencti":
        url = os.environ.get("OPENCTI_URL", sys.argv[2] if len(sys.argv) > 2 else "")
        token = os.environ.get("OPENCTI_TOKEN", sys.argv[3] if len(sys.argv) > 3 else "")
        if url and token:
            print(json.dumps(test_opencti_api(url, token), indent=2, default=str))
        else:
            print("Set OPENCTI_URL and OPENCTI_TOKEN env vars or pass as arguments")
    else:
        print("Usage: agent.py [compare|template|test-misp [url key]|test-opencti [url token]]")
Keep exploring