According to our back and forth discussion, we tried: ${index+sourcetype-information} NOT host IN ("10.128.220.19","10.169.0.1*") NOT src_ip IN ("10.*","127.*","192.168.*","172.16.0.0/12") dest_ip IN ("10.*","192.168.*","172.16.0.0/12") dest_port>-1 NOT dest_port IN (80,443) | eval combination = _time.",".dest_ip | stats values(combination) as V by src_ip dest_port | where ( mvcount(V) > 99 ) | eval singleString = mvjoin(V, ";") | rex max_match=0 field=singleString "(?<v>([^;]+(;|)){1,100})" | search v=* | mvexpand v | where mvcount(split(v, ";") ) > 99 | rex max_match=0 field=v "(?i)^(?<sT>[^,]*),[^;]*;([^,]*,[^;]*;){98}(?<eT>[^,]*),.*$" | where ( eT - sT < 300 ) AND ( mvcount(mvdedup(split(replace(v, "\d+,", ""), ";"))) > 99 ) | eval sT = strftime(sT, "%c") | eval eT = strftime(eT, "%c") | table src_ip dest_port sT eT v Only item we want to check is the way to use "[^,]*," instead of "\d+," in either "replace" or by another function so that we can try to make it generic if possible. It is able to detect scanning in this case it is host enumeration. Few issues with the query: * Possibly computation expensive * Can only be run say from "00:55:00" to "01:05:00", "01:00:00" to "01:00:00" to "01:10:00", etc. and may have results that are common in the Date-Time frames as it is mainly for high events per second (EPS) datasets with average of 15 K EPS * If the scanning is on say "10.0.0.0/24" with all the IPs within 5 minutes (00:02:00 till 00:07:00), then there will be multiple results such as "10.0.0.0" to "10.0.0.99", "10.0.0.1" to "10.0.0.100", "10.0.0.2" to "10.0.0.101", etc. until "10.0.0.156" to "10.0.0.255"
... View more