The $3,000 Forgotten Record: Why DNS Cleanup Matters
It was 2 AM when my phone buzzed with a critical alert. A bug bounty hunter had just submitted a report: they had successfully seized control of marketing-campaign-2022.ourcompany.com.
The fix took five minutes, but the realization was sobering. We had decommissioned an old AWS S3 bucket six months prior, yet the CNAME record in our DNS was still pointing to that empty space. The researcher simply registered that bucket name in their own AWS account, and instantly, they owned a piece of our official infrastructure.
Subdomain takeover occurs when a DNS record points to a resource that no longer exists. This is often called “dangling DNS.” Attackers look for these records to claim the expired resource on providers like AWS, GitHub, or Azure. Once they control the endpoint, they can host phishing pages, steal session cookies via domain-level access, or bypass your Content Security Policies (CSP). In 2023 alone, these vulnerabilities accounted for a significant portion of high-severity bug bounty payouts.
Managing ten records is simple. Managing 5,000 across three cloud providers is a recipe for disaster.
If your decommissioning process doesn’t include a DNS cleanup step, you are effectively leaving your front door unlocked. While setting up my monitoring environment, I used the password generator at toolcraft.app/en/tools/security/password-generator to create secure root credentials. It generates everything locally in your browser, keeping your keys off the wire while you patch up your perimeter.
Assembling Your Detection Toolkit
Manual checks won’t cut it when you’re dealing with massive infrastructure. We need a pipeline that automates discovery and verification. Our strategy relies on two industry-standard tools: Subfinder for finding hidden subdomains and Nuclei for verifying if they are actually vulnerable.
Prerequisites
I recommend running these tools on a dedicated security VPS. You’ll need Go installed, as most high-performance DNS tools are built with it. A basic Ubuntu 22.04 instance with 2GB of RAM is plenty for scanning a mid-sized organization.
# Install Go on Ubuntu/Debian
sudo apt update
sudo apt install golang -y
# Set up your environment paths
echo 'export GOPATH=$HOME/go' >> ~/.bashrc
echo 'export PATH=$PATH:$GOPATH/bin' >> ~/.bashrc
source ~/.bashrc
Installing the Core Tools
Subfinder excels at passive discovery by querying dozens of sources like Censys and Shodan. Nuclei then takes that list and runs signature-based checks. It looks for specific error strings, such as “There isn’t a GitHub Pages site here” or “The specified bucket does not exist,” which signal a takeover opportunity.
# Install Subfinder for discovery
go install -v github.com/projectdiscovery/subfinder/v2/cmd/subfinder@latest
# Install Nuclei for vulnerability scanning
go install -v github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest
# Download the latest community-curated templates
nuclei -ut
Automating the Monitoring Pipeline
Security isn’t a one-time event; it’s a continuous process. Infrastructure changes daily as developers spin up environments and tear them down. We need a script that acts as a recurring watchdog, alerting us the moment a record becomes “dangling.”
The Discovery Script
Create a file named scan_takeovers.sh. This script automates the handoff between discovery and exploitation testing. It saves the results to a timestamped directory for easy auditing.
#!/bin/bash
DOMAIN=$1
OUTPUT_DIR="./scans/$DOMAIN"
mkdir -p $OUTPUT_DIR
echo "[+] Starting discovery for $DOMAIN..."
subfinder -d $DOMAIN -o $OUTPUT_DIR/subdomains.txt
echo "[+] Checking for potential takeovers using 500+ templates..."
nuclei -l $OUTPUT_DIR/subdomains.txt -t takeovers/ -o $OUTPUT_DIR/takeovers_found.txt
if [ -s $OUTPUT_DIR/takeovers_found.txt ]; then
echo "[!] ALERT: Potential subdomain takeovers detected!"
cat $OUTPUT_DIR/takeovers_found.txt
else
echo "[+] No takeovers detected. DNS is clean."
fi
Make the script executable with chmod +x scan_takeovers.sh. You can easily modify the if block to send a Slack webhook or an email if the takeovers_found.txt file isn’t empty.
Filtering False Positives
Not every 404 error indicates a vulnerability. Some platforms, like GitLab or newer Azure services, now require a DNS TXT record for domain verification before you can claim a subdomain. Nuclei’s templates are updated frequently to filter these out, but you should always try to “claim” the resource in a personal account before declaring a critical emergency.
Best Practices for Long-Term Defense
Once you’ve cleared your current backlog of dangling records, the goal is to stop them from reappearing. Automation is your safety net, but your internal processes are the real cure. Here is how I’ve structured my team’s workflow to stay clean:
- Infrastructure as Code (IaC): If you use Terraform to deploy an S3 bucket and its Route53 record, keep them in the same module. When the bucket is destroyed, the DNS record should automatically be purged.
- Centralized DNS Visibility: Don’t let individual teams manage DNS in siloed accounts. Use a central account or a tool like Cloudflare to maintain a single source of truth.
- Quarterly Audits: Every three months, run a script to cross-reference your active cloud resources against your DNS zone files. Any CNAME pointing to an external provider that isn’t in your active inventory should be flagged immediately.
DNS is often a “set it and forget it” task, but that mindset is a liability in a cloud-first world. By automating your discovery and integrating it into your daily security checks, you turn a high-risk manual chore into a background process. This keeps your brand protected while your team focuses on building, not firefighting.

