I'm trying to set up a watch to join data from multiple indices.
Here's how I would like it to work: first, I look up if there are anti-virus alerts from the firewall log, if there are, then look up the IP address from DHCP log and finally, look up DNS records which were made from the IP address around the time of the alert.
This is what I have succeeded to do so far:
{
"trigger": {
"schedule": {
"interval": "1m"
}
},
"input": {
"chain": {
"inputs": [
{
"firewall": {
"search": {
"request": {
"search_type": "query_then_fetch",
"indices": [
"<company-firewall-{now/d}>"
],
"types": [],
"body": {
"query": {
"bool": {
"filter": [
{
"term": {
"event_id": 809
}
},
{
"range": {
"@timestamp": {
"from": "{{ctx.trigger.scheduled_time}}||-1m",
"to": "{{ctx.trigger.triggered_time}}"
}
}
}
]
}
}
}
}
}
}
},
{
"dhcp": {
"search": {
"request": {
"search_type": "query_then_fetch",
"indices": [
"<company-dhcp-{now/M{YYYY.MM}}>"
],
"types": [],
"body": {
"query": {
"bool": {
"must": [
{
"term": {
"ID": 11
}
},
{
"exists": {
"field": "{{ctx.payload.firewall.hits.hits.0._source}}"
}
}
],
"should": [
{
"term": {
"IP": "{{ctx.payload.firewall.hits.hits.0._source.src_ip}}"
}
},
{
"term": {
"IP": "{{ctx.payload.firewall.hits.hits.0._source.dst_ip}}"
}
}
],
"minimum_should_match": 1
}
},
"size": 1,
"sort": [
{
"@timestamp": {
"order": "desc"
}
}
]
}
}
}
}
},
{
"dns": {
"search": {
"request": {
"search_type": "query_then_fetch",
"indices": [
"<company-dns-{now/d}>"
],
"types": [],
"body": {
"query": {
"bool": {
"filter": [
{
"term": {
"client_ip": "{{ctx.payload.dhcp.hits.hits.0._source.IP}}"
}
},
{
"range": {
"@timestamp": {
"from": "{{ctx.payload.firewall.hits.hits.0._source.@timestamp}}||-1m",
"to": "{{ctx.payload.firewall.hits.hits.0._source.@timestamp}}||+1m"
}
}
}
]
}
}
}
}
}
}
}
]
}
},
"condition": {
"script": "ctx.payload.firewall.hits.total > 0 && ctx.payload.dhcp.hits.total > 0 && ctx.payload.dns.hits.total > 0"
},
"actions": {
"cmk_ec": {
"webhook": {
"scheme": "http",
"host": "logstash.company.tld",
"port": 6557,
"method": "post",
"path": "/alarm",
"params": {},
"headers": {},
"auth": {
"basic": {
"username": "user1",
"password": "hunter2"
}
},
"body": "{\"_type\":\"ids\", \"msg\":\"{{ctx.payload.firewall.hits.hits.0._source.msg}}\", \"src_ip\": \"{{ctx.payload.firewall.hits.hits.0._source.src_ip}}\", \"dst_ip\": \"{{ctx.payload.firewall.hits.hits.0._source.dst_ip}}\", \"MAC\": \"{{ctx.payload.dhcp.hits.hits.0._source.MAC}}\", \"HostName\": \"{{ctx.payload.dhcp.hits.hits.0._source.HostName}}\", \"dns\": [\"{{#ctx.payload.dns.hits.hits}}{{_source.dns.question.etld_plus_one}}, {{/ctx.payload.dns.hits.hits}}\"]}"
}
}
}
}
Now of course the dhcp and dns queries will fail if there are no virus alerts.
Is there a way to make it conditional, because now it floods the log with index out of bound exceptions.
I tried to tacle this problem with:
"exists": {
"field": "{{ctx.payload.firewall.hits.hits.0._source}}"
}
But it didn't do what I expected.
Thank you.