Note: This skill covers a defensive threat-intelligence platform. Handle ingested intelligence according to its Traffic Light Protocol (TLP) marking and your sharing agreements. Treat ingested IOCs as potentially sensitive.
MISP (Malware Information Sharing Platform) is the de-facto open-source threat-intelligence platform for storing, correlating, and sharing structured indicators (IOCs), events, galaxies (threat-actor/technique knowledge), and objects. Running a MISP instance is only the first step; the value comes from operationalizing it — curating high-quality feeds, suppressing false positives with warninglists, and pushing the resulting IOCs into detection tooling so intelligence actually drives blocking and alerting.
A feed in MISP is a remote source (another MISP, a CSV/freetext list, or a structured collection) that you enable and optionally cache. Caching pulls the feed's IOCs into the instance's Redis-backed cache so values can be correlated and looked up in real time (e.g., a SIEM asking "have you seen this domain?") without importing every event. Curation matters: enabling every public feed produces noise and false positives, so you select reputable feeds (CIRCL OSINT, abuse.ch, Feodo Tracker, etc.), apply warninglists (known-good ranges like RFC1918, Alexa/Tranco top sites, public DNS resolvers) to flag non-actionable indicators, and use taxonomies/tags (TLP, confidence) to scope what gets exported.
The detection-engineering payoff comes from MISP's export formats and PyMISP. MISP can render matching attributes directly as Suricata and Snort rules via the REST API, and PyMISP lets you script extraction of fresh IOCs to generate Sigma rules and Wazuh CDB lists / rules on a schedule. This skill walks the full lifecycle: feed enablement and caching, warninglist-based FP reduction, PyMISP-driven search, and automated generation of Suricata, Sigma, and Wazuh detections.
git clone https://github.com/MISP/misp-docker.git
cd misp-docker && cp template.env .env
docker compose up -d
# Web UI on https://localhost; default admin: admin@admin.test / admin
pip install pymisp
pip install sigma-cli), and/or Wazuh manager.| Technique ID | Technique Name | Relevance |
|---|---|---|
| T1589 | Gather Victim Identity Information | Feeds capture adversary reconnaissance indicators; operationalizing them detects/contextualizes such activity. |
| T1071.001 | Application Layer Protocol: Web Protocols | C2 domain/URL IOCs from feeds become Suricata/Sigma detections for malicious HTTP(S). |
| T1071.004 | Application Layer Protocol: DNS | Malicious-domain IOCs feed DNS-based detection (Wazuh/Suricata). |
| T1105 | Ingress Tool Transfer | File-hash IOCs from feeds detect known malicious payload delivery. |
Register a reputable source and turn it on.
# add_feed.py (PyMISP) — register the CIRCL OSINT feed
from pymisp import PyMISP, MISPFeed
misp = PyMISP("https://localhost", "YOUR_AUTH_KEY", ssl=False)
feed = MISPFeed()
feed.name = "CIRCL OSINT Feed"
feed.provider = "CIRCL"
feed.url = "https://www.circl.lu/doc/misp/feed-osint"
feed.source_format = "misp"
feed.input_source = "network"
feed.enabled = True
print(misp.add_feed(feed, pythonify=True))
Caching loads feed IOCs into Redis so lookups are instant.
# Cache all enabled feeds (equivalent to "Enable caching" in the UI)
print(misp.cache_all_feeds())
# Or fetch a single feed's events into the instance by feed id:
print(misp.fetch_feed(1))
Turn on known-good lists so non-actionable indicators are flagged.
# Enable the common false-positive warninglists
for wl in misp.warninglists(pythonify=True):
if wl.name in ("List of RFC 1918 CIDR blocks",
"Top 1000 website from Cisco Umbrella",
"List of known public DNS resolvers"):
misp.toggle_warninglist(warninglist_id=wl.id, force_enable=True)
Pull recently published, TLP-scoped, to-IDS attributes only.
from pymisp import PyMISP
misp = PyMISP("https://localhost", "YOUR_AUTH_KEY", ssl=False)
# Only export attributes flagged to_ids=1, published, last 7 days, IP/domain/url/hash
attrs = misp.search(
controller="attributes",
type_attribute=["ip-dst", "domain", "url", "md5", "sha256"],
to_ids=True, published=True, last="7d",
enforce_warninglist=True, # drop warninglisted (known-good) values
pythonify=True,
)
print(f"{len(attrs)} actionable IOCs")
MISP renders matching attributes directly as IDS rules.
# Suricata rules for all to_ids network IOCs (NIDS export)
curl -s -k -H "Authorization: YOUR_AUTH_KEY" -H "Accept: application/json" \
"https://localhost/attributes/restSearch/returnFormat:suricata/to_ids:1/type:domain%7Cip-dst%7Curl" \
-o misp_suricata.rules
# Snort equivalent
curl -s -k -H "Authorization: YOUR_AUTH_KEY" -H "Accept: application/json" \
"https://localhost/attributes/restSearch/returnFormat:snort/to_ids:1" -o misp_snort.rules
Load and reload.
cp misp_suricata.rules /etc/suricata/rules/
suricata -T -c /etc/suricata/suricata.yaml # validate config + rules
suricatasc -c reload-rules # hot reload
Convert MISP domains/IPs into a Wazuh CDB lookup list referenced by a rule.
# Build a Wazuh CDB list (key:value per line) from the searched attributes
with open("misp_iocs.cdb", "w") as fh:
for a in attrs:
if a.type in ("domain", "ip-dst"):
fh.write(f"{a.value}:\n")
# On the Wazuh manager: place under /var/ossec/etc/lists/, reference in ossec.conf:
# <list>etc/lists/misp_iocs</list>
# then compile and restart:
# /var/ossec/bin/wazuh-control restart
Emit a Sigma rule matching the exported domains.
import yaml
domains = [a.value for a in attrs if a.type == "domain"]
sigma = {
"title": "MISP feed malicious domain contact",
"status": "experimental",
"logsource": {"category": "dns"},
"detection": {"selection": {"query|contains": domains}, "condition": "selection"},
"level": "high",
"tags": ["attack.command_and_control", "attack.t1071.004"],
}
with open("misp_domains.yml", "w") as fh:
yaml.safe_dump(sigma, fh, sort_keys=False)
Use sigma-cli to compile to the target backend (Splunk, Elastic, etc.).
sigma convert -t splunk -p splunk_windows misp_domains.yml > misp_domains.spl
sigma convert -t elasticsearch misp_domains.yml > misp_domains.eql
agent.py searches MISP and writes Suricata/Sigma/Wazuh artifacts in one pass; schedule it via cron.
python scripts/agent.py --url https://localhost --key YOUR_AUTH_KEY \
--last 7d --outdir ./detections --insecure
# crontab: 0 * * * * /usr/bin/python /path/scripts/agent.py ... >> /var/log/misp_pipeline.log 2>&1
| Tool | Purpose | Source |
|---|---|---|
| MISP | Threat-intelligence platform | https://www.misp-project.org/ |
| misp-docker | Maintained container deployment | https://github.com/MISP/misp-docker |
| PyMISP | Python client for the MISP REST API | https://github.com/MISP/PyMISP |
| MISP warninglists | Known-good lists for FP reduction | https://github.com/MISP/misp-warninglists |
| MISP automation docs | REST API + export formats | https://www.circl.lu/doc/misp/automation/ |
| sigma-cli | Sigma rule conversion | https://github.com/SigmaHQ/sigma-cli |
| Wazuh CDB lists | IOC lookup lists for Wazuh | https://documentation.wazuh.com/ |
enforce_warninglist applied to searches.suricata -T.