File: //usr/share/filebeat/module/threatintel/anomali/ingest/pipeline.yml
---
description: Pipeline for parsing Anomali Limo indicators
processors:
####################
# Event ECS fields #
####################
- set:
field: event.ingested
value: "{{_ingest.timestamp}}"
- set:
field: event.kind
value: enrichment
- set:
field: event.category
value: threat
- set:
field: event.type
value: indicator
######################
# General ECS fields #
######################
- rename:
field: message
target_field: event.original
ignore_missing: true
- json:
field: event.original
target_field: anomali.limo
- fingerprint:
fields:
- anomali.limo.id
target_field: "_id"
ignore_missing: true
#####################
# Threat ECS Fields #
#####################
- set:
field: threat.feed.name
value: "[Filebeat] Anomali Limo"
- set:
field: threat.feed.dashboard_id
value: "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f"
## File indicator operations
- date:
field: anomali.limo.created
formats:
- "yyyy-MM-dd'T'HH:mm:ssz"
- "yyyy-MM-dd'T'HH:mm:ssZ"
- "yyyy-MM-dd'T'HH:mm:ss.Sz"
- "yyyy-MM-dd'T'HH:mm:ss.SZ"
- "yyyy-MM-dd'T'HH:mm:ss.SSz"
- "yyyy-MM-dd'T'HH:mm:ss.SSZ"
- "yyyy-MM-dd'T'HH:mm:ss.SSSz"
- "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
if: "ctx.anomali?.limo?.created != null"
- date:
field: anomali.limo.modified
target_field: anomali.limo.modified
formats:
- "yyyy-MM-dd'T'HH:mm:ssz"
- "yyyy-MM-dd'T'HH:mm:ssZ"
- "yyyy-MM-dd'T'HH:mm:ss.Sz"
- "yyyy-MM-dd'T'HH:mm:ss.SZ"
- "yyyy-MM-dd'T'HH:mm:ss.SSz"
- "yyyy-MM-dd'T'HH:mm:ss.SSZ"
- "yyyy-MM-dd'T'HH:mm:ss.SSSz"
- "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
if: "ctx.anomali?.limo?.modified != null"
- date:
field: anomali.limo.valid_from
target_field: threat.indicator.first_seen
formats:
- "yyyy-MM-dd'T'HH:mm:ssz"
- "yyyy-MM-dd'T'HH:mm:ssZ"
- "yyyy-MM-dd'T'HH:mm:ss.Sz"
- "yyyy-MM-dd'T'HH:mm:ss.SZ"
- "yyyy-MM-dd'T'HH:mm:ss.SSz"
- "yyyy-MM-dd'T'HH:mm:ss.SSZ"
- "yyyy-MM-dd'T'HH:mm:ss.SSSz"
- "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
if: "ctx.anomali?.limo?.valid_from != null"
- grok:
field: anomali.limo.pattern
patterns:
- "^\\[%{DATA:_tmp.threattype}:value%{SPACE}=%{SPACE}'%{DATA:_tmp.threatvalue}'\\]"
if: ctx.anomali?.limo?.pattern != null
- rename:
field: _tmp.threattype
target_field: threat.indicator.type
ignore_missing: true
- rename:
field: _tmp.threatvalue
target_field: threat.indicator.ip
ignore_missing: true
if: "['ipv4-addr', 'ipv6-addr'].contains(ctx.threat?.indicator?.type)"
- uri_parts:
field: _tmp.threatvalue
target_field: threat.indicator.url
keep_original: true
remove_if_successful: true
if: ctx.threat?.indicator?.type == 'url'
- set:
field: threat.indicator.url.full
value: "{{{threat.indicator.url.original}}}"
ignore_empty_value: true
- rename:
field: _tmp.threatvalue
target_field: threat.indicator.email.address
ignore_missing: true
if: ctx.threat?.indicator?.type == 'email-addr'
- rename:
field: _tmp.threatvalue
target_field: threat.indicator.url.domain
ignore_missing: true
if: ctx.threat?.indicator?.type == 'domain-name'
- set:
field: threat.indicator.type
value: unknown
if: ctx.threat?.indicator?.type == null
- foreach:
field: anomali.limo.labels
ignore_missing: true
processor:
append:
field: tags
value: "{{_ingest._value}}"
allow_duplicates: false
- grok:
field: anomali.limo.description
patterns:
- "^%{GREEDYDATA}Source: %{GREEDYDATA:threat.indicator.provider}"
ignore_missing: true
ignore_failure: true
######################
# Cleanup processors #
######################
- script:
lang: painless
if: ctx?.threatintel != null
source: |
void handleMap(Map map) {
for (def x : map.values()) {
if (x instanceof Map) {
handleMap(x);
} else if (x instanceof List) {
handleList(x);
}
}
map.values().removeIf(v -> v == null);
}
void handleList(List list) {
for (def x : list) {
if (x instanceof Map) {
handleMap(x);
} else if (x instanceof List) {
handleList(x);
}
}
}
handleMap(ctx);
- remove:
field: event.original
if: "ctx?.tags == null || !(ctx.tags.contains('preserve_original_event'))"
ignore_failure: true
ignore_missing: true
- remove:
field:
- anomali.limo.created
- message
- _tmp
ignore_missing: true
on_failure:
- set:
field: error.message
value: "{{ _ingest.on_failure_message }}"