subdomain_enum
Discover subdomains of target domains using multiple enumeration methods including wordlist fuzzing and external tools for comprehensive reconnaissance in penetration testing.
Instructions
Enumerate subdomains of target domain using multiple methods
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| domain | Yes | Target domain | |
| wordlist | No | Wordlist to use (optional) | |
| use_subfinder | No | Also use subfinder for enumeration | |
| fuzz_tool | No | Use fuzzing tool for subdomain discovery (ffuf/wfuzz) |
Implementation Reference
- src/tools/recon.ts:223-297 (handler)Core handler function implementing subdomain enumeration using certificate transparency logs, DNS brute-forcing, optional subfinder, and fuzzing with ffuf/wfuzz.async subdomainEnum(domain: string, wordlist?: string, useSubfinder?: boolean, fuzzTool?: 'ffuf' | 'wfuzz'): Promise<ScanResult> { try { const subdomains = new Set<string>(); // Method 1: Certificate Transparency logs try { const ctLogs = await this.getCertTransparencySubdomains(domain); ctLogs.forEach(sub => subdomains.add(sub)); } catch (e) { console.error('CT logs failed:', e); } // Method 2: DNS brute force with common subdomains or supplied wordlist const commonSubs = [ 'www', 'mail', 'ftp', 'localhost', 'webmail', 'smtp', 'pop', 'ns1', 'webdisk', 'ns2', 'cpanel', 'whm', 'autodiscover', 'autoconfig', 'dev', 'staging', 'test', 'api', 'admin', 'blog', 'shop', 'forum', 'support', 'mobile', 'app', 'cdn' ]; const customWordlist = wordlist ? await this.loadWordlist(wordlist) : commonSubs; for (const subdomain of customWordlist) { try { const fullDomain = `${subdomain}.${domain}`; const dns = require('dns').promises; await dns.lookup(fullDomain); subdomains.add(fullDomain); } catch (e) { // Subdomain doesn't exist } } // Method 3: subfinder integration if (useSubfinder) { try { const cmd = `subfinder -silent -d ${domain}`; const { stdout } = await execAsync(cmd, { timeout: 60000 }); stdout.split('\n').map(s => s.trim()).filter(s => s).forEach(s => subdomains.add(s)); } catch (e) { console.error('subfinder failed:', e); } } // Method 4: Fuzzing with ffuf/wfuzz if (fuzzTool) { try { const fuzzSubs = await this.fuzzSubdomains(domain, fuzzTool, wordlist); fuzzSubs.forEach(sub => subdomains.add(sub)); } catch (e) { console.error(`${fuzzTool} subdomain fuzzing failed:`, e); } } return { target: domain, timestamp: new Date().toISOString(), tool: 'subdomain_enum', results: { subdomains: Array.from(subdomains), count: subdomains.size, methods_used: ['certificate_transparency', 'dns_bruteforce'] .concat(useSubfinder ? ['subfinder'] : []) .concat(fuzzTool ? [`${fuzzTool}_fuzzing`] : []) }, status: 'success' }; } catch (error) { return { target: domain, timestamp: new Date().toISOString(), tool: 'subdomain_enum', results: {}, status: 'error', error: error instanceof Error ? error.message : String(error) }; }
- src/index.ts:92-107 (schema)Input schema and tool metadata definition for the subdomain_enum tool, registered in the MCP server.name: "subdomain_enum", description: "Enumerate subdomains of target domain using multiple methods", inputSchema: { type: "object", properties: { domain: { type: "string", description: "Target domain" }, wordlist: { type: "string", description: "Wordlist to use (optional)" }, use_subfinder: { type: "boolean", description: "Also use subfinder for enumeration" }, fuzz_tool: { type: "string", enum: ["ffuf", "wfuzz"], description: "Use fuzzing tool for subdomain discovery (ffuf/wfuzz)" } }, required: ["domain"] }
- src/index.ts:508-509 (registration)Dispatch/registration case in the MCP tool call handler that invokes the subdomainEnum method from ReconTools.case "subdomain_enum": return respond(await this.reconTools.subdomainEnum(args.domain, args.wordlist, args.use_subfinder, args.fuzz_tool));