recon.full
Perform comprehensive reconnaissance by discovering subdomains, checking active HTTP services, and mapping attack surfaces for security testing.
Instructions
Run full reconnaissance workflow: subfinder -> httpx -> amass
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| domain | Yes | Target domain |
Implementation Reference
- src/tools/recon.ts:220-275 (handler)The handler function for the 'recon.full' tool. It performs full reconnaissance by running subfinder for subdomains, amass for additional enumeration, writes subdomains to temp file, runs httpx to find live hosts, stores results in Redis, and returns formatted results.async ({ domain }: any): Promise<ToolResult> => { try { const results: ReconResult = { subdomains: [] as string[], liveHosts: [] as string[], }; // Run subfinder const subfinderExists = await checkCommandExists('subfinder'); if (subfinderExists) { const subfinderResult = await runCommand('subfinder', ['-d', domain, '-silent']); const subdomains = subfinderResult.stdout .split('\n') .filter((s) => s.trim().length > 0); results.subdomains = subdomains; } // Run amass const amassExists = await checkCommandExists('amass'); if (amassExists) { const amassResult = await runCommand('amass', ['enum', '-d', domain, '-passive'], 120000); const amassSubs = amassResult.stdout .split('\n') .filter((s) => s.trim().length > 0 && s.includes('.')); results.subdomains = [...new Set([...(results.subdomains || []), ...amassSubs])]; } // Check live hosts if (results.subdomains && results.subdomains.length > 0) { const httpxExists = await checkCommandExists('httpx'); if (httpxExists) { const inputFile = path.join('/tmp', `subdomains_${Date.now()}.txt`); await fs.writeFile(inputFile, results.subdomains.join('\n')); const httpxResult = await runCommand('httpx', ['-l', inputFile, '-silent', '-status-code']); results.liveHosts = httpxResult.stdout .split('\n') .filter((s) => s.trim().length > 0); await fs.remove(inputFile); } } await setWorkingMemory(`recon:${domain}:full`, results, 7200); return formatToolResult(true, { ...results, summary: { totalSubdomains: results.subdomains?.length || 0, liveHosts: results.liveHosts?.length || 0, }, }); } catch (error: any) { return formatToolResult(false, null, error.message); } }
- src/tools/recon.ts:210-219 (schema)Input schema for the 'recon.full' tool, requiring a 'domain' string.{ description: 'Run full reconnaissance workflow: subfinder -> httpx -> amass', inputSchema: { type: 'object', properties: { domain: { type: 'string', description: 'Target domain' }, }, required: ['domain'], }, },
- src/tools/recon.ts:208-276 (registration)Direct registration of the 'recon.full' tool using server.tool() within registerReconTools function.server.tool( 'recon.full', { description: 'Run full reconnaissance workflow: subfinder -> httpx -> amass', inputSchema: { type: 'object', properties: { domain: { type: 'string', description: 'Target domain' }, }, required: ['domain'], }, }, async ({ domain }: any): Promise<ToolResult> => { try { const results: ReconResult = { subdomains: [] as string[], liveHosts: [] as string[], }; // Run subfinder const subfinderExists = await checkCommandExists('subfinder'); if (subfinderExists) { const subfinderResult = await runCommand('subfinder', ['-d', domain, '-silent']); const subdomains = subfinderResult.stdout .split('\n') .filter((s) => s.trim().length > 0); results.subdomains = subdomains; } // Run amass const amassExists = await checkCommandExists('amass'); if (amassExists) { const amassResult = await runCommand('amass', ['enum', '-d', domain, '-passive'], 120000); const amassSubs = amassResult.stdout .split('\n') .filter((s) => s.trim().length > 0 && s.includes('.')); results.subdomains = [...new Set([...(results.subdomains || []), ...amassSubs])]; } // Check live hosts if (results.subdomains && results.subdomains.length > 0) { const httpxExists = await checkCommandExists('httpx'); if (httpxExists) { const inputFile = path.join('/tmp', `subdomains_${Date.now()}.txt`); await fs.writeFile(inputFile, results.subdomains.join('\n')); const httpxResult = await runCommand('httpx', ['-l', inputFile, '-silent', '-status-code']); results.liveHosts = httpxResult.stdout .split('\n') .filter((s) => s.trim().length > 0); await fs.remove(inputFile); } } await setWorkingMemory(`recon:${domain}:full`, results, 7200); return formatToolResult(true, { ...results, summary: { totalSubdomains: results.subdomains?.length || 0, liveHosts: results.liveHosts?.length || 0, }, }); } catch (error: any) { return formatToolResult(false, null, error.message); } } );
- src/index.ts:35-35 (registration)Top-level call to registerReconTools(server) which includes the 'recon.full' tool registration.registerReconTools(server);