Detection rules › Kusto
Rare client observed with high reverse DNS lookup count - Static threshold based (ASIM DNS Solution)
This rule identifies clients with high reverse DNS counts, which could be carrying out reconnaissance or discovery activity. This helps in detecting the possible initial phases of an attack, like discovery and reconnaissance. It utilizes ASIM normalization and is applied to any source that supports the ASIM DNS schema.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Reconnaissance |
Telemetry coverage
| Provider | Record / event type |
|---|---|
| Sysmon | Event ID 22: DNSEvent (DNS query) |
Rule body
id: 77b7c820-5f60-4779-8bdb-f06e21add5f1
name: Rare client observed with high reverse DNS lookup count - Static threshold based (ASIM DNS Solution)
description: |
'This rule identifies clients with high reverse DNS counts, which could be carrying out reconnaissance or discovery activity. This helps in detecting the possible initial phases of an attack, like discovery and reconnaissance. It utilizes [ASIM](https://aka.ms/AboutASIM) normalization and is applied to any source that supports the ASIM DNS schema.'
severity: Medium
status: Available
tags:
- Schema: ASimDns
SchemaVersion: 0.1.6
requiredDataConnectors: []
queryFrequency: 1d
queryPeriod: 10d
triggerOperator: gt
triggerThreshold: 0
tactics:
- Reconnaissance
relevantTechniques:
- T1590
query: |
let threshold = 10;
let stime = 10d;
let etime = 1d;
let SearchDomain = dynamic(["in-addr.arpa"]);
_Im_Dns(starttime=ago(etime), domain_has_any=SearchDomain)
| summarize
StartTimeUtc = min(TimeGenerated),
EndTimeUtc = max(TimeGenerated),
DNSQueryCount=dcount(DnsQuery)
by SrcIpAddr
| where DNSQueryCount > threshold
| project StartTimeUtc, EndTimeUtc, SrcIpAddr, DNSQueryCount
| join kind=leftanti (_Im_Dns(starttime=ago(stime), endtime=ago(etime), domain_has_any=SearchDomain)
| summarize DNSQueryCount=dcount(DnsQuery) by SrcIpAddr, bin(TimeGenerated, 1d)
| where DNSQueryCount > threshold
| project SrcIpAddr, DNSQueryCount
)
on SrcIpAddr
| join kind=inner (_Im_Dns(starttime=ago(etime), domain_has_any=SearchDomain)
| summarize DNSQueries=make_set(DnsQuery, 1000) by SrcIpAddr)
on SrcIpAddr
| extend DNSQuerythreshold = threshold
| project-away SrcIpAddr1
entityMappings:
- entityType: IP
fieldMappings:
- identifier: Address
columnName: SrcIpAddr
eventGroupingSettings:
aggregationKind: AlertPerResult
customDetails:
DNSQueries: DNSQueries
DNSQuerythreshold: DNSQuerythreshold
DNSQueryCount: DNSQueryCount
alertDetailsOverride:
alertDisplayNameFormat: "[Static threshold] Rare client has been observed as making high reverse DNS lookup count - client IP: '{{SrcIpAddr}}'"
alertDescriptionFormat: "Client identified as making high reverse DNS counts which could be carrying out reconnaissance or discovery activity.\n\nReverse DNS lookup threshold is: '{{DNSQuerythreshold}}'\n\nCurrent reverse DNS lookup count from this client is : '{{DNSQueryCount}}'\n\nDNS queries requested by this client inlcude: '{{DNSQueries}}'"
version: 1.0.2
kind: Scheduled
Stages and Predicates
Parameters
let threshold = 10;
let stime = 10d;
let etime = 1d;
let SearchDomain = dynamic(["in-addr.arpa"]);
Stage 1: source
_Im_Dns(starttime=ago(etime), domain_has_any=SearchDomain)
Stage 2: summarize
| summarize
StartTimeUtc = min(TimeGenerated),
EndTimeUtc = max(TimeGenerated),
DNSQueryCount=dcount(DnsQuery)
by SrcIpAddr
Stage 3: where
| where DNSQueryCount > threshold
Stage 4: project
| project StartTimeUtc, EndTimeUtc, SrcIpAddr, DNSQueryCount
Stage 5: join (negated)
| join kind=leftanti (_Im_Dns(starttime=ago(stime), endtime=ago(etime), domain_has_any=SearchDomain)
| summarize DNSQueryCount=dcount(DnsQuery) by SrcIpAddr, bin(TimeGenerated, 1d)
| where DNSQueryCount > threshold
| project SrcIpAddr, DNSQueryCount
)
on SrcIpAddr
Stage 6: join
| join kind=inner (_Im_Dns(starttime=ago(etime), domain_has_any=SearchDomain)
| summarize DNSQueries=make_set(DnsQuery, 1000) by SrcIpAddr)
on SrcIpAddr
Stage 7: extend
| extend DNSQuerythreshold = threshold
Stage 8: project-away
| project-away SrcIpAddr1
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
DNSQueryCount | gt | 10 | excludes:DNSQueryCount field:"DNSQueryCount" value:"10" |
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
DNSQueryCount | gt |
| field:"DNSQueryCount" kind:gt value:"10" |
Output fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
DNSQueryCount | project |
EndTimeUtc | project |
SrcIpAddr | project |
StartTimeUtc | project |
DNSQuerythreshold | extend |