[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M7B5A90FAQCSM2CAE1SPEV22":3,"skill-same:01M7B5A90FAQCSM2CAE1SPEV22":81},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":15,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":19,"linkOnly":20,"markdownContent":21,"markdownBody":22,"frontMatter":23,"refName":45,"commitSha":46,"skillDirectory":47,"forksCount":13,"repositoryHtmlUrl":48,"repositoryHomepageUrl":6,"ownerHtmlUrl":49,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":50,"install":51,"resources":64},"01M7B5A90FAQCSM2CAE1SPEV22","building-threat-feed-aggregation-with-misp",null,"Deploy MISP via Docker and configure feeds from sources like abuse.ch, AlienVault OTX, and CIRCL to aggregate, correlate, and distribute threat intelligence, including automated feed synchronization and STIX\u002FTAXII-based integration with Splunk, Elasticsearch, and SOAR platforms. Use when standing up centralized IOC management or wiring multi-source threat feeds into a SIEM.","vikasvardhanv\u002Fjerry_skills","vikasvardhanv","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F99010657?v=4","01M7B2B0VN78W7529RQX5BR6DZ","01M7B2B0WDNTXJHRK3QNPNWRP6",0,"Apache-2.0","https:\u002F\u002Fgithub.com\u002Fvikasvardhanv\u002Fjerry_skills\u002Fblob\u002Fmain\u002Fskills\u002Fcurated_premium_skills\u002FAnthropic-Cybersecurity-Skills\u002Fskills\u002Fbuilding-threat-feed-aggregation-with-misp\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fvikasvardhanv\u002Fjerry_skills\u002Fblob\u002Fmain\u002Fskills\u002Fcurated_premium_skills\u002FAnthropic-Cybersecurity-Skills\u002Fskills\u002Fbuilding-threat-feed-aggregation-with-misp\u002FSKILL.md",[],[],"2026-11-15 14:19:17",false,"---\nname: building-threat-feed-aggregation-with-misp\ndescription: Deploy MISP via Docker and configure feeds from sources like abuse.ch, AlienVault OTX, and CIRCL to aggregate, correlate, and distribute threat intelligence, including automated feed synchronization and STIX\u002FTAXII-based integration with Splunk, Elasticsearch, and SOAR platforms. Use when standing up centralized IOC management or wiring multi-source threat feeds into a SIEM.\ndomain: cybersecurity\nsubdomain: threat-intelligence\ntags:\n- misp\n- threat-feed\n- aggregation\n- indicator\n- sharing\n- correlation\n- siem-integration\n- threat-intelligence\nversion: '1.0'\nauthor: mahipal\nlicense: Apache-2.0\nnist_csf:\n- ID.RA-01\n- ID.RA-05\n- DE.CM-01\n- DE.AE-02\nmitre_attack:\n- T1071\n- T1105\n- T1588.001\n---\n# Building Threat Feed Aggregation with MISP\n\n## Overview\n\nMISP is the leading open-source threat intelligence platform for collecting, storing, distributing, and sharing cybersecurity indicators and threat intelligence. It aggregates feeds from OSINT sources, commercial providers, and sharing communities into a unified platform with automatic correlation, STIX\u002FTAXII export, and direct integration with SIEMs and security tools. This skill covers deploying MISP via Docker, configuring feeds from sources like abuse.ch, AlienVault OTX, and CIRCL, setting up automated feed synchronization, and integrating with Splunk, Elasticsearch, and SOAR platforms.\n\n\n## When to Use\n\n- When deploying or configuring building threat feed aggregation with misp capabilities in your environment\n- When establishing security controls aligned to compliance requirements\n- When building or improving security architecture for this domain\n- When conducting security assessments that require this implementation\n\n## Prerequisites\n\n- Docker and Docker Compose for deployment\n- Python 3.9+ with `pymisp` library for API interaction\n- Linux server with 8GB+ RAM for production deployment\n- Understanding of IOC types and threat intelligence lifecycle\n- Network access to external feed URLs\n\n## Key Concepts\n\n### MISP Architecture\n\nMISP stores threat intelligence as Events containing Attributes (IOCs) organized by type and category. Events can have Tags (MITRE ATT&CK, TLP marking, sector tags), Galaxies (threat actor profiles, malware families, attack patterns), and Objects (structured groupings of related attributes). Events are correlated automatically across the instance.\n\n### Feed Types\n\nMISP supports three feed formats: MISP format (native JSON events), CSV (comma-separated IOCs), and freetext (unstructured text with automatic IOC extraction). Feeds can be remote (fetched from URLs) or local (uploaded files). MISP ships with 80+ default OSINT feeds including abuse.ch URLhaus, Botvrij, CIRCL OSINT, and malware traffic analysis.\n\n### Sharing and Synchronization\n\nMISP instances can synchronize with other MISP instances via push\u002Fpull mechanisms. Sharing groups control distribution (organization only, this community, connected communities, all communities). The TAXII server module enables integration with STIX\u002FTAXII consumers.\n\n## Workflow\n\n### Step 1: Deploy MISP with Docker\n\n```yaml\n# docker-compose.yml for MISP deployment\nversion: '3.8'\nservices:\n  misp:\n    image: coolacid\u002Fmisp-docker:core-latest\n    container_name: misp\n    restart: unless-stopped\n    ports:\n      - \"443:443\"\n      - \"80:80\"\n    environment:\n      - MYSQL_HOST=misp-db\n      - MYSQL_DATABASE=misp\n      - MYSQL_USER=misp\n      - MYSQL_PASSWORD=misp_db_password_change_me\n      - MISP_ADMIN_EMAIL=admin@organization.com\n      - MISP_ADMIN_PASSPHRASE=admin_password_change_me\n      - MISP_BASEURL=https:\u002F\u002Fmisp.organization.com\n      - POSTFIX_RELAY_HOST=smtp.organization.com\n      - TIMEZONE=UTC\n    volumes:\n      - misp-data:\u002Fvar\u002Fwww\u002FMISP\u002Fapp\u002Ffiles\n      - misp-config:\u002Fvar\u002Fwww\u002FMISP\u002Fapp\u002FConfig\n    depends_on:\n      - misp-db\n      - misp-redis\n\n  misp-db:\n    image: mysql:8.0\n    container_name: misp-db\n    restart: unless-stopped\n    environment:\n      - MYSQL_DATABASE=misp\n      - MYSQL_USER=misp\n      - MYSQL_PASSWORD=misp_db_password_change_me\n      - MYSQL_ROOT_PASSWORD=root_password_change_me\n    volumes:\n      - misp-db-data:\u002Fvar\u002Flib\u002Fmysql\n\n  misp-redis:\n    image: redis:7\n    container_name: misp-redis\n    restart: unless-stopped\n\nvolumes:\n  misp-data:\n  misp-config:\n  misp-db-data:\n```\n\n### Step 2: Configure Feeds via PyMISP API\n\n```python\nfrom pymisp import PyMISP, MISPFeed\nimport json\n\nclass MISPFeedManager:\n    def __init__(self, misp_url, misp_key, verify_ssl=False):\n        self.misp = PyMISP(misp_url, misp_key, verify_ssl)\n        print(f\"[+] Connected to MISP: {misp_url}\")\n\n    def list_feeds(self):\n        \"\"\"List all configured feeds.\"\"\"\n        feeds = self.misp.feeds()\n        enabled = [f for f in feeds if f.get(\"Feed\", {}).get(\"enabled\")]\n        disabled = [f for f in feeds if not f.get(\"Feed\", {}).get(\"enabled\")]\n        print(f\"[+] Feeds: {len(enabled)} enabled, {len(disabled)} disabled\")\n        return feeds\n\n    def enable_default_feeds(self):\n        \"\"\"Enable recommended default OSINT feeds.\"\"\"\n        recommended_feeds = [\n            \"CIRCL OSINT Feed\",\n            \"Botvrij.eu - Indicators of Compromise\",\n            \"abuse.ch URLhaus Host file\",\n            \"abuse.ch Feodo Tracker\",\n            \"abuse.ch SSL Blacklist\",\n            \"malwaredomainlist\",\n            \"CyberCure - IP Feed\",\n        ]\n\n        feeds = self.misp.feeds()\n        enabled_count = 0\n        for feed in feeds:\n            feed_data = feed.get(\"Feed\", {})\n            if feed_data.get(\"name\") in recommended_feeds:\n                if not feed_data.get(\"enabled\"):\n                    self.misp.enable_feed(feed_data[\"id\"])\n                    self.misp.enable_feed_cache(feed_data[\"id\"])\n                    enabled_count += 1\n                    print(f\"  [+] Enabled: {feed_data['name']}\")\n\n        print(f\"[+] Enabled {enabled_count} feeds\")\n\n    def add_custom_feed(self, name, url, provider, feed_format=\"csv\",\n                        input_source=\"network\", enabled=True):\n        \"\"\"Add a custom threat intelligence feed.\"\"\"\n        feed = MISPFeed()\n        feed.name = name\n        feed.provider = provider\n        feed.url = url\n        feed.source_format = feed_format\n        feed.input_source = input_source\n        feed.enabled = enabled\n        feed.caching_enabled = True\n        feed.publish = False\n        feed.distribution = \"3\"  # All communities\n\n        result = self.misp.add_feed(feed)\n        if \"Feed\" in result:\n            feed_id = result[\"Feed\"][\"id\"]\n            print(f\"[+] Added feed: {name} (ID: {feed_id})\")\n            return feed_id\n        else:\n            print(f\"[-] Error adding feed: {result}\")\n            return None\n\n    def fetch_all_feeds(self):\n        \"\"\"Trigger fetch for all enabled feeds.\"\"\"\n        feeds = self.misp.feeds()\n        for feed in feeds:\n            feed_data = feed.get(\"Feed\", {})\n            if feed_data.get(\"enabled\"):\n                self.misp.fetch_feed(feed_data[\"id\"])\n                print(f\"  [*] Fetching: {feed_data['name']}\")\n        print(\"[+] Feed fetch triggered for all enabled feeds\")\n\nmanager = MISPFeedManager(\n    \"https:\u002F\u002Fmisp.organization.com\",\n    \"YOUR_MISP_API_KEY\",\n)\nmanager.enable_default_feeds()\nmanager.add_custom_feed(\n    name=\"Abuse.ch MalwareBazaar Recent\",\n    url=\"https:\u002F\u002Fbazaar.abuse.ch\u002Fexport\u002Fcsv\u002Frecent\u002F\",\n    provider=\"abuse.ch\",\n    feed_format=\"csv\",\n)\nmanager.fetch_all_feeds()\n```\n\n### Step 3: Search and Correlate Indicators\n\n```python\ndef search_indicators(misp, value=None, type_attribute=None, tags=None, last_days=30):\n    \"\"\"Search MISP for indicators with correlation.\"\"\"\n    from datetime import datetime, timedelta\n    date_from = (datetime.now() - timedelta(days=last_days)).strftime(\"%Y-%m-%d\")\n\n    search_params = {\n        \"date_from\": date_from,\n        \"published\": True,\n        \"enforceWarninglist\": True,\n    }\n    if value:\n        search_params[\"value\"] = value\n    if type_attribute:\n        search_params[\"type_attribute\"] = type_attribute\n    if tags:\n        search_params[\"tags\"] = tags\n\n    results = misp.search(\"attributes\", **search_params)\n    attributes = results.get(\"Attribute\", [])\n    print(f\"[+] Search returned {len(attributes)} attributes\")\n\n    # Group by event for context\n    events = {}\n    for attr in attributes:\n        event_id = attr.get(\"event_id\", \"\")\n        if event_id not in events:\n            events[event_id] = {\"attributes\": [], \"tags\": set()}\n        events[event_id][\"attributes\"].append({\n            \"type\": attr.get(\"type\", \"\"),\n            \"value\": attr.get(\"value\", \"\"),\n            \"category\": attr.get(\"category\", \"\"),\n            \"timestamp\": attr.get(\"timestamp\", \"\"),\n        })\n        for tag in attr.get(\"Tag\", []):\n            events[event_id][\"tags\"].add(tag.get(\"name\", \"\"))\n\n    return {\"attributes\": attributes, \"events\": events}\n\n# Search for specific IOC\nmisp = manager.misp\nresults = search_indicators(misp, value=\"203.0.113.1\")\nresults_by_type = search_indicators(misp, type_attribute=\"ip-dst\", last_days=7)\nresults_by_tag = search_indicators(misp, tags=[\"tlp:white\", \"type:OSINT\"])\n```\n\n### Step 4: Export to SIEM (Splunk \u002F Elasticsearch)\n\n```python\nimport requests\nfrom datetime import datetime, timedelta\n\nclass MISPSIEMExporter:\n    def __init__(self, misp_client):\n        self.misp = misp_client\n\n    def export_to_splunk(self, splunk_url, hec_token, days=7):\n        \"\"\"Export recent MISP indicators to Splunk via HEC.\"\"\"\n        date_from = (datetime.now() - timedelta(days=days)).strftime(\"%Y-%m-%d\")\n        results = self.misp.search(\"attributes\", date_from=date_from,\n                                    published=True, enforceWarninglist=True)\n        attributes = results.get(\"Attribute\", [])\n\n        headers = {\"Authorization\": f\"Splunk {hec_token}\"}\n        exported = 0\n        for attr in attributes:\n            event = {\n                \"event\": {\n                    \"ioc_type\": attr.get(\"type\", \"\"),\n                    \"ioc_value\": attr.get(\"value\", \"\"),\n                    \"category\": attr.get(\"category\", \"\"),\n                    \"event_id\": attr.get(\"event_id\", \"\"),\n                    \"timestamp\": attr.get(\"timestamp\", \"\"),\n                    \"tags\": [t.get(\"name\", \"\") for t in attr.get(\"Tag\", [])],\n                },\n                \"sourcetype\": \"misp:attribute\",\n                \"source\": \"misp\",\n                \"index\": \"threat_intel\",\n            }\n            resp = requests.post(\n                f\"{splunk_url}\u002Fservices\u002Fcollector\u002Fevent\",\n                headers=headers, json=event,\n                verify=not os.environ.get(\"SKIP_TLS_VERIFY\", \"\").lower() == \"true\",  # Set SKIP_TLS_VERIFY=true for self-signed certs in lab environments\n            )\n            if resp.status_code == 200:\n                exported += 1\n\n        print(f\"[+] Exported {exported}\u002F{len(attributes)} indicators to Splunk\")\n\n    def export_ioc_list(self, output_file, ioc_types=None, days=30):\n        \"\"\"Export flat IOC list for firewall\u002Fproxy blocklists.\"\"\"\n        ioc_types = ioc_types or [\"ip-dst\", \"domain\", \"hostname\", \"url\"]\n        date_from = (datetime.now() - timedelta(days=days)).strftime(\"%Y-%m-%d\")\n\n        all_iocs = []\n        for ioc_type in ioc_types:\n            results = self.misp.search(\n                \"attributes\", type_attribute=ioc_type,\n                date_from=date_from, published=True,\n                enforceWarninglist=True,\n            )\n            for attr in results.get(\"Attribute\", []):\n                all_iocs.append(attr.get(\"value\", \"\"))\n\n        unique_iocs = sorted(set(all_iocs))\n        with open(output_file, \"w\") as f:\n            for ioc in unique_iocs:\n                f.write(f\"{ioc}\\n\")\n\n        print(f\"[+] Exported {len(unique_iocs)} unique IOCs to {output_file}\")\n\nexporter = MISPSIEMExporter(misp)\nexporter.export_ioc_list(\"blocklist_ips.txt\", ioc_types=[\"ip-dst\"], days=7)\n```\n\n## Validation Criteria\n\n- MISP deployed and accessible via web interface and API\n- Default OSINT feeds enabled and fetching data\n- Custom feeds added and ingesting indicators\n- Indicators searchable with correlation across events\n- IOCs exported to SIEM (Splunk\u002FElasticsearch) successfully\n- Blocklists generated for firewall\u002Fproxy integration\n\n## References\n\n- [MISP Project](https:\u002F\u002Fwww.misp-project.org\u002F)\n- [MISP GitHub Repository](https:\u002F\u002Fgithub.com\u002FMISP\u002FMISP)\n- [MISP Default Feeds](https:\u002F\u002Fwww.misp-project.org\u002Ffeeds\u002F)\n- [PyMISP Documentation](https:\u002F\u002Fpymisp.readthedocs.io\u002F)\n- [Kraven Security: MISP Using Feeds](https:\u002F\u002Fkravensecurity.com\u002Fthreat-intelligence-with-misp-part-4-using-feeds\u002F)\n- [Cosive: What is MISP](https:\u002F\u002Fwww.cosive.com\u002Fblog\u002Fwhat-is-misp-the-ultimate-introduction)\n","# Building Threat Feed Aggregation with MISP\n\n## Overview\n\nMISP is the leading open-source threat intelligence platform for collecting, storing, distributing, and sharing cybersecurity indicators and threat intelligence. It aggregates feeds from OSINT sources, commercial providers, and sharing communities into a unified platform with automatic correlation, STIX\u002FTAXII export, and direct integration with SIEMs and security tools. This skill covers deploying MISP via Docker, configuring feeds from sources like abuse.ch, AlienVault OTX, and CIRCL, setting up automated feed synchronization, and integrating with Splunk, Elasticsearch, and SOAR platforms.\n\n\n## When to Use\n\n- When deploying or configuring building threat feed aggregation with misp capabilities in your environment\n- When establishing security controls aligned to compliance requirements\n- When building or improving security architecture for this domain\n- When conducting security assessments that require this implementation\n\n## Prerequisites\n\n- Docker and Docker Compose for deployment\n- Python 3.9+ with `pymisp` library for API interaction\n- Linux server with 8GB+ RAM for production deployment\n- Understanding of IOC types and threat intelligence lifecycle\n- Network access to external feed URLs\n\n## Key Concepts\n\n### MISP Architecture\n\nMISP stores threat intelligence as Events containing Attributes (IOCs) organized by type and category. Events can have Tags (MITRE ATT&CK, TLP marking, sector tags), Galaxies (threat actor profiles, malware families, attack patterns), and Objects (structured groupings of related attributes). Events are correlated automatically across the instance.\n\n### Feed Types\n\nMISP supports three feed formats: MISP format (native JSON events), CSV (comma-separated IOCs), and freetext (unstructured text with automatic IOC extraction). Feeds can be remote (fetched from URLs) or local (uploaded files). MISP ships with 80+ default OSINT feeds including abuse.ch URLhaus, Botvrij, CIRCL OSINT, and malware traffic analysis.\n\n### Sharing and Synchronization\n\nMISP instances can synchronize with other MISP instances via push\u002Fpull mechanisms. Sharing groups control distribution (organization only, this community, connected communities, all communities). The TAXII server module enables integration with STIX\u002FTAXII consumers.\n\n## Workflow\n\n### Step 1: Deploy MISP with Docker\n\n```yaml\n# docker-compose.yml for MISP deployment\nversion: '3.8'\nservices:\n  misp:\n    image: coolacid\u002Fmisp-docker:core-latest\n    container_name: misp\n    restart: unless-stopped\n    ports:\n      - \"443:443\"\n      - \"80:80\"\n    environment:\n      - MYSQL_HOST=misp-db\n      - MYSQL_DATABASE=misp\n      - MYSQL_USER=misp\n      - MYSQL_PASSWORD=misp_db_password_change_me\n      - MISP_ADMIN_EMAIL=admin@organization.com\n      - MISP_ADMIN_PASSPHRASE=admin_password_change_me\n      - MISP_BASEURL=https:\u002F\u002Fmisp.organization.com\n      - POSTFIX_RELAY_HOST=smtp.organization.com\n      - TIMEZONE=UTC\n    volumes:\n      - misp-data:\u002Fvar\u002Fwww\u002FMISP\u002Fapp\u002Ffiles\n      - misp-config:\u002Fvar\u002Fwww\u002FMISP\u002Fapp\u002FConfig\n    depends_on:\n      - misp-db\n      - misp-redis\n\n  misp-db:\n    image: mysql:8.0\n    container_name: misp-db\n    restart: unless-stopped\n    environment:\n      - MYSQL_DATABASE=misp\n      - MYSQL_USER=misp\n      - MYSQL_PASSWORD=misp_db_password_change_me\n      - MYSQL_ROOT_PASSWORD=root_password_change_me\n    volumes:\n      - misp-db-data:\u002Fvar\u002Flib\u002Fmysql\n\n  misp-redis:\n    image: redis:7\n    container_name: misp-redis\n    restart: unless-stopped\n\nvolumes:\n  misp-data:\n  misp-config:\n  misp-db-data:\n```\n\n### Step 2: Configure Feeds via PyMISP API\n\n```python\nfrom pymisp import PyMISP, MISPFeed\nimport json\n\nclass MISPFeedManager:\n    def __init__(self, misp_url, misp_key, verify_ssl=False):\n        self.misp = PyMISP(misp_url, misp_key, verify_ssl)\n        print(f\"[+] Connected to MISP: {misp_url}\")\n\n    def list_feeds(self):\n        \"\"\"List all configured feeds.\"\"\"\n        feeds = self.misp.feeds()\n        enabled = [f for f in feeds if f.get(\"Feed\", {}).get(\"enabled\")]\n        disabled = [f for f in feeds if not f.get(\"Feed\", {}).get(\"enabled\")]\n        print(f\"[+] Feeds: {len(enabled)} enabled, {len(disabled)} disabled\")\n        return feeds\n\n    def enable_default_feeds(self):\n        \"\"\"Enable recommended default OSINT feeds.\"\"\"\n        recommended_feeds = [\n            \"CIRCL OSINT Feed\",\n            \"Botvrij.eu - Indicators of Compromise\",\n            \"abuse.ch URLhaus Host file\",\n            \"abuse.ch Feodo Tracker\",\n            \"abuse.ch SSL Blacklist\",\n            \"malwaredomainlist\",\n            \"CyberCure - IP Feed\",\n        ]\n\n        feeds = self.misp.feeds()\n        enabled_count = 0\n        for feed in feeds:\n            feed_data = feed.get(\"Feed\", {})\n            if feed_data.get(\"name\") in recommended_feeds:\n                if not feed_data.get(\"enabled\"):\n                    self.misp.enable_feed(feed_data[\"id\"])\n                    self.misp.enable_feed_cache(feed_data[\"id\"])\n                    enabled_count += 1\n                    print(f\"  [+] Enabled: {feed_data['name']}\")\n\n        print(f\"[+] Enabled {enabled_count} feeds\")\n\n    def add_custom_feed(self, name, url, provider, feed_format=\"csv\",\n                        input_source=\"network\", enabled=True):\n        \"\"\"Add a custom threat intelligence feed.\"\"\"\n        feed = MISPFeed()\n        feed.name = name\n        feed.provider = provider\n        feed.url = url\n        feed.source_format = feed_format\n        feed.input_source = input_source\n        feed.enabled = enabled\n        feed.caching_enabled = True\n        feed.publish = False\n        feed.distribution = \"3\"  # All communities\n\n        result = self.misp.add_feed(feed)\n        if \"Feed\" in result:\n            feed_id = result[\"Feed\"][\"id\"]\n            print(f\"[+] Added feed: {name} (ID: {feed_id})\")\n            return feed_id\n        else:\n            print(f\"[-] Error adding feed: {result}\")\n            return None\n\n    def fetch_all_feeds(self):\n        \"\"\"Trigger fetch for all enabled feeds.\"\"\"\n        feeds = self.misp.feeds()\n        for feed in feeds:\n            feed_data = feed.get(\"Feed\", {})\n            if feed_data.get(\"enabled\"):\n                self.misp.fetch_feed(feed_data[\"id\"])\n                print(f\"  [*] Fetching: {feed_data['name']}\")\n        print(\"[+] Feed fetch triggered for all enabled feeds\")\n\nmanager = MISPFeedManager(\n    \"https:\u002F\u002Fmisp.organization.com\",\n    \"YOUR_MISP_API_KEY\",\n)\nmanager.enable_default_feeds()\nmanager.add_custom_feed(\n    name=\"Abuse.ch MalwareBazaar Recent\",\n    url=\"https:\u002F\u002Fbazaar.abuse.ch\u002Fexport\u002Fcsv\u002Frecent\u002F\",\n    provider=\"abuse.ch\",\n    feed_format=\"csv\",\n)\nmanager.fetch_all_feeds()\n```\n\n### Step 3: Search and Correlate Indicators\n\n```python\ndef search_indicators(misp, value=None, type_attribute=None, tags=None, last_days=30):\n    \"\"\"Search MISP for indicators with correlation.\"\"\"\n    from datetime import datetime, timedelta\n    date_from = (datetime.now() - timedelta(days=last_days)).strftime(\"%Y-%m-%d\")\n\n    search_params = {\n        \"date_from\": date_from,\n        \"published\": True,\n        \"enforceWarninglist\": True,\n    }\n    if value:\n        search_params[\"value\"] = value\n    if type_attribute:\n        search_params[\"type_attribute\"] = type_attribute\n    if tags:\n        search_params[\"tags\"] = tags\n\n    results = misp.search(\"attributes\", **search_params)\n    attributes = results.get(\"Attribute\", [])\n    print(f\"[+] Search returned {len(attributes)} attributes\")\n\n    # Group by event for context\n    events = {}\n    for attr in attributes:\n        event_id = attr.get(\"event_id\", \"\")\n        if event_id not in events:\n            events[event_id] = {\"attributes\": [], \"tags\": set()}\n        events[event_id][\"attributes\"].append({\n            \"type\": attr.get(\"type\", \"\"),\n            \"value\": attr.get(\"value\", \"\"),\n            \"category\": attr.get(\"category\", \"\"),\n            \"timestamp\": attr.get(\"timestamp\", \"\"),\n        })\n        for tag in attr.get(\"Tag\", []):\n            events[event_id][\"tags\"].add(tag.get(\"name\", \"\"))\n\n    return {\"attributes\": attributes, \"events\": events}\n\n# Search for specific IOC\nmisp = manager.misp\nresults = search_indicators(misp, value=\"203.0.113.1\")\nresults_by_type = search_indicators(misp, type_attribute=\"ip-dst\", last_days=7)\nresults_by_tag = search_indicators(misp, tags=[\"tlp:white\", \"type:OSINT\"])\n```\n\n### Step 4: Export to SIEM (Splunk \u002F Elasticsearch)\n\n```python\nimport requests\nfrom datetime import datetime, timedelta\n\nclass MISPSIEMExporter:\n    def __init__(self, misp_client):\n        self.misp = misp_client\n\n    def export_to_splunk(self, splunk_url, hec_token, days=7):\n        \"\"\"Export recent MISP indicators to Splunk via HEC.\"\"\"\n        date_from = (datetime.now() - timedelta(days=days)).strftime(\"%Y-%m-%d\")\n        results = self.misp.search(\"attributes\", date_from=date_from,\n                                    published=True, enforceWarninglist=True)\n        attributes = results.get(\"Attribute\", [])\n\n        headers = {\"Authorization\": f\"Splunk {hec_token}\"}\n        exported = 0\n        for attr in attributes:\n            event = {\n                \"event\": {\n                    \"ioc_type\": attr.get(\"type\", \"\"),\n                    \"ioc_value\": attr.get(\"value\", \"\"),\n                    \"category\": attr.get(\"category\", \"\"),\n                    \"event_id\": attr.get(\"event_id\", \"\"),\n                    \"timestamp\": attr.get(\"timestamp\", \"\"),\n                    \"tags\": [t.get(\"name\", \"\") for t in attr.get(\"Tag\", [])],\n                },\n                \"sourcetype\": \"misp:attribute\",\n                \"source\": \"misp\",\n                \"index\": \"threat_intel\",\n            }\n            resp = requests.post(\n                f\"{splunk_url}\u002Fservices\u002Fcollector\u002Fevent\",\n                headers=headers, json=event,\n                verify=not os.environ.get(\"SKIP_TLS_VERIFY\", \"\").lower() == \"true\",  # Set SKIP_TLS_VERIFY=true for self-signed certs in lab environments\n            )\n            if resp.status_code == 200:\n                exported += 1\n\n        print(f\"[+] Exported {exported}\u002F{len(attributes)} indicators to Splunk\")\n\n    def export_ioc_list(self, output_file, ioc_types=None, days=30):\n        \"\"\"Export flat IOC list for firewall\u002Fproxy blocklists.\"\"\"\n        ioc_types = ioc_types or [\"ip-dst\", \"domain\", \"hostname\", \"url\"]\n        date_from = (datetime.now() - timedelta(days=days)).strftime(\"%Y-%m-%d\")\n\n        all_iocs = []\n        for ioc_type in ioc_types:\n            results = self.misp.search(\n                \"attributes\", type_attribute=ioc_type,\n                date_from=date_from, published=True,\n                enforceWarninglist=True,\n            )\n            for attr in results.get(\"Attribute\", []):\n                all_iocs.append(attr.get(\"value\", \"\"))\n\n        unique_iocs = sorted(set(all_iocs))\n        with open(output_file, \"w\") as f:\n            for ioc in unique_iocs:\n                f.write(f\"{ioc}\\n\")\n\n        print(f\"[+] Exported {len(unique_iocs)} unique IOCs to {output_file}\")\n\nexporter = MISPSIEMExporter(misp)\nexporter.export_ioc_list(\"blocklist_ips.txt\", ioc_types=[\"ip-dst\"], days=7)\n```\n\n## Validation Criteria\n\n- MISP deployed and accessible via web interface and API\n- Default OSINT feeds enabled and fetching data\n- Custom feeds added and ingesting indicators\n- Indicators searchable with correlation across events\n- IOCs exported to SIEM (Splunk\u002FElasticsearch) successfully\n- Blocklists generated for firewall\u002Fproxy integration\n\n## References\n\n- [MISP Project](https:\u002F\u002Fwww.misp-project.org\u002F)\n- [MISP GitHub Repository](https:\u002F\u002Fgithub.com\u002FMISP\u002FMISP)\n- [MISP Default Feeds](https:\u002F\u002Fwww.misp-project.org\u002Ffeeds\u002F)\n- [PyMISP Documentation](https:\u002F\u002Fpymisp.readthedocs.io\u002F)\n- [Kraven Security: MISP Using Feeds](https:\u002F\u002Fkravensecurity.com\u002Fthreat-intelligence-with-misp-part-4-using-feeds\u002F)\n- [Cosive: What is MISP](https:\u002F\u002Fwww.cosive.com\u002Fblog\u002Fwhat-is-misp-the-ultimate-introduction)\n",{"name":5,"tags":24,"author":33,"domain":34,"license":14,"version":35,"nist_csf":36,"subdomain":32,"description":7,"mitre_attack":41},[25,26,27,28,29,30,31,32],"misp","threat-feed","aggregation","indicator","sharing","correlation","siem-integration","threat-intelligence","mahipal","cybersecurity","1.0",[37,38,39,40],"ID.RA-01","ID.RA-05","DE.CM-01","DE.AE-02",[42,43,44],"T1071","T1105","T1588.001","main","1eb986d0b0ecc180291597e08eb5a58288843536","skills\u002Fcurated_premium_skills\u002FAnthropic-Cybersecurity-Skills\u002Fskills\u002Fbuilding-threat-feed-aggregation-with-misp","https:\u002F\u002Fgithub.com\u002Fvikasvardhanv\u002Fjerry_skills","https:\u002F\u002Fgithub.com\u002Fvikasvardhanv","2026-08-25 13:16:33",{"source":8,"skillName":5,"commands":52,"prompt":62,"zipAvailable":63},[53,56,59],{"tool":54,"command":55},"npx","npx skills add vikasvardhanv\u002Fjerry_skills --skill building-threat-feed-aggregation-with-misp",{"tool":57,"command":58},"bunx","bunx skills add vikasvardhanv\u002Fjerry_skills --skill building-threat-feed-aggregation-with-misp",{"tool":60,"command":61},"pnpm","pnpm dlx skills add vikasvardhanv\u002Fjerry_skills --skill building-threat-feed-aggregation-with-misp","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fvikasvardhanv\u002Fjerry_skills\u002Fblob\u002Fmain\u002Fskills\u002Fcurated_premium_skills\u002FAnthropic-Cybersecurity-Skills\u002Fskills\u002Fbuilding-threat-feed-aggregation-with-misp\u002FSKILL.md",true,[65,69,75],{"path":66,"resourceType":66,"resourceTypeDesc":67,"sizeBytes":68,"sourceHtmlUrl":15},"LICENSE","许可证",11255,{"path":70,"resourceType":71,"resourceTypeDesc":72,"sizeBytes":73,"sourceHtmlUrl":74},"references\u002Fapi-reference.md","REFERENCE","参考文档",2135,"https:\u002F\u002Fgithub.com\u002Fvikasvardhanv\u002Fjerry_skills\u002Fblob\u002Fmain\u002Fskills\u002Fcurated_premium_skills\u002FAnthropic-Cybersecurity-Skills\u002Fskills\u002Fbuilding-threat-feed-aggregation-with-misp\u002Freferences\u002Fapi-reference.md",{"path":76,"resourceType":77,"resourceTypeDesc":78,"sizeBytes":79,"sourceHtmlUrl":80},"scripts\u002Fagent.py","SCRIPT","脚本",6731,"https:\u002F\u002Fgithub.com\u002Fvikasvardhanv\u002Fjerry_skills\u002Fblob\u002Fmain\u002Fskills\u002Fcurated_premium_skills\u002FAnthropic-Cybersecurity-Skills\u002Fskills\u002Fbuilding-threat-feed-aggregation-with-misp\u002Fscripts\u002Fagent.py",[82,90,97,104,111,118],{"skillNo":83,"name":84,"nameZh":6,"description":85,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":86,"licenseFileUrl":6,"sourceHtmlUrl":87,"categories":88,"keywords":89,"publishedAt":19},"01M7BESR1CJ3H5SP9XM8KYJZ9W","syllabus","Generates a curated supplementary reading list from any course syllabus using Consensus academic search. Grill-me intake (syllabus input format + course audience + year range) plus a grouping forcing-options checkpoint before any search runs — so the reading list matches the course's level and recency need. Parses the syllabus to extract topics and learning outcomes, searches Consensus for recent peer-reviewed papers per topic, and produces a professionally formatted .docx with clickable Consensus links, plain-language summaries calibrated to audience level, and Bloom-higher-order discussion questions tied to course learning goals. Use when the user uploads a syllabus, course outline, or curriculum document and wants supplementary readings (e.g., 'create a reading list from this syllabus', 'find recent papers for my course') — even casual mentions with a syllabus attached should trigger this skill.","MIT","https:\u002F\u002Fgithub.com\u002Fvikasvardhanv\u002Fjerry_skills\u002Fblob\u002Fmain\u002Fskills\u002Fresearch\u002Fsyllabus\u002Fskills\u002Fsyllabus\u002FSKILL.md",[],[],{"skillNo":91,"name":92,"nameZh":6,"description":93,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":86,"licenseFileUrl":6,"sourceHtmlUrl":94,"categories":95,"keywords":96,"publishedAt":19},"01M7BES1YA6R97W7QPMFFM1PED","pulse","Multi-source recency research skill that takes the pulse of any topic across Reddit, Hacker News, the open web, and optionally X\u002FTwitter within a configurable recent window (default 30 days). Forcing intake clarifies topic specificity, angle (trend\u002Fsentiment\u002Fproblems\u002Fopportunities\u002Fcomparison), time window, and platform scope before searching. Returns a synthesized briefing with citations, engagement metrics, and cross-platform pattern analysis. Use when the user requests multi-source recency intelligence on a topic (e.g., 'pulse on [topic]', 'what's happening with [topic]', 'what are people saying about [topic]', 'current conversation about [topic]', 'take the pulse of [topic]', 'trending: [topic]', 'find me info on [topic]'), and for competitor research, trend discovery, tool comparisons, and audience sentiment analysis.","https:\u002F\u002Fgithub.com\u002Fvikasvardhanv\u002Fjerry_skills\u002Fblob\u002Fmain\u002Fskills\u002Fresearch\u002Fpulse\u002Fskills\u002Fpulse\u002FSKILL.md",[],[],{"skillNo":98,"name":99,"nameZh":6,"description":100,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":86,"licenseFileUrl":6,"sourceHtmlUrl":101,"categories":102,"keywords":103,"publishedAt":19},"01M7BERNHYGY035AR00VRT03KE","patent","Patent prior-art and landscape intelligence skill — not generic patent help. Commits to one of five sub-use-cases via forcing intake (novelty search \u002F freedom-to-operate \u002F competitive landscape \u002F acquisition diligence \u002F litigation prior-art) before any search runs. Searches Google Patents, Espacenet, USPTO, and optionally Lens.org for citation-graph signals. Output is an editable Word document (.docx) with verdict, ranked closest art (claim-text extracted), CPC-class-aware landscape, family-resolved hits, geographic coverage, FTO flags where applicable, strategy recommendations, and full audit log. Use when the user asks for patent searching or analysis (e.g., 'prior art search for [invention]', 'freedom to operate analysis for [product]'). Produces search signal, not legal advice — always recommends consulting a patent attorney before filing or licensing decisions. Trademark, copyright, and trade-secret questions are out of scope.","https:\u002F\u002Fgithub.com\u002Fvikasvardhanv\u002Fjerry_skills\u002Fblob\u002Fmain\u002Fskills\u002Fresearch\u002Fpatent\u002Fskills\u002Fpatent\u002FSKILL.md",[],[],{"skillNo":105,"name":106,"nameZh":6,"description":107,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":86,"licenseFileUrl":6,"sourceHtmlUrl":108,"categories":109,"keywords":110,"publishedAt":19},"01M7BERCK1EAKTWW7R436WAR0J","notebooklm","Browser automation skill for controlling Google's NotebookLM. Use when the user wants anything done in NotebookLM (e.g., 'open NotebookLM', 'check my [name] notebook', 'ask my notebook about X', 'add [source] to NotebookLM', 'generate a Video Overview from my notebook', 'use NotebookLM Studio'). Handles reading and querying notebooks, adding sources (URLs, text, files, YouTube links, synthesized content), generating Studio outputs (Audio\u002FVideo Overviews, Mind Maps, Reports incl. Briefing Doc\u002FStudy Guide\u002FFAQ, Flashcards, Quiz, slide decks, infographics — discover the exact set from the live Studio panel; the UI evolves fast), and creating new notebooks. Requires browser automation environment — fails gracefully when unavailable.","https:\u002F\u002Fgithub.com\u002Fvikasvardhanv\u002Fjerry_skills\u002Fblob\u002Fmain\u002Fskills\u002Fresearch\u002Fnotebooklm\u002Fskills\u002Fnotebooklm\u002FSKILL.md",[],[],{"skillNo":112,"name":113,"nameZh":6,"description":114,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":86,"licenseFileUrl":6,"sourceHtmlUrl":115,"categories":116,"keywords":117,"publishedAt":19},"01M7BEQZAZAQRTXFJRY7RHV3TY","litreview","Academic literature orientation skill that searches papers via free keyless APIs (PubMed E-utilities + OpenAlex) by default — with the Consensus MCP as an optional enhancement lane when connected — builds a strategic search plan using PICO (default) or SPIDER \u002F Decomposition \u002F hybrid as fallbacks, and synthesizes findings into a formatted Word (.docx) research guide. Grill-me intake (research question specificity + framework hint + tentative depth) before the recon search; a second forcing checkpoint after Phase 2 confirms framework + sub-areas + depth before searches consume budget. Configurable depth (5\u002F10\u002F20 queries) controls coverage vs. speed. Output is a 'launching pad' — an orientation guide that lets a researcher dive in confidently, not a finished review. Use when the user starts literature-oriented research (e.g., 'litreview on [topic]', 'literature review on [topic]', 'I'm starting a literature review on X', 'I'm writing a paper on X', 'help me research X', 'I'm doing research on X', 'can you help me research X'). Do NOT use for single one-off paper searches wanting a quick list — that's a plain PubMed\u002FOpenAlex (or Consensus) query.","https:\u002F\u002Fgithub.com\u002Fvikasvardhanv\u002Fjerry_skills\u002Fblob\u002Fmain\u002Fskills\u002Fresearch\u002Flitreview\u002Fskills\u002Flitreview\u002FSKILL.md",[],[],{"skillNo":119,"name":120,"nameZh":6,"description":121,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":86,"licenseFileUrl":6,"sourceHtmlUrl":122,"categories":123,"keywords":124,"publishedAt":19},"01M7BEQKJ45K31QK5VRAQSVJCJ","grants","NIH grant research skill for clinical researchers. Grill-me intake (research idea + career stage + preliminary data + environment + submission posture + known institute targets) locks down the funding strategy before any search runs. Runs a 5-facet Consensus positioning analysis (with draft Significance\u002FInnovation language), maps the research to the right NIH institutes and study sections via RePORTER, finds NOSIs and funded overlap, and produces an editable Word document (.docx) with budget\u002Fscope-aware mechanism recommendations, submission timelines, and a mandatory program officer recommendation. Use when the user asks about research funding or makes any grant-related request (e.g., 'grants for [topic]', 'find grants for my research idea', 'what grants match my research', 'help me find NIH funding', 'grant opportunities for my research'). NIH-only scope — non-NIH funders (PCORI, DOD CDMRP, VA, foundations) are out of scope and flagged at intake.","https:\u002F\u002Fgithub.com\u002Fvikasvardhanv\u002Fjerry_skills\u002Fblob\u002Fmain\u002Fskills\u002Fresearch\u002Fgrants\u002Fskills\u002Fgrants\u002FSKILL.md",[],[]]