T1590.002 Google Chronicle · YARA-L

Detect DNS in Google Chronicle

Adversaries may gather information about the victim's DNS infrastructure to support targeting. DNS reconnaissance reveals registered name servers, subdomains, mail servers, and host addressing. DNS record types including MX, TXT, SPF, DMARC, and DKIM records expose third-party cloud and SaaS provider usage (Office 365, Google Workspace, Salesforce, Zendesk). Adversaries may perform full DNS zone transfers (AXFR queries) against misconfigured authoritative servers, query passive DNS databases (Circl, SecurityTrails, Shodan), or run OSINT tools such as dnsrecon, subfinder, amass, and fierce. The collected intelligence maps the organization's external attack surface and informs infrastructure acquisition, phishing infrastructure setup, and initial access planning.

MITRE ATT&CK

Tactic
Reconnaissance
Technique
T1590 Gather Victim Network Information
Sub-technique
T1590.002 DNS
Canonical reference
https://attack.mitre.org/techniques/T1590/002/

YARA-L Detection Query

Google Chronicle (YARA-L)
yaral
// Rule 1: External DNS Zone Transfer Attempt (AXFR/IXFR/ANY from non-RFC1918 sources)
rule t1590_002_dns_zone_transfer_external {
  meta:
    author = "Detection Engineer"
    description = "Detects AXFR, IXFR, or ANY DNS queries arriving from non-RFC1918 source IPs"
    mitre_attack_tactic = "Reconnaissance"
    mitre_attack_technique = "T1590.002"
    severity = "HIGH"
    priority = "HIGH"
    false_positives = "Authorized secondary DNS replication from hosted or DMZ name servers"

  events:
    $e.metadata.event_type = "NETWORK_DNS"
    (
      $e.network.dns.questions.type = "AXFR" or
      $e.network.dns.questions.type = "IXFR" or
      $e.network.dns.questions.type = "ANY"
    )
    not net.ip_in_range_cidr($e.principal.ip, "10.0.0.0/8")
    not net.ip_in_range_cidr($e.principal.ip, "192.168.0.0/16")
    not net.ip_in_range_cidr($e.principal.ip, "172.16.0.0/12")
    not net.ip_in_range_cidr($e.principal.ip, "127.0.0.0/8")
    not net.ip_in_range_cidr($e.principal.ip, "169.254.0.0/16")

  condition:
    $e
}

// Rule 2: DNS OSINT Tool or Built-in Utility Abused for Enumeration on Endpoint
rule t1590_002_dns_osint_tool_execution {
  meta:
    author = "Detection Engineer"
    description = "Detects execution of DNS reconnaissance tools or abuse of nslookup/dig with AXFR/enumeration arguments"
    mitre_attack_tactic = "Reconnaissance"
    mitre_attack_technique = "T1590.002"
    severity = "HIGH"
    priority = "HIGH"
    false_positives = "Authorized red team operators, security engineers running attack surface tooling"

  events:
    $e.metadata.event_type = "PROCESS_LAUNCH"
    (
      re.regex($e.principal.process.file.full_path,
        `(?i)(dnsrecon|dnsx|subfinder|amass|fierce|dnsmap|dnsenum|gobuster|dnstwist|dnswalk|shuffledns|puredns|altdns|knockpy)(\.py|\.pl)?$`)
      or
      (
        re.regex($e.principal.process.file.full_path, `(?i)python[23]?(\.exe)?$`) and
        re.regex($e.principal.process.command_line, `(?i)(dnsrecon|dnsenum|fierce|sublist3r|dnstwist)`)
      )
      or
      (
        re.regex($e.principal.process.file.full_path, `(?i)nslookup(\.exe)?$`) and
        re.regex($e.principal.process.command_line, `(?i)(-type=axfr|-q=axfr|-querytype=axfr|-type=any|ls\s+-[dt])`)
      )
      or
      (
        re.regex($e.principal.process.file.full_path, `(?i)(^|[/\\])dig(\.exe)?$`) and
        re.regex($e.principal.process.command_line, `(?i)(axfr|_dmarc|\sMX\s|\sNS\s|\sTXT\s|\+short)`)
      )
    )

  condition:
    $e
}

// Rule 3: Bulk External DNS Enumeration — NS/MX/TXT/SOA/ANY volume over 10-minute window
rule t1590_002_bulk_dns_enumeration {
  meta:
    author = "Detection Engineer"
    description = "Detects bulk NS/MX/TXT/SOA/ANY queries from a single external IP exceeding 30 events or 20 unique names in a 10-minute window"
    mitre_attack_tactic = "Reconnaissance"
    mitre_attack_technique = "T1590.002"
    severity = "MEDIUM"
    priority = "MEDIUM"
    false_positives = "IPAM platforms, vulnerability scanners, authorized attack surface management tools"

  events:
    $e.metadata.event_type = "NETWORK_DNS"
    (
      $e.network.dns.questions.type = "NS" or
      $e.network.dns.questions.type = "MX" or
      $e.network.dns.questions.type = "TXT" or
      $e.network.dns.questions.type = "SOA" or
      $e.network.dns.questions.type = "ANY"
    )
    not net.ip_in_range_cidr($e.principal.ip, "10.0.0.0/8")
    not net.ip_in_range_cidr($e.principal.ip, "192.168.0.0/16")
    not net.ip_in_range_cidr($e.principal.ip, "172.16.0.0/12")
    not net.ip_in_range_cidr($e.principal.ip, "127.0.0.0/8")
    $ip = $e.principal.ip
    $name = $e.network.dns.questions.name

  match:
    $ip over 10m

  outcome:
    $unique_names = count_distinct($name)
    $query_count = count()

  condition:
    $query_count > 30 or $unique_names > 20
}
high severity high confidence

Three Chronicle YARA-L 2.0 rules for T1590.002 DNS reconnaissance targeting the Google Chronicle Detection Engine. Rule 1 matches NETWORK_DNS events for AXFR/IXFR/ANY query types from non-RFC1918 source IPs using net.ip_in_range_cidr() negation for precise CIDR exclusion across all five private address blocks. Rule 2 matches PROCESS_LAUNCH events using re.regex() against process.file.full_path and process.command_line to detect known DNS OSINT tool names and abuse of Python, nslookup, and dig with zone transfer or enumeration arguments. Rule 3 uses the match/outcome pattern to aggregate NETWORK_DNS events over a 10-minute sliding window keyed on source IP, using count_distinct() on the queried domain name and alerting when total queries exceed 30 or unique names exceed 20 — equivalent to the KQL BulkEnumAlerts branch. All rules reference UDM fields and are deployable directly as Detection Engine rules in the Chronicle console.

Data Sources

Google Chronicle UDM NETWORK_DNS events (from DNS server log ingestion parsers)Google Chronicle UDM PROCESS_LAUNCH events (from CrowdStrike Falcon, Carbon Black, SentinelOne, or Defender forwarded to Chronicle)Chronicle ingestion parsers for Microsoft DNS, BIND, Windows Event Log, and Sysmon

Required Tables

UDM events with metadata.event_type = NETWORK_DNSUDM events with metadata.event_type = PROCESS_LAUNCH

False Positives & Tuning

  • Authorized DNS secondary name servers performing AXFR replication from hosted or cloud-segment IPs not covered by the RFC1918 CIDR exclusions in Rules 1 and 3
  • Security research or red team endpoints enrolled in Chronicle telemetry that run amass, subfinder, or similar tools during authorized assessments against the organization's own infrastructure
  • DNS-based monitoring and IPAM solutions (Infoblox, BlueCat, NetBox) generating bulk NS/MX/TXT/SOA queries above the Rule 3 threshold during automated inventory reconciliation
  • CI/CD pipeline agents querying multiple DNS record types for infrastructure validation during deployments, exceeding the 10-minute window threshold in Rule 3
Download portable Sigma rule (.yml)

Other platforms for T1590.002


Testing Methodology

Validate this detection against 5 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.

  1. Test 1DNS Zone Transfer Attempt via nslookup

    Expected signal: Sysmon Event ID 1: Process Create with Image=nslookup.exe, CommandLine containing '-type=axfr'. Sysmon Event ID 3: Network Connection to nsztm1.digi.ninja on TCP/53 (zone transfers require TCP). DNS server debug log (if configured): outbound AXFR query. Windows Security Event ID 4688 (if command line auditing enabled).

  2. Test 2DNS Zone Transfer via dig

    Expected signal: Linux process execution via auditd: execve syscall for /usr/bin/dig with arguments 'axfr zonetransfer.me @nsztm1.digi.ninja'. Network connection on TCP/53 to nsztm1.digi.ninja. Sysmon for Linux Event ID 1 (if deployed): Process Create. Stream:DNS capture shows query_type=AXFR from the endpoint IP.

  3. Test 3DNS Subdomain Enumeration with dnsrecon

    Expected signal: Sysmon for Linux EventCode=1: Process Create with Image=dnsrecon or python3, CommandLine containing 'dnsrecon' and 'example.com'. Multiple DNS queries for MX, NS, TXT, SOA, A records for example.com visible in stream:dns or DNS server logs. High query count from the endpoint IP within a short window.

  4. Test 4DNS MX and TXT Record Harvesting via PowerShell

    Expected signal: Sysmon Event ID 1: Process Create for powershell.exe with CommandLine containing 'Resolve-DnsName' and record type arguments. Sysmon Event ID 22 (DNS Query): Multiple DNS queries for MX, TXT, NS, SOA record types for example.com. PowerShell ScriptBlock Logging Event ID 4104: full script content including all Resolve-DnsName calls.

  5. Test 5Subfinder Passive DNS Enumeration

    Expected signal: Sysmon for Linux EventCode=1: Process Create with Image=subfinder, CommandLine containing 'example.com' and '-o /tmp/subdomains.txt'. Sysmon for Linux EventCode=11 (File Create): /tmp/subdomains.txt written. Network connections to multiple external threat intelligence APIs (api.shodan.io, virustotal.com, crt.sh) over HTTPS.

Unlock Pro Content

Get the full detection package for T1590.002 including response playbook, investigation guide, and atomic red team tests.

Response PlaybookInvestigation GuideHunting QueriesAtomic Red Team TestsTuning Guidance

Related Detections