directory_scan
Scan web directories to discover hidden files and folders using popular security tools for penetration testing and security assessments.
Instructions
Advanced directory scanning with dirb/dirsearch/gobuster/feroxbuster
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| recursive | No | Enable recursive scanning | |
| target | Yes | Target URL | |
| tool | No | Directory scanning tool to use |
Input Schema (JSON Schema)
{
"properties": {
"recursive": {
"description": "Enable recursive scanning",
"type": "boolean"
},
"target": {
"description": "Target URL",
"type": "string"
},
"tool": {
"description": "Directory scanning tool to use",
"enum": [
"dirb",
"dirsearch",
"gobuster",
"feroxbuster"
],
"type": "string"
}
},
"required": [
"target"
],
"type": "object"
}
Implementation Reference
- src/index.ts:323-339 (registration)Tool registration including name, description, and input schema definition for 'directory_scan' in the listTools handler.{ name: "directory_scan", description: "Advanced directory scanning with dirb/dirsearch/gobuster/feroxbuster", inputSchema: { type: "object", properties: { target: { type: "string", description: "Target URL" }, tool: { type: "string", enum: ["dirb", "dirsearch", "gobuster", "feroxbuster"], description: "Directory scanning tool to use" }, recursive: { type: "boolean", description: "Enable recursive scanning" } }, required: ["target"] } },
- src/index.ts:561-565 (handler)Dispatch handler in main switch statement that calls DirectoryScannerEngine.scanDirectories with parsed arguments.case "directory_scan": return respond(await this.directoryScanner.scanDirectories(args.target, { tool: args.tool || 'dirsearch', recursive: args.recursive }));
- src/tools/directory-scanner.ts:38-109 (handler)Core handler function implementing directory scanning logic: configures tool, executes selected scanner (dirb/dirsearch/gobuster/feroxbuster), parses output, analyzes results, and returns formatted ScanResult.async scanDirectories(target: string, config: Partial<DirectoryScanConfiguration> = {}): Promise<ScanResult> { try { const defaultConfig: DirectoryScanConfiguration = { tool: 'dirsearch', wordlist: this.getDefaultWordlist(), extensions: ['php', 'asp', 'aspx', 'jsp', 'html', 'htm', 'txt', 'xml', 'json', 'js', 'css'], threads: 30, timeout: 10, recursive: true, max_depth: 3, status_codes: [200, 201, 204, 301, 302, 307, 308, 401, 403, 405, 500], user_agent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', delay: 0, ...config }; console.error(`🔍 Directory scanning ${target} with ${defaultConfig.tool}`); let results: DirectoryResult[] = []; switch (defaultConfig.tool) { case 'dirb': results = await this.runDirb(target, defaultConfig); break; case 'dirsearch': results = await this.runDirsearch(target, defaultConfig); break; case 'gobuster': results = await this.runGobuster(target, defaultConfig); break; case 'feroxbuster': results = await this.runFeroxbuster(target, defaultConfig); break; default: throw new Error(`Unsupported tool: ${defaultConfig.tool}`); } // Analyze and categorize results const analyzedResults = this.analyzeResults(results); const sensitiveFiles = analyzedResults.filter(r => r.is_sensitive); const accessibleDirs = analyzedResults.filter(r => r.is_directory && r.status_code === 200); const highRiskFindings = analyzedResults.filter(r => r.risk_level === 'high' || r.risk_level === 'critical'); return { target, timestamp: new Date().toISOString(), tool: 'directory_scanner', results: { scan_tool: defaultConfig.tool, total_discovered: results.length, accessible_directories: accessibleDirs.length, sensitive_files: sensitiveFiles.length, high_risk_findings: highRiskFindings.length, status_code_breakdown: this.groupByStatusCode(results), risk_level_breakdown: this.groupByRiskLevel(analyzedResults), discovered_paths: analyzedResults, security_recommendations: this.generateSecurityRecommendations(analyzedResults) }, status: 'success' }; } catch (error) { return { target, timestamp: new Date().toISOString(), tool: 'directory_scanner', results: {}, status: 'error', error: error instanceof Error ? error.message : String(error) }; } }
- src/tools/directory-scanner.ts:21-34 (schema)Type definition for DirectoryScanConfiguration used to parameterize the scanning tools.export interface DirectoryScanConfiguration { tool: 'dirb' | 'dirsearch' | 'gobuster' | 'feroxbuster'; wordlist?: string; extensions?: string[]; threads: number; timeout: number; recursive: boolean; max_depth: number; status_codes: number[]; user_agent?: string; headers?: Record<string, string>; proxy?: string; delay?: number; }
- Example helper: Executes dirsearch tool, one of four tool runners called by main handler.private async runDirsearch(target: string, config: DirectoryScanConfiguration): Promise<DirectoryResult[]> { try { // Check if dirsearch is installed try { await execAsync('dirsearch -h', { timeout: 5000 }); } catch { console.warn('dirsearch not found, skipping dirsearch scan'); return []; } const extensions = config.extensions?.join(',') || 'php,asp,aspx,jsp,html'; const statusCodes = config.status_codes.join(','); let command = `dirsearch -u ${target} -e ${extensions} -t ${config.threads} --timeout ${config.timeout}`; command += ` --include-status ${statusCodes}`; if (config.recursive) { command += ` -r --max-recursion-depth ${config.max_depth}`; } if (config.wordlist) { command += ` -w ${config.wordlist}`; } if (config.user_agent) { command += ` --user-agent "${config.user_agent}"`; } command += ' --format simple --quiet-mode'; console.error(`Executing: ${command}`); const { stdout } = await execAsync(command, { timeout: 600000, // 10 minutes maxBuffer: 1024 * 1024 * 20 // 20MB }); return this.parseDirsearchOutput(stdout, target); } catch (error) { console.error('Dirsearch execution error:', error); return []; } }