Detect Domain Generation Algorithms in Google Chronicle
Adversaries use Domain Generation Algorithms (DGAs) to dynamically identify C2 destinations by algorithmically generating large numbers of candidate domain names. Only the operator-registered domain resolves successfully; all others return NXDOMAIN. This makes blocking impractical — defenders cannot predict the full space of generated domains. DGAs may produce random character strings (e.g., istgmxdejdnxuyla.ru) or concatenate dictionary words (e.g., cityjulydish.net). Many implementations are time-seeded, generating different candidate domains hourly or daily. Some incorporate a shared secret seed to prevent defender prediction. Detection focuses on statistical anomalies: abnormally high NXDOMAIN failure rates from a single host, domain names with low vowel ratios or high character entropy, rapid successive queries to many unique failing domains, and beaconing patterns once a DGA domain resolves. Malware families using DGA include QakBot, Conficker, Ursnif, DarkWatchman, BONDUPDATER, POSHSPY, CHOPSTICK, Aria-body, Milan, SombRAT, and MiniDuke. APT41 changes C2 monthly via DGA; TA551 generates URLs from executed macros.
MITRE ATT&CK
- Tactic
- Command and Control
- Technique
- T1568 Dynamic Resolution
- Sub-technique
- T1568.002 Domain Generation Algorithms
- Canonical reference
- https://attack.mitre.org/techniques/T1568/002/
YARA-L Detection Query
rule t1568_002_dga_nxdomain_entropy_detection {
meta:
author = "df00tech"
description = "Detects potential DGA C2 activity via abnormal NXDOMAIN rates and low-entropy domain names. Identifies hosts generating 20+ NXDOMAIN responses within 1 hour with 15+ unique failing domains, applying vowel ratio and domain length heuristics to classify algorithmically-generated domains."
mitre_attack_id = "T1568.002"
mitre_tactic = "Command And Control"
severity = "HIGH"
priority = "HIGH"
reference = "https://attack.mitre.org/techniques/T1568/002/"
version = "1.0"
created = "2024-01-01"
events:
$dns.metadata.event_type = "NETWORK_DNS"
$dns.network.dns.response_code = "NXDOMAIN"
// Require a registered domain label of at least 7 characters
$dns.network.dns.questions.name != ""
re.regex($dns.network.dns.questions.name, `[a-zA-Z0-9]{7,}`) nocase
// Bind principal host for grouping
$dns.principal.hostname = $hostname
$dns.principal.ip = $src_ip
match:
// Group by source host over a 1-hour sliding window
$hostname, $src_ip over 1h
outcome:
// Count total NXDOMAIN events in window
$total_nxdomain = count($dns.network.dns.questions.name)
// Count distinct failing domain names
$unique_nx_domains = count_distinct($dns.network.dns.questions.name)
// Flag domains with high digit density (proxy for DGA without full entropy math in YARA-L)
// domains where >35% chars are digits: use regex to approximate
$likely_dga_high_digits = count_distinct(
if(
re.regex($dns.network.dns.questions.name, `^(?:.*\.)?[a-z]*[0-9][a-z0-9]*[0-9][a-z0-9]*[0-9]`),
$dns.network.dns.questions.name
)
)
// Flag abnormally long SLD (> 16 chars before TLD)
$likely_dga_long_label = count_distinct(
if(
re.regex($dns.network.dns.questions.name, `^(?:.*\.)?[a-zA-Z0-9]{17,}\.[a-zA-Z]{2,}$`),
$dns.network.dns.questions.name
)
)
// Approximate low-vowel domains: SLD with no vowel runs of > 4 consonants
$likely_dga_low_vowel = count_distinct(
if(
re.regex($dns.network.dns.questions.name, `^(?:.*\.)?[a-z]*[^aeiou ]{5,}[a-z]*\.`),
$dns.network.dns.questions.name
)
)
$likely_dga_total = $likely_dga_high_digits + $likely_dga_long_label + $likely_dga_low_vowel
$sample_domain = array_distinct($dns.network.dns.questions.name)[0]
condition:
$total_nxdomain >= 20 and $unique_nx_domains >= 15
} Chronicle YARA-L 2.0 rule detecting DGA-based C2 via abnormal NXDOMAIN rates. Groups DNS NXDOMAIN events by source host over a 1-hour window and triggers when volume and unique domain thresholds are exceeded. Uses regex-based approximations to classify likely algorithmically-generated domain labels: high digit density, abnormally long labels, and consonant-heavy strings (proxy for low vowel ratio). Full entropy scoring requires post-alert enrichment via SOAR or UDM enrichment pipelines.
Data Sources
Required Tables
False Positives & Tuning
- Corporate DNS resolvers serving many endpoints will aggregate NXDOMAIN traffic from thousands of hosts behind a single principal.ip, triggering the threshold for benign aggregate traffic
- Security tools performing passive DNS collection or threat intelligence enrichment via bulk DNS resolution of IoC lists will generate high NXDOMAIN counts from the tool host
- Gaming clients, P2P software, or browser extensions with aggressive background DNS checks for CDN availability may produce NXDOMAIN bursts during CDN failover events
Other platforms for T1568.002
Testing Methodology
Validate this detection against 4 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.
- Test 1PowerShell Time-Seeded DGA Simulation (Conficker-Style)
Expected signal: Sysmon Event ID 22 (DNS Query): 30 entries with Image=powershell.exe, QueryName values containing random-character strings (10-16 chars, low vowel ratio). QueryStatus will show 'No Such Name' or equivalent NXDOMAIN code for all 30. DnsEvents: ResultCode=3 for all generated domains. The Sysmon process chain shows powershell.exe as the Image with no suspicious parent.
- Test 2Bash DGA Simulation — Random Character String Domains (Linux/macOS)
Expected signal: Linux auditd SYSCALL records for nslookup execution with random domain arguments (if auditd configured for execve syscalls). Syslog entries from nslookup showing NXDOMAIN responses. Network capture shows UDP port 53 queries to the configured resolver for random-string .com domains. EDR process telemetry: nslookup spawned 30 times from bash with unique arguments per invocation.
- Test 3Python DGA Simulation with Date-Seeded Algorithm
Expected signal: Sysmon Event ID 1: python3.exe process creation with command line containing the DGA script inline. Sysmon Event ID 22: 30 DNS query events with Image=python3.exe (or python.exe), QueryName values showing random lowercase strings ending in .net. Windows Security Event 4688 (if command line auditing enabled) shows the full python3.exe invocation.
- Test 4Rapid nslookup Batch — High-Entropy Domain Names (Windows CMD)
Expected signal: Sysmon Event ID 22: 17 DNS query events with Image=nslookup.exe (or cmd.exe as parent), each QueryName showing a consonant-heavy random string ending in .com. All return NXDOMAIN. Windows Security Event 4688 shows cmd.exe execution followed by multiple nslookup.exe child processes. The batch executes in approximately 2-5 seconds, creating a high-velocity NXDOMAIN burst.
References (12)
- https://attack.mitre.org/techniques/T1568/002/
- https://umbrella.cisco.com/blog/2016/10/10/domain-generation-algorithms-effective/
- http://go.cybereason.com/rs/996-YZT-709/images/Cybereason-Lab-Analysis-Dissecting-DGAs-Eight-Real-World-DGA-Variants.pdf
- https://unit42.paloaltonetworks.com/threat-brief-understanding-domain-generation-algorithms-dga/
- https://arxiv.org/pdf/1611.00791.pdf
- https://datadrivensecurity.info/blog/posts/2014/Oct/dga-part2/
- https://www.welivesecurity.com/2017/12/21/sednit-update-fancy-bear-spent-year/
- https://www.fireeye.com/blog/threat-research/2017/03/dissecting_one_ofap.html
- http://blog.talosintelligence.com/2017/09/avast-distributes-malware.html
- https://learn.microsoft.com/en-us/azure/sentinel/dns-domain-generation-algorithm
- https://docs.microsoft.com/en-us/sysinternals/downloads/sysmon
- https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1568.002/T1568.002.md
Unlock Pro Content
Get the full detection package for T1568.002 including response playbook, investigation guide, and atomic red team tests.