| name | hunting-for-dns-based-persistence |
| description | Hunt for DNS-based persistence mechanisms including DNS hijacking, dangling CNAME records, wildcard DNS abuse, and unauthorized zone modifications using passive DNS databases, SecurityTrails API, and DNS audit log analysis. Use when hunting for dns-based persistence mechanisms including dns hijacking, dangling cname. |
| domain | cybersecurity |
| subdomain | threat-hunting |
| tags | ["dns","persistence","threat-hunting","passive-dns","dns-hijacking","subdomain-takeover","securitytrails"] |
| version | 1.0 |
| author | oyi77 |
| license | Apache-2.0 |
| nist_csf | ["DE.CM-01","DE.AE-02","DE.AE-07","ID.RA-05"] |
Hunting for DNS-based Persistence
Overview
Attackers establish DNS-based persistence by hijacking DNS records, creating unauthorized subdomains, abusing wildcard DNS entries, or modifying NS delegations to redirect traffic through attacker-controlled infrastructure. These techniques survive credential rotations, endpoint reimaging, and traditional remediation because DNS changes persist independently of compromised hosts. Detection requires passive DNS historical analysis, zone file auditing, and monitoring for unauthorized record modifications. This skill covers hunting methodologies using SecurityTrails passive DNS API, DNS audit logs from Route53/Azure DNS/Cloudflare, and zone transfer analysis.
When to Use
Trigger phrases:
-
"hunting for dns based persistence"
-
"Hunt for DNS-based persistence mechanisms including DNS hijacking, dangling CNAM"
-
When investigating security incidents that require hunting for dns based persistence
-
When building detection rules or threat hunting queries for this domain
-
When SOC analysts need structured procedures for this analysis type
-
When validating security monitoring coverage for related attack techniques
Prerequisites
- SecurityTrails API key (free tier provides 50 queries/month)
- Access to DNS provider audit logs (Route53, Azure DNS, Cloudflare, or on-premises DNS)
- Python 3.9+ with requests library
- DNS zone file access or AXFR capability for internal zones
- Historical DNS baseline for comparison
Steps
import re
IOC_PATTERNS = {
"ip": r"\b(?:\d{1,3}\.){3}\d{1,3}\b",
"domain": r"\b[a-z0-9-]+\.[a-z]{2,}\b",
"hash_md5": r"\b[a-f0-9]{32}\b",
"hash_sha256": r"\b[a-f0-9]{64}\b",
}
def extract_iocs(text: str) -> dict:
return {k: re.findall(v, text) for k, v in IOC_PATTERNS.items()}