2025-01-20 // Security Team
C2 Beacon Detection via DNS Regularity
Elastic SIEMIdentifies potential command-and-control beaconing behaviour by analysing the statistical regularity of DNS queries to external domains from internal hosts.
Overview
C2 frameworks like Cobalt Strike and Metasploit often beacon at regular intervals. This detection uses statistical analysis of inter-query timing to identify hosts making suspiciously regular DNS requests to the same external domain.
Query
sequence by host.name, dns.question.name with maxspan=1h
[dns where dns.question.type == "A" and not cidr_match(destination.ip, "10.0.0.0/8", "192.168.0.0/16")]
[dns where dns.question.type == "A" and not cidr_match(destination.ip, "10.0.0.0/8", "192.168.0.0/16")]
[dns where dns.question.type == "A" and not cidr_match(destination.ip, "10.0.0.0/8", "192.168.0.0/16")]
Companion aggregation (ES|QL):
FROM logs-dns*
| WHERE @timestamp > NOW() - 24 HOURS
| WHERE NOT CIDR_MATCH(destination.ip, "10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16")
| STATS
query_count = COUNT(*),
first_seen = MIN(@timestamp),
last_seen = MAX(@timestamp)
BY host.name, dns.question.name
| EVAL duration_mins = DATE_DIFF("minutes", first_seen, last_seen)
| EVAL beacon_interval = duration_mins / query_count
| WHERE query_count > 5 AND beacon_interval BETWEEN 0.8 AND 1.2
| SORT query_count DESC
Logic Explanation
The ES|QL query calculates an average inter-query interval per host/domain pair. A beacon_interval close to 1.0 (normalised) indicates highly regular timing, a hallmark of automated C2 callbacks. The BETWEEN 0.8 AND 1.2 window allows for minor jitter while catching consistent beacons.
Tuning Notes
- Exclude known CDN and telemetry domains to reduce noise
- Adjust the
query_count > 5threshold based on beacon frequency - Combine with threat intel feeds to correlate against known C2 infrastructure
References
- MITRE ATT&CK: T1071.004 - Application Layer Protocol: DNS
- MITRE ATT&CK: T1132 - Data Encoding