IOC Feed (MISP Threat Lists)
The IOC component watches incoming logs and marks documents whose content matches the Malware Information Sharing Platform (MISP) threat lists delivered with the Energy Security Feed. Marked events can be routed to alert rules or used to track incident behaviour.
How it works
A shell script (
misp_threat_lists.sh) downloads the eight blacklist files over HTTPS with Basic authentication.An ELS Network Node pipeline (
blacklists.conf) reads the downloaded files and stores each entry in the.blacklistsindex (used as an intermediate store).The same pipeline re-queries
.blacklistsdaily and writes YAML dictionary files (misp_<type>.yml) consumed by:Logstash
translatefilters in integration pipelines, which add a per-event field (for example[source][badip] => "true") when an indicator matches,the Blacklist-IOC alert rule type, which reads the YAML files directly (see Alert Rule Types).
At the end of the run, after all eight categories have been fetched, the script issues a single
_delete_by_querythat removes entries in.blacklistsolder than five minutes and taggedmisp_blacklist, so the intermediate index does not grow indefinitely.The shell script uses
curlover HTTPS with default TLS certificate validation. Only HTTP 200 responses trigger the rename of the downloaded file to the timestamped form (misp_<type>-<epoch>.blacklist) that the ELS Network Node pipeline picks up — any other response (401, 403, timeout) skips the rename, so the pipeline does not ingest new data for that category.
repository.energylogserver.pl/ioc/
│ misp_threat_lists.sh (HTTPS + Basic auth)
▼
/etc/logserver-probe/lists/misp_<type>.blacklist
│ blacklists.conf ELS Network Node pipeline
▼
.blacklists index (intermediate store)
│ daily export
▼
/etc/logserver-probe/lists/misp_<type>.yml ──┬─► Blacklist-IOC alert rules
│ │
│ translate filter │
▼ │
Logs tagged "misp_threat_detected" │
Feed categories
Eight category files are fetched from https://repository.energylogserver.pl/ioc/misp_<type>.blacklist:
Category file |
Indicator type |
|---|---|
|
Domain names |
|
Email addresses |
|
File names |
|
IP addresses |
|
URLs |
|
File hashes |
|
Certificate hashes |
|
Windows registry keys |
Feed file format
Each .blacklist file is tab-separated. The blacklists.conf ELS Network Node pipeline renames the five columns as follows:
Column |
Renamed to |
|---|---|
1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
Note
This is a custom Energy Logserver TSV format. It is not the standard MISP feed format (which supports MISP JSON, CSV or freetext per misp-project.org/feeds).
Generated dictionary format
The pipeline writes one line per indicator into /etc/logserver-probe/lists/misp_<type>.yml:
"<indicator value>": "bad_<type>"
The value is a literal presence label (bad_domain, bad_ip, bad_url, …) taken from the pipeline tag list, not a threat description. The source, description and url columns from the .blacklist file are stored in the .blacklists index but are not written into the YAML dictionary.
Note
Shipped translate integrations (Barracuda, Ruckus) therefore use the dictionary as a presence check and attach their own badip = "true" field via add_field. Custom integrations can read the dictionary value directly if a simple category label is sufficient; for richer threat context (source, description, url), query the .blacklists index instead.
Installation paths
On the ELS Network Node host the IOC components live at the following paths:
Path |
Purpose |
|---|---|
|
Download script |
|
Downloaded |
|
ELS Network Node pipeline |
|
Index template for |
The index template declares four properties: object (keyword), status (keyword), name (keyword) and description (text). The current pipeline stores five fields per entry — object, type, source, description, url — so type, source and url are mapped dynamically by the data engine, and status and name from the template are reserved but not populated by the pipeline.
Configure feed credentials
Edit /etc/logserver-probe/lists/bin/misp_threat_lists.sh and fill in the variables at the top of the file. A valid SIEM-PLAN license is required; IOC repository credentials are provided with it.
Variable |
Purpose |
Shipped default |
|---|---|---|
|
Directory for downloaded blacklist files |
|
|
Basic-auth user for |
empty |
|
Basic-auth password for |
empty |
|
Local account used to prune |
commented out, default |
|
Password for |
commented out, default |
|
Data node address |
|
|
Data node port |
|
|
Use TLS when querying the data node |
|
In addition, the pipeline output step uses ${PROBE_USER} / ${PROBE_PASS} passed from the ELS Network Node environment when writing to .blacklists.
Scheduling
The blacklists.conf pipeline carries its own schedule through the Logstash exec and logserver input plugins — no external cron is required when the pipeline is enabled on the ELS Network Node host. Cron expressions use the format m h * * *.
Cron |
Local time |
Action |
|---|---|---|
|
02:01 |
Run |
|
03:01 |
Query |
|
04:01 |
Sort and deduplicate each |
|
04:05 |
Remove entries listed in |
|
04:10 |
Append entries from |
If the script must run from a host that does not run the pipeline, schedule it externally. See Installation — Blacklist and Threat Intelligence Setup for the crontab example and the ELS Console Scheduler configuration.
Custom exclude and include lists
The pipeline reads two auxiliary indices once a day and applies them to misp_domain.yml only:
Index |
Field read by pipeline |
Effect |
|---|---|---|
|
|
Domains listed here are removed from the translate dictionary — use this to eliminate false positives |
|
|
Domains listed here are appended to the translate dictionary — use this to add local indicators |
Write documents to these indices through the data API. Changes take effect at the next apply step (04:05 for excludes, 04:10 for includes).
Using IOC in alert rules
The Blacklist-IOC rule type (see Alert Rule Types) reads the generated YAML dictionaries directly. The shipped Watchguard alert rules illustrate the expected configuration:
blacklist-ioc:
- "!yaml /etc/logserver-probe/lists/misp_ip.yml"
compare_key: src.ip
realert:
minutes: 60
blacklist-ioc:— list of YAML dictionary files prefixed with!yamlcompare_key:— event field compared against the dictionary keysrealert:— minimum interval between repeated alerts for the same match
Point compare_key at the field you want to check (for example src.ip, dst.ip, dst.domain) and blacklist-ioc at the matching misp_<type>.yml file.
Using IOC in ELS Network Node pipelines
The generated YAML files in /etc/logserver-probe/lists/ can be consumed by any ELS Network Node pipeline through the Logstash translate filter. Two shipped integrations use this pattern: Barracuda CloudGen Firewall (barracuda/conf.d/barracuda/096-filter-misp.conf) and Ruckus (ruckus/conf.d/ruckus/090-filter-misp.conf). The Barracuda filter is shown below:
filter {
if "barracuda" in [tags] {
if [source][locality] == "public" {
if [source][ip] {
translate {
field => "[source][ip]"
dictionary_path => "/etc/logserver-probe/lists/misp_ip.yml"
add_field => {
"[source][badip]" => "true"
}
refresh_behaviour => "replace"
override => true
}
}
}
if ![source][badip] {
mutate {
add_field => { "[source][badip]" => "false" }
}
}
# (symmetric block for [destination][ip] omitted for brevity)
if [source][badip] == "true" or [destination][badip] == "true" {
mutate {
add_tag => [ "misp_threat_detected" ]
}
}
}
}
Other integrations can adopt the same approach by pointing dictionary_path at the relevant misp_<type>.yml file.
Note
The Barracuda example above uses the field => parameter, which is deprecated in Logstash translate 3.3.0+ (use source => in new pipelines). Existing shipped integrations mix both forms.
Verification
Confirm the feed is flowing after installation:
# Index exists and holds documents
curl -sS -u $CREDENTIAL -XGET '127.0.0.1:9200/_cat/indices/.blacklists?v'
# YAML dictionaries were generated
ls -l /etc/logserver-probe/lists/misp_*.yml
Troubleshooting
Symptom |
What to check |
|---|---|
|
Credentials |
YAML dictionaries not updating |
The |
False positive for a domain |
Add the domain to |
Missing internal indicator |
Add the domain to |
HTTP 401/403 from the feed URL |
Verify |
|
|
Further reading
The feed uses MISP category naming (domain, email, url, ip, filehash, filename, certhash, regkey). For background on what a MISP feed is and how public MISP feeds are distributed, see the MISP project public feeds page.