threat intelligence

Building Threat Intelligence Platform

Building a Threat Intelligence Platform (TIP) involves deploying and integrating multiple CTI tools into a unified system for collecting, analyzing, enriching, and disseminating threat intelligence. This skill covers designing TIP architecture using open-source tools (MISP, OpenCTI, TheHive, Cortex), configuring feed ingestion pipelines, establishing enrichment workflows, implementing STIX/TAXII interoperability, and building analyst dashboards for CTI operations.

ctiiocmispmitre-attackopenctiplatform-buildingstixthreat-intelligence
Install this skill
npx skills add mukul975/Anthropic-Cybersecurity-Skills
Framework mappings

Overview

Building a Threat Intelligence Platform (TIP) involves deploying and integrating multiple CTI tools into a unified system for collecting, analyzing, enriching, and disseminating threat intelligence. This skill covers designing TIP architecture using open-source tools (MISP, OpenCTI, TheHive, Cortex), configuring feed ingestion pipelines, establishing enrichment workflows, implementing STIX/TAXII interoperability, and building analyst dashboards for CTI operations.

When to Use

  • When deploying or configuring building threat intelligence platform capabilities in your environment
  • When establishing security controls aligned to compliance requirements
  • When building or improving security architecture for this domain
  • When conducting security assessments that require this implementation

Prerequisites

  • Docker and Docker Compose for deploying platform components
  • Python 3.9+ with pymisp, pycti, thehive4py libraries
  • Elasticsearch/OpenSearch cluster for data storage
  • Redis and RabbitMQ for message queuing
  • Understanding of STIX 2.1 data model and TAXII 2.1 transport
  • API keys for enrichment services (VirusTotal, Shodan, AbuseIPDB)

Key Concepts

TIP Architecture Components

  1. Collection Layer: Feed ingestion from OSINT, commercial, and internal sources
  2. Storage Layer: Elasticsearch/OpenSearch for indexed CTI data with STIX 2.1 schema
  3. Analysis Layer: OpenCTI for knowledge graph analysis and MISP for IOC correlation
  4. Enrichment Layer: Cortex analyzers for automated IOC enrichment
  5. Response Layer: TheHive for case management and incident response integration
  6. Sharing Layer: TAXII server for outbound intelligence sharing

Platform Integration Points

  • MISP <-> OpenCTI: Bidirectional sync via OpenCTI MISP connector
  • OpenCTI <-> TheHive: Alert/case creation from high-confidence indicators
  • TheHive <-> Cortex: Automated analysis and enrichment of case observables
  • All <-> SIEM: Real-time IOC push to Splunk/Elastic via API or Kafka

Workflow

Step 1: Deploy Platform with Docker Compose

version: '3.8'
services:
  # --- Storage Layer ---
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:8.12.0
    environment:
      - discovery.type=single-node
      - xpack.security.enabled=false
      - "ES_JAVA_OPTS=-Xms2g -Xmx2g"
    ports:
      - "9200:9200"
    volumes:
      - es-data:/usr/share/elasticsearch/data
 
  redis:
    image: redis:7
    ports:
      - "6379:6379"
 
  rabbitmq:
    image: rabbitmq:3-management
    ports:
      - "5672:5672"
      - "15672:15672"
 
  minio:
    image: minio/minio
    command: server /data --console-address ":9001"
    ports:
      - "9000:9000"
      - "9001:9001"
 
  # --- MISP ---
  misp:
    image: ghcr.io/misp/misp-docker/misp-core:latest
    ports:
      - "8443:443"
    environment:
      - MISP_ADMIN_EMAIL=admin@tip.local
      - MISP_BASEURL=https://localhost:8443
    volumes:
      - misp-data:/var/www/MISP/app/files
 
  # --- OpenCTI ---
  opencti:
    image: opencti/platform:6.4.4
    environment:
      - APP__PORT=8080
      - APP__ADMIN__EMAIL=admin@tip.local
      - APP__ADMIN__PASSWORD=TIPAdminPassword
      - APP__ADMIN__TOKEN=tip-opencti-token-uuid
      - ELASTICSEARCH__URL=http://elasticsearch:9200
      - MINIO__ENDPOINT=minio
      - RABBITMQ__HOSTNAME=rabbitmq
      - REDIS__HOSTNAME=redis
    ports:
      - "8080:8080"
    depends_on:
      - elasticsearch
      - redis
      - rabbitmq
      - minio
 
  # --- TheHive ---
  thehive:
    image: strangebee/thehive:5.3
    environment:
      - TH_CORTEX_URL=http://cortex:9001
    ports:
      - "9000:9000"
    depends_on:
      - elasticsearch
 
  # --- Cortex ---
  cortex:
    image: thehiveproject/cortex:3.1.8
    ports:
      - "9001:9001"
    depends_on:
      - elasticsearch
 
volumes:
  es-data:
  misp-data:

Step 2: Configure Feed Ingestion Pipeline

from pymisp import PyMISP
from pycti import OpenCTIApiClient
import json
 
class TIPFeedManager:
    """Manage threat intelligence feed ingestion across platform components."""
 
    def __init__(self, misp_url, misp_key, opencti_url, opencti_token):
        self.misp = PyMISP(misp_url, misp_key, ssl=False)
        self.opencti = OpenCTIApiClient(opencti_url, opencti_token)
 
    def configure_osint_feeds(self):
        """Enable default OSINT feeds in MISP."""
        osint_feeds = [
            {"name": "CIRCL OSINT", "id": 1},
            {"name": "Botvrij.eu", "id": 2},
            {"name": "abuse.ch URLhaus", "id": 5},
            {"name": "abuse.ch Feodo Tracker", "id": 6},
        ]
        for feed in osint_feeds:
            try:
                self.misp.enable_feed(feed["id"])
                self.misp.fetch_feed(feed["id"])
                print(f"[+] Enabled feed: {feed['name']}")
            except Exception as e:
                print(f"[-] Failed: {feed['name']}: {e}")
 
    def configure_opencti_connectors(self):
        """List and verify OpenCTI connector status."""
        connectors = self.opencti.connector.list()
        for conn in connectors:
            print(
                f"  Connector: {conn['name']} - "
                f"Active: {conn['active']} - "
                f"Type: {conn['connector_type']}"
            )
 
    def sync_misp_to_opencti(self):
        """Verify MISP-OpenCTI sync is operational."""
        # OpenCTI MISP connector handles this automatically
        # Check connector status
        connectors = self.opencti.connector.list()
        misp_connector = [
            c for c in connectors if "misp" in c["name"].lower()
        ]
        if misp_connector:
            print(f"[+] MISP connector active: {misp_connector[0]['active']}")
        else:
            print("[-] MISP connector not found - configure in Docker Compose")

Step 3: Build Enrichment Pipeline with Cortex

import requests
 
class CortexEnrichment:
    """Integrate Cortex analyzers for automated enrichment."""
 
    def __init__(self, cortex_url, cortex_key):
        self.url = cortex_url
        self.headers = {"Authorization": f"Bearer {cortex_key}"}
 
    def list_analyzers(self):
        """List available Cortex analyzers."""
        resp = requests.get(
            f"{self.url}/api/analyzer",
            headers=self.headers,
            timeout=30,
        )
        if resp.status_code == 200:
            analyzers = resp.json()
            for a in analyzers:
                print(f"  {a['name']}: {a.get('description', '')[:60]}")
            return analyzers
        return []
 
    def analyze_observable(self, observable_type, observable_value, analyzer_id):
        """Submit an observable for analysis."""
        job = {
            "data": observable_value,
            "dataType": observable_type,
            "tlp": 2,
            "message": "TIP automated enrichment",
        }
        resp = requests.post(
            f"{self.url}/api/analyzer/{analyzer_id}/run",
            json=job,
            headers=self.headers,
            timeout=30,
        )
        if resp.status_code == 200:
            return resp.json()
        return None
 
    def get_job_report(self, job_id):
        """Get the report for a completed analysis job."""
        resp = requests.get(
            f"{self.url}/api/job/{job_id}/report",
            headers=self.headers,
            timeout=60,
        )
        if resp.status_code == 200:
            return resp.json()
        return None

Step 4: Implement Analyst Dashboard Metrics

class TIPMetrics:
    """Collect platform metrics for analyst dashboards."""
 
    def __init__(self, misp, opencti):
        self.misp = misp
        self.opencti = opencti
 
    def get_platform_stats(self):
        """Collect statistics across all platform components."""
        stats = {}
 
        # MISP stats
        misp_stats = self.misp.get_server_statistics()
        stats["misp"] = {
            "total_events": misp_stats.get("event_count", 0),
            "total_attributes": misp_stats.get("attribute_count", 0),
            "active_feeds": len([
                f for f in self.misp.feeds()
                if f.get("Feed", {}).get("enabled")
            ]),
        }
 
        # OpenCTI stats via GraphQL
        stats["opencti"] = {
            "total_indicators": self.opencti.indicator.list(
                first=0, withPagination=True
            ).get("pagination", {}).get("globalCount", 0),
            "total_reports": self.opencti.report.list(
                first=0, withPagination=True
            ).get("pagination", {}).get("globalCount", 0),
        }
 
        return stats

Validation Criteria

  • All platform components (MISP, OpenCTI, TheHive, Cortex) deployed and accessible
  • MISP-OpenCTI bidirectional sync operational
  • At least 3 OSINT feeds ingesting data
  • Cortex analyzers configured and returning enrichment results
  • Platform metrics dashboard showing real-time statistics
  • STIX/TAXII export functional for intelligence sharing

References

Source materials

References and resources

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

References 3

api-reference.md1.9 KB

API Reference: Threat Intelligence Platform

STIX 2.1 Indicator Object

{
  "type": "indicator",
  "spec_version": "2.1",
  "id": "indicator--<uuid5>",
  "created": "2025-01-15T10:00:00.000Z",
  "modified": "2025-01-15T10:00:00.000Z",
  "name": "Malicious IP",
  "pattern": "[ipv4-addr:value = '198.51.100.42']",
  "pattern_type": "stix",
  "valid_from": "2025-01-15T10:00:00.000Z",
  "confidence": 85,
  "object_marking_refs": ["marking-definition--f88d31f6-486f-44da-b317-01333bde0b82"]
}

TLP Marking Definition IDs (STIX 2.1)

TLP Level STIX Marking Definition ID
TLP:CLEAR marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9
TLP:GREEN marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da
TLP:AMBER marking-definition--f88d31f6-486f-44da-b317-01333bde0b82
TLP:AMBER+STRICT marking-definition--826578e1-40a3-4b46-a8d8-b9931fdd750e
TLP:RED marking-definition--5e57c739-391a-4eb3-b6be-7d15ca92d5ed

TAXII 2.1 Endpoints

# Discovery
curl https://taxii.server.com/taxii2/
 
# Collections
curl https://taxii.server.com/taxii2/collections/
 
# Get objects from collection
curl "https://taxii.server.com/taxii2/collections/{id}/objects?type=indicator"
 
# Add objects
curl -X POST "https://taxii.server.com/taxii2/collections/{id}/objects" \
  -H "Content-Type: application/stix+json;version=2.1" \
  -d @bundle.json

OpenCTI GraphQL API

mutation {
  indicatorAdd(input: {
    name: "Malicious IP"
    pattern: "[ipv4-addr:value = '198.51.100.42']"
    pattern_type: "stix"
    x_opencti_score: 80
  }) {
    id
    standard_id
  }
}

MISP REST API

# Add attribute
curl -X POST "https://misp/attributes/add/EVENT_ID" \
  -H "Authorization: MISP_KEY" \
  -H "Content-Type: application/json" \
  -d '{"type":"ip-dst","value":"198.51.100.42","category":"Network activity","to_ids":true}'
standards.md1.2 KB

Standards and Frameworks Reference

TIP Architecture Standards

  • STIX 2.1: Native data model for CTI representation
  • TAXII 2.1: Transport protocol for CTI sharing
  • MITRE ATT&CK: Technique taxonomy for TTP mapping
  • Diamond Model: Intrusion analysis framework
  • Kill Chain: Lockheed Martin Cyber Kill Chain for attack phase tracking

Platform Component Standards

Component Protocol Data Format
MISP REST API MISP JSON, STIX 2.1
OpenCTI GraphQL API STIX 2.1
TheHive REST API TheHive JSON
Cortex REST API Cortex Report JSON
Elasticsearch REST API JSON

Integration Standards

  • MISP Sync Protocol: Push/Pull over HTTPS with API key auth
  • OpenCTI Connectors: RabbitMQ-based message queue for async processing
  • Cortex Analyzers: Docker-based analyzers with standardized I/O
  • SIEM Integration: Syslog, Kafka, REST API, or file-based export

References

workflows.md1.5 KB

TIP Architecture Workflows

Workflow 1: End-to-End Intelligence Pipeline

[External Feeds] --> [MISP] --> [OpenCTI] --> [Enrichment (Cortex)] --> [SIEM/TheHive]
    |                   |            |                |                       |
    v                   v            v                v                       v
OSINT/Commercial   Correlate    Knowledge Graph   VT/Shodan/AIPDB    Alerts/Cases

Workflow 2: Incident-to-Intelligence Feedback Loop

[SOC Alert] --> [TheHive Case] --> [Cortex Analysis] --> [IOC Extraction]
                                                               |
                                                               v
                                                    [MISP Event Creation]
                                                               |
                                                               v
                                                    [OpenCTI Knowledge Update]
                                                               |
                                                               v
                                                    [Updated Detections --> SIEM]

Workflow 3: Platform Health Monitoring

[Prometheus/Grafana] --> [Component Health] --> [Feed Status] --> [Alert on Failure]
                              |                      |
                              v                      v
                     [ES Cluster Health]    [Connector Status]

Scripts 2

agent.py5.7 KB
Display-only source. This catalog never executes bundled scripts.
#!/usr/bin/env python3
"""Threat intelligence platform builder.

Core TIP components: STIX/TAXII ingestion, indicator lifecycle management,
confidence scoring, sharing groups, and intelligence dissemination.
"""

import json
import datetime
import re
import uuid


STIX_INDICATOR_TYPES = {
    "ipv4-addr": "[ipv4-addr:value = '{}']",
    "domain-name": "[domain-name:value = '{}']",
    "url": "[url:value = '{}']",
    "file-sha256": "[file:hashes.'SHA-256' = '{}']",
    "file-md5": "[file:hashes.MD5 = '{}']",
    "email-addr": "[email-addr:value = '{}']",
}

TLP_DEFINITIONS = {
    "TLP:CLEAR": {"color": "white", "sharing": "Unlimited", "code": 0},
    "TLP:GREEN": {"color": "green", "sharing": "Community", "code": 1},
    "TLP:AMBER": {"color": "amber", "sharing": "Organization", "code": 2},
    "TLP:AMBER+STRICT": {"color": "amber", "sharing": "Need-to-know only", "code": 3},
    "TLP:RED": {"color": "red", "sharing": "Named recipients only", "code": 4},
}


def classify_indicator(value):
    """Classify indicator type from raw value."""
    if re.match(r"^[0-9]{1,3}(\\.[0-9]{1,3}){3}$", value):
        return "ipv4-addr"
    if re.match(r"^[a-fA-F0-9]{64}$", value):
        return "file-sha256"
    if re.match(r"^[a-fA-F0-9]{32}$", value):
        return "file-md5"
    if re.match(r"^[a-zA-Z0-9][a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$", value):
        return "domain-name"
    if value.startswith("http://") or value.startswith("https://"):
        return "url"
    if "@" in value:
        return "email-addr"
    return "unknown"


def create_stix_indicator(value, indicator_type=None, confidence=50, tlp="TLP:AMBER"):
    """Create a STIX 2.1 Indicator object."""
    if not indicator_type:
        indicator_type = classify_indicator(value)
    pattern_template = STIX_INDICATOR_TYPES.get(indicator_type)
    if not pattern_template:
        return {"error": "Unsupported indicator type: " + indicator_type}

    now = datetime.datetime.utcnow().isoformat(timespec="milliseconds") + "Z"
    indicator_id = "indicator--" + str(uuid.uuid5(uuid.NAMESPACE_URL, value))

    indicator = {
        "type": "indicator",
        "spec_version": "2.1",
        "id": indicator_id,
        "created": now,
        "modified": now,
        "name": "{}: {}".format(indicator_type, value),
        "pattern": pattern_template.format(value),
        "pattern_type": "stix",
        "valid_from": now,
        "confidence": confidence,
        "labels": ["malicious-activity"],
        "object_marking_refs": [tlp_to_marking_ref(tlp)],
    }
    return indicator


def tlp_to_marking_ref(tlp):
    """Convert TLP label to STIX marking definition ID."""
    tlp_refs = {
        "TLP:CLEAR": "marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9",
        "TLP:GREEN": "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da",
        "TLP:AMBER": "marking-definition--f88d31f6-486f-44da-b317-01333bde0b82",
        "TLP:AMBER+STRICT": "marking-definition--826578e1-40a3-4b46-a8d8-b9931fdd750e",
        "TLP:RED": "marking-definition--5e57c739-391a-4eb3-b6be-7d15ca92d5ed",
    }
    return tlp_refs.get(tlp, tlp_refs["TLP:AMBER"])


def calculate_indicator_score(sources_count, age_days, confirmed_sightings, false_positives):
    """Calculate indicator confidence score (0-100)."""
    source_score = min(sources_count * 15, 40)
    age_penalty = min(age_days * 0.5, 30)
    sighting_score = min(confirmed_sightings * 10, 30)
    fp_penalty = min(false_positives * 15, 30)
    score = source_score - age_penalty + sighting_score - fp_penalty
    return max(0, min(100, round(score)))


def build_stix_bundle(indicators):
    """Build STIX 2.1 Bundle from list of indicators."""
    bundle = {
        "type": "bundle",
        "id": "bundle--" + str(uuid.uuid4()),
        "objects": indicators,
    }
    return bundle


def generate_tip_report(indicators, platform_name="Internal TIP"):
    """Generate TIP status report."""
    type_counts = {}
    for ind in indicators:
        itype = ind.get("name", "").split(":")[0] if ":" in ind.get("name", "") else "unknown"
        type_counts[itype] = type_counts.get(itype, 0) + 1

    return {
        "platform": platform_name,
        "generated_at": datetime.datetime.utcnow().isoformat() + "Z",
        "total_indicators": len(indicators),
        "type_breakdown": type_counts,
        "avg_confidence": round(
            sum(i.get("confidence", 0) for i in indicators) / max(len(indicators), 1), 1
        ),
    }


if __name__ == "__main__":
    print("=" * 60)
    print("Threat Intelligence Platform Builder")
    print("STIX 2.1 indicators, scoring, TLP marking, bundle export")
    print("=" * 60)

    demo_values = [
        "198.51.100.42",
        "evil-domain.example.com",
        "a" * 64,
        "https://evil.example.com/payload.exe",
        "attacker@evil.example.com",
    ]

    indicators = []
    for val in demo_values:
        ind = create_stix_indicator(val, confidence=75, tlp="TLP:AMBER")
        if "error" not in ind:
            indicators.append(ind)

    print("\n--- Indicators Created ---")
    for ind in indicators:
        print("  {} [confidence={}]".format(ind["name"], ind["confidence"]))
        print("    Pattern: {}".format(ind["pattern"]))

    bundle = build_stix_bundle(indicators)
    print("\nSTIX Bundle: {} ({} objects)".format(bundle["id"], len(bundle["objects"])))

    score = calculate_indicator_score(sources_count=3, age_days=5, confirmed_sightings=2, false_positives=0)
    print("\nSample score calculation: {}".format(score))

    report = generate_tip_report(indicators)
    print("\n--- Platform Report ---")
    for k, v in report.items():
        print("  {}: {}".format(k, v))

    print("\n" + json.dumps({"indicators_created": len(indicators)}, indent=2))
process.py6.2 KB
Display-only source. This catalog never executes bundled scripts.
#!/usr/bin/env python3
"""
Threat Intelligence Platform Management Script

Manages a multi-component TIP deployment:
- Checks platform component health
- Configures feed ingestion across MISP and OpenCTI
- Runs enrichment pipelines via Cortex analyzers
- Generates platform metrics and dashboards

Requirements:
    pip install pymisp pycti requests

Usage:
    python process.py --check-health --misp-url URL --misp-key KEY --opencti-url URL --opencti-token TOKEN
    python process.py --configure-feeds --misp-url URL --misp-key KEY
    python process.py --platform-stats --misp-url URL --misp-key KEY --opencti-url URL --opencti-token TOKEN
"""

import argparse
import json
import sys
from datetime import datetime

import requests

try:
    from pymisp import PyMISP
except ImportError:
    PyMISP = None

try:
    from pycti import OpenCTIApiClient
except ImportError:
    OpenCTIApiClient = None


class TIPManager:
    """Manage Threat Intelligence Platform operations."""

    def __init__(self, misp_url="", misp_key="", opencti_url="", opencti_token="",
                 thehive_url="", thehive_key="", cortex_url="", cortex_key=""):
        self.misp = PyMISP(misp_url, misp_key, ssl=False) if PyMISP and misp_url else None
        self.opencti = (
            OpenCTIApiClient(opencti_url, opencti_token)
            if OpenCTIApiClient and opencti_url else None
        )
        self.thehive_url = thehive_url
        self.thehive_key = thehive_key
        self.cortex_url = cortex_url
        self.cortex_key = cortex_key

    def check_health(self) -> dict:
        """Check health of all platform components."""
        health = {}

        if self.misp:
            try:
                version = self.misp.misp_instance_version
                health["misp"] = {"status": "healthy", "version": str(version)}
            except Exception as e:
                health["misp"] = {"status": "unhealthy", "error": str(e)}

        if self.opencti:
            try:
                about = self.opencti.health.check()
                health["opencti"] = {"status": "healthy"}
            except Exception as e:
                health["opencti"] = {"status": "unhealthy", "error": str(e)}

        if self.thehive_url:
            try:
                resp = requests.get(
                    f"{self.thehive_url}/api/status",
                    headers={"Authorization": f"Bearer {self.thehive_key}"},
                    timeout=10,
                )
                health["thehive"] = {
                    "status": "healthy" if resp.status_code == 200 else "unhealthy"
                }
            except Exception as e:
                health["thehive"] = {"status": "unreachable", "error": str(e)}

        if self.cortex_url:
            try:
                resp = requests.get(
                    f"{self.cortex_url}/api/status",
                    headers={"Authorization": f"Bearer {self.cortex_key}"},
                    timeout=10,
                )
                health["cortex"] = {
                    "status": "healthy" if resp.status_code == 200 else "unhealthy"
                }
            except Exception as e:
                health["cortex"] = {"status": "unreachable", "error": str(e)}

        return health

    def configure_feeds(self) -> dict:
        """Configure default OSINT feeds in MISP."""
        if not self.misp:
            return {"error": "MISP not configured"}

        feeds = self.misp.feeds()
        enabled = []
        for feed in feeds:
            feed_info = feed.get("Feed", {})
            if not feed_info.get("enabled"):
                try:
                    self.misp.enable_feed(feed_info["id"])
                    enabled.append(feed_info["name"])
                except Exception:
                    pass

        return {"enabled_feeds": enabled, "total_feeds": len(feeds)}

    def get_platform_stats(self) -> dict:
        """Collect statistics from all platform components."""
        stats = {"timestamp": datetime.utcnow().isoformat()}

        if self.misp:
            try:
                server_stats = self.misp.get_server_statistics()
                feeds = self.misp.feeds()
                stats["misp"] = {
                    "events": server_stats.get("event_count", 0),
                    "attributes": server_stats.get("attribute_count", 0),
                    "active_feeds": len([
                        f for f in feeds if f.get("Feed", {}).get("enabled")
                    ]),
                    "organizations": server_stats.get("org_count", 0),
                }
            except Exception as e:
                stats["misp"] = {"error": str(e)}

        if self.opencti:
            try:
                connectors = self.opencti.connector.list()
                stats["opencti"] = {
                    "active_connectors": len([
                        c for c in connectors if c.get("active")
                    ]),
                    "total_connectors": len(connectors),
                }
            except Exception as e:
                stats["opencti"] = {"error": str(e)}

        return stats


def main():
    parser = argparse.ArgumentParser(description="TIP Management Tool")
    parser.add_argument("--misp-url", default="", help="MISP URL")
    parser.add_argument("--misp-key", default="", help="MISP API key")
    parser.add_argument("--opencti-url", default="", help="OpenCTI URL")
    parser.add_argument("--opencti-token", default="", help="OpenCTI token")
    parser.add_argument("--check-health", action="store_true")
    parser.add_argument("--configure-feeds", action="store_true")
    parser.add_argument("--platform-stats", action="store_true")
    parser.add_argument("--output", default="tip_report.json", help="Output file")

    args = parser.parse_args()
    manager = TIPManager(args.misp_url, args.misp_key, args.opencti_url, args.opencti_token)

    result = {}
    if args.check_health:
        result = manager.check_health()
    elif args.configure_feeds:
        result = manager.configure_feeds()
    elif args.platform_stats:
        result = manager.get_platform_stats()

    print(json.dumps(result, indent=2, default=str))
    with open(args.output, "w") as f:
        json.dump(result, f, indent=2, default=str)


if __name__ == "__main__":
    main()

Assets 1

template.mdtext/markdown · 1.0 KB
Keep exploring