# EQL - Network Port scan - Watcher to EQL

**URL:** <https://discuss.elastic.co/t/eql-network-port-scan-watcher-to-eql/273104>\
**Category:** Elastic Security\
**Tags:** eql-elastic-query-language\
**Created:** [May 16, 2021, 10:02am UTC](https://discuss.elastic.co/t/eql-network-port-scan-watcher-to-eql/273104 "2021-05-16T10:02:15Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![jancodenew](https://avatars.discourse-cdn.com/v4/letter/j/87869e/32.png) [@jancodenew](https://discuss.elastic.co/u/jancodenew)\
**Post date:** [May 16, 2021, 10:02am UTC](https://discuss.elastic.co/t/eql-network-port-scan-watcher-to-eql/273104/1 "2021-05-16T10:02:15Z")

</div>

Please help me to convert the below port scan watcher query to EQL in ELK SIEM 7.12.1.

PUT \_watcher/watch/port\_scan\_watch  
{  
"trigger": {  
"schedule": {  
"interval": "10s"  
}  
},  
"input": {  
"search": {  
"request": {  
"search\_type": "query\_then\_fetch",  
"indices": [  
"logstash-tcpdump-\*"  
],  
"types": [  
"tcpdump"  
],  
"body": {  
"size": 0,  
"query": {  
"bool": {  
"must": [  
{  
"match": {  
"tags": "tcp\_connection\_started"  
}  
},  
{  
"range": {  
"@timestamp": {  
"gte": "now-30s"  
}  
}  
}  
]  
}  
},  
"aggs": {  
"by\_src\_ip": {  
"terms": {  
"field": "src\_ip"  
},  
"aggs": {  
"by\_target\_ip": {  
"terms": {  
"field": "dst\_ip",  
"order": {  
"unique\_port\_count": "desc"  
}  
},  
"aggs": {  
"unique\_port\_count": {  
"cardinality": {  
"field": "dst\_port"  
}  
}  
}  
}  
}  
}  
}  
}  
}  
}  
},  
"condition": {  
"script": {  
"inline": "for (int i = 0; i \< ctx.payload.aggregations.by\_src\_ip.buckets.size(); i++) {for (int j = 0; j \< ctx.payload.aggregations.by\_src\_ip.buckets[i].by\_target\_ip.buckets.size(); j++) {if (ctx.payload.aggregations.by\_src\_ip.buckets[i].by\_target\_ip.buckets[j].unique\_port\_count.value \> threshold) return true;};};return false;",  
"params": {  
"threshold": 50  
}  
}  
},  
"throttle\_period": "30s",  
"actions": {  
"email\_administrator": {  
"transform": {  
"script": {  
"inline": "def target='';def attacker='';def body='';for (int i = 0; i \< ctx.payload.aggregations.by\_src\_ip.buckets.size(); i++) {for (int j = 0; j \< ctx.payload.aggregations.by\_src\_ip.buckets[i].by\_target\_ip.buckets.size(); j++) {if (ctx.payload.aggregations.by\_src\_ip.buckets[i].by\_target\_ip.buckets[j].unique\_port\_count.value \> threshold) {target=ctx.payload.aggregations.by\_src\_ip.buckets[i].by\_target\_ip.buckets[j].key;attacker=ctx.payload.aggregations.by\_src\_ip.buckets[i].key;body='Detected portscan from ['+attacker+'] to ['+target+']. '+ctx.payload.aggregations.by\_src\_ip.buckets[i].by\_target\_ip.buckets[j].unique\_port\_count.value+ ' unique ports scanned.'; return [body : body];};};};",  
"params": {  
"threshold": 50  
}  
}  
},  
"email": {  
"profile": "standard",  
"attach\_data": true,  
"priority": "high",  
"to": [  
"[antonio@elastic.co](mailto:antonio@elastic.co)"  
],  
"subject": "[Security Alert] - Port scan detected",  
"body": "{{ctx.payload.body}}"  
}  
}  
}  
}

---

<div class="post-metadata">

**Author:** ![austinsonger](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/austinsonger/32/78994_2.png) [@austinsonger](https://discuss.elastic.co/u/austinsonger)\
**Post date:** [May 17, 2021, 11:55pm UTC](https://discuss.elastic.co/t/eql-network-port-scan-watcher-to-eql/273104/2 "2021-05-17T23:55:38Z")

</div>

Can you place it in a code block so it retains the format.

---

<div class="post-metadata">

**Author:** ![Mike\_Paquette](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/mike_paquette/32/119011_2.png) [@Mike\_Paquette](https://discuss.elastic.co/u/Mike_Paquette)\
**Post date:** [May 18, 2021, 11:52am UTC](https://discuss.elastic.co/t/eql-network-port-scan-watcher-to-eql/273104/3 "2021-05-18T11:52:01Z")

</div>

Hi @jancodenew, thanks for the post.

I see that your question presumes you want an EQL solution, but could you possibly take advantage of the security solution's "Threshold" rule type for this use case? The rule could look like this:

 ![image](https://us1.discourse-cdn.com/elastic/original/3X/7/d/7d48c3ee7b1ed9c71e9d9e6fa2ac70ec7168747b.jpeg)

One note of caution that applies to watcher or detection engine rules with nested aggregations is that the number aggregation buckets across all (`source.ip` x `destination.ip`) combinations could have very high cardinality in a large environment, so you might want to ensure that the rule operates on only a single comprehensive set of network data, and/or include filters in the original query where appropriate.

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [June 15, 2021, 11:52am UTC](https://discuss.elastic.co/t/eql-network-port-scan-watcher-to-eql/273104/4 "2021-06-15T11:52:34Z")

</div>

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.
