Back to blog
InspectionJanuary 1, 2024ยท 12 min read

Subdomain Discovery: Find Hidden Assets and Security Risks

A practical Fusebox guide to subdomain discovery.

Subdomain Discovery: Find Hidden Assets and Security Risks

Published: January 2024
Reading time: 8 minutes

Every subdomain is a potential entry point. Companies often forget about old staging servers, development environments, and internal tools exposed to the internet. Here's how to discover subdomains, analyze their purpose, and identify security risks.

Why Subdomain Discovery Matters

Hidden Attack Surface

  • Forgotten staging sites - Old versions with vulnerabilities
  • Development environments - Debug mode enabled, credentials exposed
  • Internal tools - Admin panels without proper authentication
  • Third-party services - Outdated integrations
  • Shadow IT - Departments creating unofficial subdomains

Real-World Impact

Uber hack (2016): Accessed via forgotten subdomain
Tesla (2018): Kubernetes dashboard on subdomain
UN (2021): Git credentials in dev subdomain
Facebook (2019): Internal tools on corp subdomain
Microsoft (2020): Misconfigured storage subdomain

Quick Subdomain Discovery

1. Basic Subdomain Enumeration

// Discover subdomains using multiple techniques
async function discoverSubdomains(domain) {
  console.log(`๐Ÿ” Subdomain Discovery for ${domain}\n`);
  
  const subdomains = new Set();
  
  // 1. Common subdomain patterns
  const commonPrefixes = [
    'www', 'mail', 'ftp', 'blog', 'shop', 'api', 'cdn', 'static',
    'admin', 'portal', 'secure', 'vpn', 'remote', 'webmail',
    'ns1', 'ns2', 'smtp', 'pop', 'imap', 'forum', 'help',
    'dev', 'stage', 'staging', 'test', 'demo', 'beta', 'alpha',
    'uat', 'prod', 'production', 'live', 'old', 'new', 'mobile',
    'app', 'api-v1', 'api-v2', 'backend', 'frontend', 'assets',
    'images', 'img', 'media', 'videos', 'download', 'downloads'
  ];
  
  console.log('๐ŸŽฏ Checking common subdomain patterns...');
  
  // Simulate checking (in practice, you'd do DNS lookups)
  const foundCommon = ['www', 'mail', 'api', 'blog', 'dev', 'staging'];
  foundCommon.forEach(sub => {
    subdomains.add(`${sub}.${domain}`);
    console.log(`  โœ… Found: ${sub}.${domain}`);
  });
  
  // 2. Certificate Transparency logs
  console.log('\n๐Ÿ” Checking Certificate Transparency logs...');
  const ctSubdomains = [
    'secure.example.com',
    'payment.example.com',
    'admin.example.com',
    '*.dev.example.com',
    'internal.example.com'
  ];
  
  ctSubdomains.forEach(sub => {
    if (sub.includes(domain)) {
      subdomains.add(sub);
      console.log(`  ๐Ÿ“œ Found in CT logs: ${sub}`);
    }
  });
  
  // 3. Search engine discovery
  console.log('\n๐Ÿ”Ž Search engine discovery...');
  console.log('  Google: site:*.example.com -www');
  console.log('  Bing: site:example.com -site:www.example.com');
  
  // 4. DNS zone transfer attempt (usually fails)
  console.log('\n๐Ÿ“‹ Attempting zone transfer...');
  console.log('  โŒ Zone transfer denied (expected)');
  
  // 5. Reverse DNS
  console.log('\n๐Ÿ”„ Reverse DNS lookup...');
  const reverseDNS = ['app1.example.com', 'app2.example.com'];
  reverseDNS.forEach(sub => {
    subdomains.add(sub);
    console.log(`  ๐Ÿ”— Found via PTR: ${sub}`);
  });
  
  // Summary
  console.log(`\n๐Ÿ“Š Total subdomains found: ${subdomains.size}`);
  console.log('\n๐Ÿ“ Discovered subdomains:');
  Array.from(subdomains).sort().forEach(sub => {
    console.log(`  - ${sub}`);
  });
  
  return Array.from(subdomains);
}

// Run discovery
discoverSubdomains('example.com');

2. Advanced Subdomain Enumeration

// Advanced techniques for finding hidden subdomains
function advancedSubdomainDiscovery(domain) {
  console.log(`\n๐Ÿ”ฌ Advanced Subdomain Discovery for ${domain}\n`);
  
  // 1. Permutation generation
  console.log('๐ŸŽฒ Generating intelligent permutations...');
  
  const baseWords = ['api', 'app', 'dev', 'stage', 'test', 'admin'];
  const modifiers = ['', '-', '1', '2', 'new', 'old', 'v1', 'v2'];
  const environments = ['dev', 'qa', 'uat', 'prod'];
  
  const permutations = [];
  baseWords.forEach(base => {
    modifiers.forEach(mod => {
      if (mod === '') {
        permutations.push(base);
      } else if (mod === '-') {
        environments.forEach(env => {
          permutations.push(`${base}-${env}`);
        });
      } else {
        permutations.push(`${base}${mod}`);
        permutations.push(`${base}-${mod}`);
      }
    });
  });
  
  console.log(`  Generated ${permutations.length} permutations`);
  console.log(`  Sample: ${permutations.slice(0, 5).join(', ')}...`);
  
  // 2. Technology-specific patterns
  console.log('\n๐Ÿ”ง Technology-specific subdomain patterns:');
  
  const techPatterns = {
    'AWS': ['s3', 'ec2', 'rds', 'elasticbeanstalk'],
    'Azure': ['azurewebsites', 'blob', 'azurecontainer'],
    'Google Cloud': ['appspot', 'googleapis', 'googleusercontent'],
    'CDN': ['cdn', 'assets', 'static', 'media', 'images'],
    'Email': ['mail', 'smtp', 'imap', 'pop', 'mx', 'autodiscover'],
    'Development': ['dev', 'development', 'staging', 'stage', 'test', 'qa'],
    'API Versions': ['api', 'api-v1', 'api-v2', 'apiv1', 'apiv2', 'api1', 'api2'],
    'Mobile': ['m', 'mobile', 'ios', 'android', 'app'],
    'Regional': ['us', 'eu', 'asia', 'uk', 'de', 'fr'],
    'Internal': ['internal', 'corp', 'private', 'secure', 'vpn']
  };
  
  Object.entries(techPatterns).forEach(([tech, patterns]) => {
    console.log(`  ${tech}: ${patterns.join(', ')}`);
  });
  
  // 3. Historical data mining
  console.log('\n๐Ÿ“œ Historical subdomain analysis:');
  console.log('  Wayback Machine: Checking archived DNS records');
  console.log('  Google Cache: Finding indexed subdomains');
  console.log('  Archive.org: Historical sitemap analysis');
  
  // 4. Passive DNS databases
  console.log('\n๐Ÿ—„๏ธ Passive DNS intelligence:');
  const passiveDNSSources = [
    'VirusTotal: Extensive subdomain history',
    'SecurityTrails: Historical DNS records',
    'RiskIQ: PassiveTotal DNS data',
    'Censys: Internet-wide scan data',
    'Shodan: Service enumeration'
  ];
  
  passiveDNSSources.forEach(source => {
    console.log(`  โ€ข ${source}`);
  });
  
  // 5. Content-based discovery
  console.log('\n๐Ÿ“„ Content-based discovery techniques:');
  console.log('  โ€ข JavaScript file analysis for API endpoints');
  console.log('  โ€ข HTML source for asset references');
  console.log('  โ€ข CSS files for image/font domains');
  console.log('  โ€ข API documentation for service endpoints');
  console.log('  โ€ข Mobile app reverse engineering');
  
  return permutations;
}

advancedSubdomainDiscovery('example.com');

3. Subdomain Analysis and Classification

// Analyze discovered subdomains
async function analyzeSubdomains(subdomains) {
  console.log('\n๐Ÿ”Ž Subdomain Analysis & Classification\n');
  
  // Simulated analysis results
  const analysisResults = [
    {
      subdomain: 'www.example.com',
      ip: '192.168.1.1',
      status: 200,
      server: 'nginx/1.18.0',
      title: 'Example Company - Home',
      technologies: ['WordPress', 'PHP', 'MySQL'],
      risk: 'low',
      category: 'production'
    },
    {
      subdomain: 'dev.example.com',
      ip: '192.168.1.10',
      status: 200,
      server: 'Apache/2.4.41',
      title: 'Development Environment',
      technologies: ['Django', 'PostgreSQL', 'Redis'],
      risk: 'high',
      category: 'development',
      issues: ['Debug mode enabled', 'Directory listing', 'Default credentials']
    },
    {
      subdomain: 'staging.example.com',
      ip: '192.168.1.20',
      status: 401,
      server: 'nginx/1.16.1',
      title: 'Staging - Auth Required',
      technologies: ['Node.js', 'Express', 'MongoDB'],
      risk: 'medium',
      category: 'staging'
    },
    {
      subdomain: 'api.example.com',
      ip: '192.168.1.30',
      status: 200,
      server: 'cloudflare',
      title: 'API Documentation',
      technologies: ['REST API', 'Swagger UI'],
      risk: 'medium',
      category: 'api',
      issues: ['API key in documentation', 'No rate limiting']
    },
    {
      subdomain: 'old.example.com',
      ip: '192.168.1.40',
      status: 200,
      server: 'Apache/2.2.15',
      title: 'Old Website',
      technologies: ['PHP 5.3', 'MySQL 5.1'],
      risk: 'critical',
      category: 'legacy',
      issues: ['Outdated software', 'Known vulnerabilities', 'No HTTPS']
    }
  ];
  
  // Group by category
  const categories = {};
  analysisResults.forEach(result => {
    if (!categories[result.category]) {
      categories[result.category] = [];
    }
    categories[result.category].push(result);
  });
  
  // Display categorized results
  Object.entries(categories).forEach(([category, subdomains]) => {
    console.log(`\n๐Ÿ“ ${category.toUpperCase()} (${subdomains.length})`);
    console.log('โ”€'.repeat(50));
    
    subdomains.forEach(sub => {
      const riskIcon = sub.risk === 'critical' ? '๐Ÿ”ด' :
                      sub.risk === 'high' ? '๐ŸŸ ' :
                      sub.risk === 'medium' ? '๐ŸŸก' : '๐ŸŸข';
      
      console.log(`\n${riskIcon} ${sub.subdomain}`);
      console.log(`  IP: ${sub.ip} | Status: ${sub.status} | Server: ${sub.server}`);
      console.log(`  Technologies: ${sub.technologies.join(', ')}`);
      
      if (sub.issues && sub.issues.length > 0) {
        console.log(`  โš ๏ธ Issues:`);
        sub.issues.forEach(issue => {
          console.log(`     - ${issue}`);
        });
      }
    });
  });
  
  // Risk summary
  console.log('\n\n๐Ÿšจ Risk Summary:');
  const riskCounts = analysisResults.reduce((acc, sub) => {
    acc[sub.risk] = (acc[sub.risk] || 0) + 1;
    return acc;
  }, {});
  
  Object.entries(riskCounts).forEach(([risk, count]) => {
    console.log(`  ${risk}: ${count} subdomain(s)`);
  });
  
  return analysisResults;
}

// Analyze sample subdomains
analyzeSubdomains([
  'www.example.com',
  'dev.example.com',
  'staging.example.com',
  'api.example.com',
  'old.example.com'
]);

Security Risk Assessment

1. Common Subdomain Vulnerabilities

// Check for common security issues in subdomains
function assessSubdomainSecurity(subdomain) {
  console.log(`\n๐Ÿ”’ Security Assessment for ${subdomain}\n`);
  
  const securityChecks = {
    // Basic checks
    'HTTPS enabled': false,
    'Valid SSL certificate': false,
    'HSTS header present': false,
    'Secure cookies': false,
    
    // Authentication
    'Authentication required': false,
    'Strong authentication': false,
    'Default credentials': true, // Bad if true
    
    // Information disclosure
    'Directory listing disabled': false,
    'Error messages hidden': false,
    'Version information hidden': false,
    'Debug mode disabled': false,
    
    // Security headers
    'X-Frame-Options': false,
    'Content-Security-Policy': false,
    'X-Content-Type-Options': false,
    'Referrer-Policy': false,
    
    // Common vulnerabilities
    'SQL injection tested': false,
    'XSS protection': false,
    'CSRF protection': false,
    'Rate limiting': false
  };
  
  // Simulate security scan
  console.log('๐Ÿ” Running security checks...\n');
  
  // Display results
  const passed = [];
  const failed = [];
  const critical = [];
  
  Object.entries(securityChecks).forEach(([check, status]) => {
    if (check === 'Default credentials' || check === 'Debug mode disabled') {
      // These are bad when true
      if (status) {
        critical.push(check);
      } else {
        passed.push(check);
      }
    } else {
      if (status) {
        passed.push(check);
      } else {
        failed.push(check);
      }
    }
  });
  
  // Critical issues
  if (critical.length > 0) {
    console.log('๐Ÿ”ด CRITICAL ISSUES:');
    critical.forEach(issue => {
      console.log(`  โŒ ${issue}`);
    });
    console.log('');
  }
  
  // Failed checks
  if (failed.length > 0) {
    console.log('โš ๏ธ Failed Security Checks:');
    failed.forEach(check => {
      console.log(`  โŒ ${check}`);
    });
    console.log('');
  }
  
  // Passed checks
  if (passed.length > 0) {
    console.log('โœ… Passed Security Checks:');
    passed.forEach(check => {
      console.log(`  โœ“ ${check}`);
    });
  }
  
  // Risk score
  const totalChecks = Object.keys(securityChecks).length;
  const score = (passed.length / totalChecks * 100).toFixed(0);
  
  console.log(`\n๐Ÿ“Š Security Score: ${score}/100`);
  
  if (critical.length > 0) {
    console.log('๐Ÿšจ Risk Level: CRITICAL - Immediate action required');
  } else if (score < 30) {
    console.log('๐Ÿ”ด Risk Level: HIGH - Multiple vulnerabilities');
  } else if (score < 60) {
    console.log('๐ŸŸก Risk Level: MEDIUM - Several issues to address');
  } else if (score < 80) {
    console.log('๐ŸŸข Risk Level: LOW - Minor improvements needed');
  } else {
    console.log('โœ… Risk Level: MINIMAL - Good security posture');
  }
  
  return { score, critical, failed, passed };
}

assessSubdomainSecurity('dev.example.com');

2. Subdomain Takeover Detection

// Check for subdomain takeover vulnerabilities
function checkSubdomainTakeover(subdomain) {
  console.log(`\n๐ŸŽฏ Subdomain Takeover Check for ${subdomain}\n`);
  
  // Common services vulnerable to takeover
  const takeoverSignatures = {
    'GitHub Pages': {
      cname: 'github.io',
      response: 'There isn\'t a GitHub Pages site here',
      risk: 'high'
    },
    'Heroku': {
      cname: 'herokuapp.com',
      response: 'No such app',
      risk: 'high'
    },
    'AWS S3': {
      cname: 's3.amazonaws.com',
      response: 'NoSuchBucket',
      risk: 'critical'
    },
    'Shopify': {
      cname: 'myshopify.com',
      response: 'Sorry, this shop is currently unavailable',
      risk: 'medium'
    },
    'Azure': {
      cname: 'azurewebsites.net',
      response: 'Error 404 - Web app not found',
      risk: 'high'
    },
    'Fastly': {
      cname: 'fastly.net',
      response: 'Fastly error: unknown domain',
      risk: 'medium'
    },
    'Ghost': {
      cname: 'ghost.io',
      response: 'The thing you were looking for is no longer here',
      risk: 'medium'
    },
    'Surge.sh': {
      cname: 'surge.sh',
      response: 'project not found',
      risk: 'high'
    }
  };
  
  // Simulate DNS and HTTP checks
  console.log('1๏ธโƒฃ Checking DNS records...');
  const dnsRecord = {
    type: 'CNAME',
    value: 'old-app.herokuapp.com'
  };
  console.log(`  Found: ${dnsRecord.type} โ†’ ${dnsRecord.value}`);
  
  console.log('\n2๏ธโƒฃ Checking HTTP response...');
  const httpResponse = {
    status: 404,
    body: 'No such app'
  };
  console.log(`  Status: ${httpResponse.status}`);
  console.log(`  Response: "${httpResponse.body}"`);
  
  // Check for vulnerability
  console.log('\n3๏ธโƒฃ Analyzing takeover potential...');
  
  let vulnerable = false;
  let service = null;
  
  Object.entries(takeoverSignatures).forEach(([serviceName, signature]) => {
    if (dnsRecord.value.includes(signature.cname) && 
        httpResponse.body.includes(signature.response)) {
      vulnerable = true;
      service = serviceName;
    }
  });
  
  if (vulnerable) {
    console.log(`\n๐Ÿšจ SUBDOMAIN TAKEOVER VULNERABILITY DETECTED!`);
    console.log(`Service: ${service}`);
    console.log(`Risk: ${takeoverSignatures[service].risk.toUpperCase()}`);
    console.log('\nExploitation steps:');
    console.log(`1. Create account on ${service}`);
    console.log(`2. Claim subdomain '${subdomain}'`);
    console.log('3. Serve malicious content');
    console.log('\nImpact:');
    console.log('โ€ข Complete control over subdomain');
    console.log('โ€ข Phishing using legitimate domain');
    console.log('โ€ข Cookie theft if wildcard cookies');
    console.log('โ€ข SEO hijacking');
  } else {
    console.log('\nโœ… No subdomain takeover vulnerability detected');
  }
  
  // Additional checks
  console.log('\n4๏ธโƒฃ Additional security checks:');
  const additionalChecks = {
    'Dangling CNAME': dnsRecord.type === 'CNAME' && httpResponse.status === 404,
    'Wildcard DNS': false, // Would check if *.domain resolves
    'Domain expiration': false, // Would check WHOIS
    'Nameserver takeover': false // Would check NS records
  };
  
  Object.entries(additionalChecks).forEach(([check, vulnerable]) => {
    console.log(`  ${vulnerable ? 'โš ๏ธ' : 'โœ…'} ${check}`);
  });
  
  return { vulnerable, service };
}

checkSubdomainTakeover('old.example.com');

Subdomain Monitoring

1. Continuous Subdomain Monitoring

// Set up continuous monitoring for new subdomains
class SubdomainMonitor {
  constructor(domain) {
    this.domain = domain;
    this.knownSubdomains = new Set();
    this.newSubdomains = [];
    this.removedSubdomains = [];
  }
  
  async initialize() {
    console.log(`\n๐Ÿ“ก Subdomain Monitor for ${this.domain}\n`);
    
    // Load known subdomains
    const known = [
      'www.example.com',
      'api.example.com',
      'blog.example.com',
      'mail.example.com'
    ];
    
    known.forEach(sub => this.knownSubdomains.add(sub));
    console.log(`โœ… Loaded ${this.knownSubdomains.size} known subdomains`);
    
    return this;
  }
  
  async checkForChanges() {
    console.log('\n๐Ÿ”„ Checking for subdomain changes...');
    
    // Simulate finding new subdomains
    const currentSubdomains = new Set([
      'www.example.com',
      'api.example.com',
      'blog.example.com',
      'mail.example.com',
      'dev.example.com',  // New
      'test.example.com'  // New
    ]);
    
    // Find new subdomains
    this.newSubdomains = [];
    currentSubdomains.forEach(sub => {
      if (!this.knownSubdomains.has(sub)) {
        this.newSubdomains.push(sub);
      }
    });
    
    // Find removed subdomains
    this.removedSubdomains = [];
    this.knownSubdomains.forEach(sub => {
      if (!currentSubdomains.has(sub)) {
        this.removedSubdomains.push(sub);
      }
    });
    
    // Report changes
    if (this.newSubdomains.length > 0) {
      console.log(`\n๐Ÿ†• New subdomains detected:`);
      this.newSubdomains.forEach(sub => {
        console.log(`  + ${sub}`);
        this.knownSubdomains.add(sub);
      });
    }
    
    if (this.removedSubdomains.length > 0) {
      console.log(`\nโŒ Removed subdomains:`);
      this.removedSubdomains.forEach(sub => {
        console.log(`  - ${sub}`);
        this.knownSubdomains.delete(sub);
      });
    }
    
    if (this.newSubdomains.length === 0 && this.removedSubdomains.length === 0) {
      console.log('  โœ… No changes detected');
    }
    
    return {
      new: this.newSubdomains,
      removed: this.removedSubdomains,
      total: this.knownSubdomains.size
    };
  }
  
  async analyzeNewSubdomains() {
    if (this.newSubdomains.length === 0) return;
    
    console.log('\n๐Ÿ” Analyzing new subdomains...');
    
    this.newSubdomains.forEach(subdomain => {
      console.log(`\n๐Ÿ“Œ ${subdomain}`);
      
      // Quick security check
      const risks = [];
      
      if (subdomain.includes('dev') || subdomain.includes('test')) {
        risks.push('Development environment exposed');
      }
      if (subdomain.includes('admin') || subdomain.includes('internal')) {
        risks.push('Administrative interface exposed');
      }
      if (subdomain.includes('staging') || subdomain.includes('uat')) {
        risks.push('Non-production environment');
      }
      
      if (risks.length > 0) {
        console.log('  โš ๏ธ Potential risks:');
        risks.forEach(risk => console.log(`    - ${risk}`));
      } else {
        console.log('  โœ… No immediate risks identified');
      }
    });
  }
  
  generateAlert() {
    if (this.newSubdomains.length === 0) return null;
    
    console.log('\n๐Ÿšจ SECURITY ALERT');
    console.log('โ”€'.repeat(50));
    console.log(`Domain: ${this.domain}`);
    console.log(`New subdomains: ${this.newSubdomains.length}`);
    console.log(`Timestamp: ${new Date().toISOString()}`);
    console.log('\nAction required:');
    console.log('1. Verify if subdomains are authorized');
    console.log('2. Perform security assessment');
    console.log('3. Check for sensitive data exposure');
    console.log('4. Validate SSL certificates');
    console.log('5. Review access controls');
  }
}

// Example monitoring session
async function runSubdomainMonitoring() {
  const monitor = await new SubdomainMonitor('example.com').initialize();
  
  // Initial check
  const changes = await monitor.checkForChanges();
  
  if (changes.new.length > 0) {
    await monitor.analyzeNewSubdomains();
    monitor.generateAlert();
  }
  
  // Schedule continuous monitoring
  console.log('\nโฐ Monitoring schedule:');
  console.log('โ€ข Real-time: Certificate Transparency logs');
  console.log('โ€ข Hourly: DNS queries for common patterns');
  console.log('โ€ข Daily: Full subdomain enumeration');
  console.log('โ€ข Weekly: Deep scan with all techniques');
}

runSubdomainMonitoring();

Complete Subdomain Audit

Full Subdomain Security Audit

// Comprehensive subdomain audit
async function completeSubdomainAudit(domain) {
  console.log('๐Ÿ” COMPLETE SUBDOMAIN SECURITY AUDIT');
  console.log('โ•'.repeat(50));
  console.log(`Domain: ${domain}`);
  console.log(`Date: ${new Date().toLocaleDateString()}\n`);
  
  // Phase 1: Discovery
  console.log('๐Ÿ“ก PHASE 1: DISCOVERY');
  console.log('โ”€'.repeat(40));
  
  const discoveryMethods = {
    'DNS Enumeration': 12,
    'Certificate Transparency': 8,
    'Search Engines': 5,
    'Web Archives': 3,
    'Reverse DNS': 4,
    'Port Scanning': 6
  };
  
  let totalFound = 0;
  Object.entries(discoveryMethods).forEach(([method, count]) => {
    console.log(`${method}: ${count} subdomains`);
    totalFound += count;
  });
  
  console.log(`\nTotal unique subdomains: ${totalFound}`);
  
  // Phase 2: Classification
  console.log('\n๐Ÿ“Š PHASE 2: CLASSIFICATION');
  console.log('โ”€'.repeat(40));
  
  const classification = {
    'Production': ['www', 'api', 'app', 'secure'],
    'Development': ['dev', 'development', 'test', 'qa'],
    'Infrastructure': ['mail', 'smtp', 'ftp', 'vpn'],
    'Third-party': ['blog', 'shop', 'support', 'help'],
    'Legacy': ['old', 'v1', 'backup', 'archive']
  };
  
  Object.entries(classification).forEach(([category, subdomains]) => {
    console.log(`\n${category} (${subdomains.length})`);
    subdomains.forEach(sub => {
      console.log(`  โ€ข ${sub}.${domain}`);
    });
  });
  
  // Phase 3: Security Assessment
  console.log('\n๐Ÿ”’ PHASE 3: SECURITY ASSESSMENT');
  console.log('โ”€'.repeat(40));
  
  const securityFindings = {
    'Critical': [
      'dev.example.com - Debug mode enabled',
      'old.example.com - Outdated software versions',
      'backup.example.com - Directory listing enabled'
    ],
    'High': [
      'staging.example.com - Weak authentication',
      'test.example.com - SSL certificate expired'
    ],
    'Medium': [
      'api.example.com - Missing rate limiting',
      'blog.example.com - Outdated CMS version'
    ],
    'Low': [
      'www.example.com - Missing security headers',
      'mail.example.com - SPF record needs update'
    ]
  };
  
  let criticalCount = 0;
  Object.entries(securityFindings).forEach(([severity, findings]) => {
    console.log(`\n${severity} Risk (${findings.length})`);
    findings.forEach(finding => {
      console.log(`  โš ๏ธ ${finding}`);
      if (severity === 'Critical') criticalCount++;
    });
  });
  
  // Phase 4: Takeover Analysis
  console.log('\n๐ŸŽฏ PHASE 4: TAKEOVER ANALYSIS');
  console.log('โ”€'.repeat(40));
  
  const takeoverRisks = [
    { subdomain: 'docs.example.com', service: 'GitHub Pages', status: 'Vulnerable' },
    { subdomain: 'shop.example.com', service: 'Shopify', status: 'Protected' },
    { subdomain: 'cdn.example.com', service: 'CloudFront', status: 'Protected' }
  ];
  
  takeoverRisks.forEach(risk => {
    const icon = risk.status === 'Vulnerable' ? '๐Ÿ”ด' : '๐ŸŸข';
    console.log(`${icon} ${risk.subdomain} โ†’ ${risk.service} (${risk.status})`);
  });
  
  // Executive Summary
  console.log('\n๐Ÿ“‹ EXECUTIVE SUMMARY');
  console.log('โ•'.repeat(50));
  
  const summary = {
    'Total Subdomains': totalFound,
    'Critical Issues': criticalCount,
    'Takeover Vulnerabilities': takeoverRisks.filter(r => r.status === 'Vulnerable').length,
    'SSL Issues': 3,
    'Authentication Weaknesses': 2,
    'Information Disclosure': 4
  };
  
  Object.entries(summary).forEach(([metric, value]) => {
    console.log(`${metric}: ${value}`);
  });
  
  // Risk Score
  const riskScore = criticalCount > 0 ? 'HIGH' : 
                   securityFindings.High.length > 2 ? 'MEDIUM' : 'LOW';
  
  console.log(`\nOverall Risk: ${riskScore}`);
  
  // Recommendations
  console.log('\n๐Ÿ’ก PRIORITY RECOMMENDATIONS');
  console.log('โ”€'.repeat(40));
  console.log('1. Remove or secure development subdomains');
  console.log('2. Update SSL certificates on all subdomains');
  console.log('3. Implement authentication on admin interfaces');
  console.log('4. Disable debug mode on all environments');
  console.log('5. Set up continuous subdomain monitoring');
  console.log('6. Create subdomain management policy');
  console.log('7. Regular security assessments (monthly)');
  
  return {
    total: totalFound,
    critical: criticalCount,
    risk: riskScore
  };
}

// Run complete audit
completeSubdomainAudit('example.com');

The Bottom Line

Subdomain discovery reveals your true attack surface:

  • Every subdomain is a door - Attackers only need one weak entry
  • Development leaks secrets - Debug modes expose everything
  • Old subdomains accumulate - Technical debt becomes security debt
  • Takeovers damage trust - Your domain serving attacker content
  • Continuous monitoring essential - New subdomains appear daily

Find all subdomains. Secure every one. Monitor continuously. Your domain is only as secure as its weakest subdomain.


Discover subdomains instantly: Fusebox finds hidden subdomains, analyzes security risks, and monitors for takeover vulnerabilities while you browse. Protect your entire domain. $29 one-time purchase.